>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
报告名称:性感相册蠕虫病毒“Worm/MSN.SendPhoto.ab”新变种的简单分析和脱壳资料
报告类型:病毒分析播报
分析编辑:Coderui
编写日期:2008年02月05日(最新版)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
--------------------------------------------------------------------------------------------
病毒未知壳手动脱壳方法:

前言:
  因为这个壳(也许是打包或虚拟程序)比较新颖(也许很早就已经存在,但我是头一次见过,呵呵),所以就写出来了这个简单的分析准备和大家一起分享下。因为是出次见过的技术,难免会有些关键的地方叙述错误,还请大家多多指教。
  我在分析的过曾中,跑飞了不下百次。难就难在下最后一步的断点上,貌似我知道的方法都用上了,也没能达到预期的效果,现在我也依然不知道怎么去下这个断点才好,呵呵。不过总结出来了一个适合目前所有新变种通用的手脱方法,其它的等以后有时间了再去继续研究分析吧。
  因为这个病毒程序比较特殊,所以本文准备以与以前不同的方式来表述壳的分析过程和手动脱壳并提取保存脱壳文件的方法。同时也因为它的特殊性,所以描述起来真的有些难度。我的语文表达能力还不太好,希望您可以看懂(不行就多读几便吧),呵呵。

说明:
  病毒主程序为EXE可执行程序,并经过添加特殊保护壳(类似于加密壳、压缩壳和虚拟机的合成体)处理。脱壳后,提取出来的病毒文件体为恶意DLL功能组件文件,采用“Microsoft Visual C++ 6.0”编写,未经过加壳处理。
  该病毒程序原形应该是一个DLL组件程序,经过特殊保护壳“类似于加密壳、压缩壳和虚拟机的合成体”打包后,形成了一个EXE病毒可执行文件。运行该EXE病毒可执行文件后,他会自己去开辟一块内存来加载运行这个DLL组件程序,并且不会把这个DLL组件程序文件在磁盘中创建保存。其中,EXE病毒可执行文件在系统中开辟内存,并将DLL组件文件解密后的代码映射到相应内存中对应的位置后,会进行重定位输入表和初始化环境变量的操作。最后自己会将EIP指向新开辟的DLL组件内存段,跳到这个DLL组件程序的代码入口处开始执行DLL中的代码来进行恶意操作,也就是将进程主运行权限交给了这个DLL组件来控制运行,给人的感觉就是这个DLL组件程序和EXE病毒可执行程序是一体的(但其实不是,应该是两个不同的程序文件。外边的EXE病毒可执行程序起到加密、压缩和虚拟初始化DLL运行环境的功能。里边的DLL组件程序才是病毒功能的真正执行体)。其中,该壳中所使用到的关键性的输入表(API函数名)都是被解密过了的,并且对所有关键性的PUSH和API函数头都进行了检测(检测INT3断点),看是否被下了软断点(下软断点的原理就是写入了INT3指令),如果代码改变了(说明下了断点)就会抛出异常、退出运行。

简单介绍病毒和壳的结构:
-------------------------------------------------------
1:自解密还原输入表。
2:使用“VirtualAllocEx”函数申请内存模块。所申请的内存基址(首地址)是不固定的,不同计算机、不同操作系统版本可能是不一样的。
3:将病毒PE文件体内的DLL组件模块的段(节) ,解压缩到申请的内存模块中。
4:使用“LoadLibraryA”和“GetProcAddress”函数解密并重定向内存模块中DLL组件的输入表函数。最后加载的系统DLL连接库是“iphlpapi.dll”。
5:初始化重定向内存模块中DLL组件的运行环境。
6:采用了非常烦琐的超级连续跨段(两个代码段来回跳,并且在每个段中还要执行很多的垃圾迷惑代码)循环跳转技术(使用OD自带的自动单步步入跟踪功能,连续跑几十分钟都跑不出来这个循环,恐怖啊)。还不停的读申请后的内存,使你无法下内存断点。
7:病毒的壳交出在进程中的运行权限,将EIP指向DLL组件所在内存地址的代码入口处[OEP = 新申请内存基址 + 102D3(偏移量)],然后继续执行DLL组件中的恶意代码(DLL组件开始会调用“GetWindowRect”函数来获取系统目录)。

害处:
  按照上边这个壳结构来运行程序的话,当把执行权交给DLL组件程序去执行后,壳程序并没有被退出,所占用着的内存也没有被释放,只能等到DLL组件程序执行到退出后,估计整个内存才会被一起释放掉。
意处:
  1:病毒所开辟的DLL组件内存模块没有加入到可执行程序的加载列表中,并且DLL组件代码数据又不在EXE自身的进程内存空间内,这样就可以躲避非常多的安全软件的内存扫描。
  2:病毒在把执行权限转交给DLL组件前,采用了非常烦琐的超级连续跨段循环跳转技术(使用OD自带的自动单步步入跟踪功能,连续跑几十分钟都跑不出来这个循环,恐怖啊)。而且在转交权限时,指向DLL组件代码入口所用的跳转代码是和跨段循环跳转共用同一个地址的RETN,使之无法准确的下断并停在DLL组件的代码入口处。如果得不到OEP,就很难进行仔细的动态分析调试;如果跑飞了,就很难定位关键段去准确分析有价值的代码。
-------------------------------------------------------

简单介绍该种病毒的目前通用脱壳方法:
-------------------------------------------------------
说明:我调试的环境是在Windows XP-SP2下。不同的操作系统中的“LoadLibraryA”函数代码(其它函数也一样)是不相同的,所以在下断点时只要尽量别下在PUSH(只针对该壳这样带有自检功能的壳而言)上就行,我一般喜欢下在MOV(只针对该壳这样带有自检功能的壳而言)上。
OD设置:(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
请按照注解顺序观看(00)-(01)-(02)…(99),不然很容易混乱。

004010B5 > $  68 343F49AD   PUSH AD493F34                            ; (00)载入后停在这里。我们使用“bp”命令对系统“VirtualAllocEx”函数下断。然后[F9]运行。
004010BA   .  E8 C4E30000   CALL img383_J.0040F483
004010BF   .  66:39E3       CMP BX,SP
004010C2   .  0FA3DD        BT EBP,EBX
004010C5   .  D0C1          ROL CL,1
004010C7   .  8B45 00       MOV EAX,DWORD PTR SS:[EBP]
004010CA   .  81E2 8EB401A0 AND EDX,A001B48E

7C809A72 >  6A 10           PUSH 10                                  ; (01)运行一段时间以后(主程序在解密修复自己的输入表),会停在这里(目前这里是kernel32.dll的领空)。我们[Alt+F9]返回到主程序领空。
7C809A74    68 C09A807C     PUSH kernel32.7C809AC0
7C809A79    E8 488AFFFF     CALL kernel32.7C8024C6
7C809A7E    8B45 0C         MOV EAX,DWORD PTR SS:[EBP+C]
7C809A81    85C0            TEST EAX,EAX
7C809A83    75 47           JNZ SHORT kernel32.7C809ACC
7C809A85    8365 FC 00      AND DWORD PTR SS:[EBP-4],0
7C809A89    FF75 18         PUSH DWORD PTR SS:[EBP+18]
7C809A8C    FF75 14         PUSH DWORD PTR SS:[EBP+14]
7C809A8F    8D45 10         LEA EAX,DWORD PTR SS:[EBP+10]
7C809A92    50              PUSH EAX
7C809A93    6A 00           PUSH 0
7C809A95    8D45 0C         LEA EAX,DWORD PTR SS:[EBP+C]
7C809A98    50              PUSH EAX
7C809A99    FF75 08         PUSH DWORD PTR SS:[EBP+8]
7C809A9C    FF15 9011807C   CALL DWORD PTR DS:[<&ntdll.NtAllocateVir>; ntdll.ZwAllocateVirtualMemory

004171DE    68 343FF6CD     PUSH CDF63F34                            ; (02)回到主程序领空后会停在这里,我们现在观看EAX寄存器的值(目前我的EAX = 003C0000)并将其值记录下来。其中,这里所得到的EAX寄存器的值就是新申请内存的基址。
004171E3    E8 3591FFFF     CALL img383_J.0041031D
004171E8    A3 43B5C55A     MOV DWORD PTR DS:[5AC5B543],EAX
004171ED    8D6424 04       LEA ESP,DWORD PTR SS:[ESP+4]
004171F1    0F83 A3350000   JNB img383_J.0041A79A
004171F7    9C              PUSHFD
004171F8    60              PUSHAD
004171F9    FEC0            INC AL
004171FB    B3 02           MOV BL,2
004171FD    60              PUSHAD
004171FE    E8 B4020000     CALL img383_J.004174B7

(03)我们现在使用“bp”命令对系统“LoadLibraryA”函数下断。然后使用[Alt+B]打开查看断点窗口。

7C801D77 >  8BFF            MOV EDI,EDI                              ; (04)我们双击刚才下过的断点会来到这里,然后[F2]将此处断点取消。
7C801D79    55              PUSH EBP
7C801D7A    8BEC            MOV EBP,ESP                              ; (05)我们在这里[F2]下断,这样就不会被程序检测到被下断了。然后[F9]运行。
7C801D7C    837D 08 00      CMP DWORD PTR SS:[EBP+8],0
7C801D80    53              PUSH EBX
7C801D81    56              PUSH ESI
7C801D82    74 14           JE SHORT kernel32.7C801D98
7C801D84    68 C0E0807C     PUSH kernel32.7C80E0C0                   ; ASCII "twain_32.dll"
7C801D89    FF75 08         PUSH DWORD PTR SS:[EBP+8]
7C801D8C    FF15 9C13807C   CALL DWORD PTR DS:[<&ntdll._strcmpi>]    ; ntdll._stricmp

(06)运行好长时间后,程序停下来,我们可以在堆栈窗口中看到当前程序要加载系统DLL连接库“KERNEL32.dll”。这个时候病毒已经申请完内存空间并且将DLL组件模块的代码也解密完毕了,剩下的就是重新定向并修复输入表了。

(07)我们现在取消掉刚才在“LoadLibraryA”函数里“7C801D7A”处下(您系统中的地址可能不是这个值)的断点,然后按[Ctrl+G]输入要跟踪的表达式地址“新申请内存基址 + 102D3(偏移量)”(因为我新申请的内存基址是003C0000,所以表达式地址就是003C0000 + 102D3 = 003D02D3),点确定。确定后所看到的代码地址就是病毒DLL组件的OEP了。我找了几个该病毒的变种看了下,OEP地址都是这个,所以目前版本的变种用这种方法脱十分简单。

003D02D3    55              PUSH EBP                                 ; (08)这个是DLL组件的入口。但我们不可以在这里下断点,因为会被程序检测到的。
003D02D4    8BEC            MOV EBP,ESP                              ; (09)我们在这里[F2]下断,然后[F9]运行,程序执行一会儿后就会停在这里。这时,DLL组件的输入表也已经重定向并修复好了,我们可以DUMP了。看一下内存块结构,再DUMP时把起始地址改为:新申请内存基址(我的是3C0000),大小改为:18000(在查看内存模块中可以看到这个大小),入口地址改为:000002D3[(003D02D3 - 3D0000 = 000002D3)您的这个OEP地址要自己算,系统环境不同可能不一样],DUMP保存成功。
003D02D6    53              PUSH EBX
003D02D7    8B5D 08         MOV EBX,DWORD PTR SS:[EBP+8]
003D02DA    56              PUSH ESI
003D02DB    8B75 0C         MOV ESI,DWORD PTR SS:[EBP+C]
003D02DE    57              PUSH EDI
003D02DF    8B7D 10         MOV EDI,DWORD PTR SS:[EBP+10]
003D02E2    85F6            TEST ESI,ESI
003D02E4    75 09           JNZ SHORT 003D02EF
003D02E6    833D 00100110 0>CMP DWORD PTR DS:[10011000],0
003D02ED    EB 26           JMP SHORT 003D0315
003D02EF    83FE 01         CMP ESI,1
003D02F2    74 05           JE SHORT 003D02F9
003D02F4    83FE 02         CMP ESI,2
003D02F7    75 22           JNZ SHORT 003D031B
003D02F9    A1 602B0110     MOV EAX,DWORD PTR DS:[10012B60]
003D02FE    85C0            TEST EAX,EAX
003D0300    74 09           JE SHORT 003D030B

(10)DUMP保护后,使用PEID查看为“Microsoft Visual C++ 6.0 DLL”,剩下的就是修复这个DLL组件的输入表了。不过修复好后要使用其它EXE程序来调用它才可以运行,呵呵。
-------------------------------------------------------

简单介绍该种病毒的目前通用脱壳方法的补充说明:
-------------------------------------------------------
1:病毒程序应该最后就是利用这个公用的返回跳:
0040F1EC    895424 50       MOV DWORD PTR SS:[ESP+50],EDX            ; img383_J.0040F318
0040F1F0    884C24 08       MOV BYTE PTR SS:[ESP+8],CL
0040F1F4    881C24          MOV BYTE PTR SS:[ESP],BL
0040F1F7    FF7424 50       PUSH DWORD PTR SS:[ESP+50]
0040F1FB    C2 5400         RETN 54                                  ;病毒程序应该最后就是利用这个公用的返回跳,跳到DLL组件代码领空中的。

2:使用过内存断点、硬件断点、ESP定律等等都不行。目前我只发现一个方法来对付这个壳比较有效,那就是对病毒在最开始启动时所调用的API进行下断,然后根据堆栈进行向回反向推入口地址,也是可以找到的(只是即麻烦又危险,呵呵)。

3:根据我前边给出来的病毒和壳的结构,相信就算OEP地址改变了,也可以很快找到正确地址的。当病毒DLL组件在内存中解密完毕后,对“GetWindowRect”函数下断,然后利用堆栈地址进行向回反推就能找到真正的入口地址了。
-------------------------------------------------------
--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------
英文名称:Worm/MSN.SendPhoto.ab
中文名称:“性感相册”变种ab
病毒类型:蠕虫
文件大小:114,688 字节
影响平台:Win 9X/ME/NT/2000/XP/2003
危险级别:★★


病毒主程序为EXE可执行程序,并经过添加特殊保护壳(类似于加密壳、压缩壳和虚拟机的合成体)处理。
脱壳后,提取出来的病毒文件体为恶意DLL功能组件文件,采用“Microsoft Visual C++ 6.0”编写,未经过加壳处理。


运行后,自我复制到被感染计算机系统的“%SystemRoot%\system32\”目录下,并自动以随机长度、随机名称来保存自己。

获取注册表“HKEY_LOCAL_MACHINE\Hardware\Description\System\CentralProcessor\0”项下的“~MHz”、“ProcessorNameString”和“Identifier”键的值信息。

获取系统TCP/IP协议驱动文件“%SystemRoot%\system32\drivers\tcpip.sys”的一些信息。

读取下边2个键值的信息:
获取注册表[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\{CE704903-3C4F-4CA9-9639-0069D1AE11AB}\Parameters\Tcpip]项下的“EnableDHCP”和“DhcpServer”键的值信息。

获取注册表“SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SFCDisable”项中的“Windows文件保护”功能信息。


会在后台获取被感染计算机系统中IE浏览器保存的“Cookie”信息,并查找所有的E_Mail地址(搜索带有“co”、“org”、“com”和“net”后缀名的E_Mail地址信息)。

便历用户系统中“我的文档‘My Documents’”目录(c:\Documents and Settings)下的所有文件。搜索以下后缀名的文件(“csv|txt|wab”、“c|asm|cpp|inc|nfo|info|h|wpd|sxw|xml|jtd|hwp|wps|dif|dbf|sdc|slk|wk1|wks|123|eps|ps|ott|rtf|sdw|php|doc|pdf|htm|html|tmp|sys|chm”),并查找文件内所有的E_Mail地址(搜索带有“co”、“org”、“com”和“net”后缀名的E_Mail地址信息)。

会清空被感染计算机系统中临时文件夹“Temp”下的所有带“~*”字符串文件名的临时文件。


群发恶意邮件时所使用到的格式和命令:
EHLO localhost(用户名)
AUTH LOGIN
MAIL FROM: <%s>
MAIL FROM: <%s@%s>
RCPT TO: <%s>
RCPT TO: <%s@%s>

构造某种特定数据的时间信息为:
expires = Tue, 01-Jan-1980 00:00:00 GMT

可能会与如下( mooo.com、dynserv.com、yi.org、dyndns.org)动态域名解析服务器进行信息交互通信。

系统后台建立socket连接,利用TCP和UDP协议同时进行网络数据通讯(群发垃圾电子邮件、接受骇客服务器控制指令并进行对其他服务器进行攻击性的操作、下载其它恶意程序并调用运行、自动升级等)。


使用两种启动方式开机同时启动:
1:服务方式启动,服务名“Print Spooler Service”。
2:向注册表“SOFTWARE\Microsoft\Windows\CurrentVersion\Run”项下添加新的启动项,启动项名为病毒文件名(因为病毒文件名的随机的,所以这里的病毒启动项名也是随机的)。


该病毒开发作者计算机系统中,存放该病毒源代码库的文件路径为:
“w:\projects\b3\release\core.pdb”
--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------
DLL组件文件中四处加密字符串(对应给出来了相应的解密串):

解密前:
003C4F77    68 183B3D00     PUSH 3D3B18                              ; ASCII ";`)$,a19zf(&2Qd!iJ/"VO;&zRe"8<c9JP_\/9$mQu5sU8QFJ<8dil"
解密后:
0012FF60   00374268  ASCII "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

解密前:
003C4FB4    68 503B3D00     PUSH 3D3B50                           ; ASCII "Q"</E=,Qt}+"
解密后:
0012FF04   00374338  ASCII "SFCDisable"

解密前:
003C7A2B    68 C4383D00     PUSH 3D38C4                              ; ASCII "JSC2?L6z(;@!;6x12l*_9K.='e&odneRO0R"zQN)!7M9xTF^_+t"
解密后:
0012FEDC   003743B8  ASCII "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

解密前:
003CE261    68 9C343D00     PUSH 3D349C                           ; ASCII "U\ze!K4"//15Qyy8ZJiJ{"$u\t1; `L!wD(+W'gWLqv/Og"
解密后:
0012FF60   00374268  ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------
截获的少部分通讯封包信息:

1  66.249.83.27:25  192.168.0.242:2192  44  Recv  
0000  32 32 30 20 6D 78 2E 67 6F 6F 67 6C 65 2E 63 6F    220 mx.google.co
0010  6D 20 45 53 4D 54 50 20 68 33 38 73 69 38 30 34    m ESMTP h38si804
0020  33 35 36 32 77 78 64 2E 31 35 0D 0A                3562wxd.15..

2  66.249.83.114:25  192.168.0.242:2194  44  Recv  
0000  32 32 30 20 6D 78 2E 67 6F 6F 67 6C 65 2E 63 6F    220 mx.google.co
0010  6D 20 45 53 4D 54 50 20 68 34 30 73 69 34 33 33    m ESMTP h40si433
0020  36 38 32 30 77 78 64 2E 33 36 0D 0A                6820wxd.36..

3  66.249.93.27:25  192.168.0.242:2195  44  Recv  
0000  32 32 30 20 6D 78 2E 67 6F 6F 67 6C 65 2E 63 6F    220 mx.google.co
0010  6D 20 45 53 4D 54 50 20 31 38 73 69 31 36 30 36    m ESMTP 18si1606
0020  32 36 36 36 75 67 6B 2E 31 38 0D 0A                2666ugk.18..

4  0.0.0.0:2196  :0  74  SendTo  
0000  D7 84 DE 17 C7 51 5E 47 35 22 17 21 01 D7 85 6F    .....Q^G5".!...o
0010  BD 94 E8 58 C2 8A D6 C6 1A 7F 00 B3 10 C8 C7 9D    ...X............
0020  4E C4 8E FB 40 74 75 42 E3 AD 8C 60 9F AC 16 7F    N...@tuB...`....
0030  E2 72 95 CC E9 EB 66 84 73 52 6D B2 4F D8 61 98    .r....f.sRm.O.a.
0040  20 87 EB 8F F2 F7 BD 8A 15 82                       .........
--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------
新、老变种不同之处对比:

1:在文件结构上有了很大的变化。老变种均为EXE程序,新变种为DLL组件打包后的特殊EXE程序。
2:程序文件图标不同。老变种均为“图片相册”图标,新变种为“控制台程序”图标。
3:老变种会在被感染计算机系统中的指定目录下创建压缩包文件并利用MSN向其好友发送诱惑信息进行自我传播病毒文件包,新变种则没有该功能。
--------------------------------------------------------------------------------------------
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>