freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

威胁分析与响应能力—Shellcode分析与检测技巧
2022-06-29 18:25:53
所属地 北京

01shellcode简介

shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。

1.1  依赖项

因Shellcode有一些依赖关系,所以编写Shellcode存在一定难度。

  • 长度 - 因为 shellcode 利用内存中的特定漏洞,所以序列需要尽可能的高效。这意味着攻击者必须使其长度适合于缓冲区的大小,所有的指令都将在内存空间中运行。如果shellcode的长度大于缓冲区的大小,可能造成程序崩溃或甚至被非法利用(如缓冲区溢出等)。
  • 不允许的字符 - 当shellcode 中出现‘\r’, ‘\n’,0x00等字符时,代码将终止运行。例如,当'Null Bytes'(如0x00值)被读取时,CPU会将它识别为字符串的结束(Null Terminator)。

1.2  Unix Shellcode

Unix操作系统提供了直接访问通信和管理内核的途径—指令int 0x80。因此,当系统调用跟随该指令设置时,shellcode 将直接被赋予以高权限执行的能力。

1.3  Windows Shellcode

在基于Windows的操作系统中,由于内存保护机制,如ASLR(地址空间布局随机化)等,创建shellcode比较困难。

02内存中查找 API 函数的地址

一般情况下,shellcode会被注入到一个正在运行的进程中,没有任何关于内存状态以及 API 函数地址的预先知识,据此可以得出结论:shellcode不能以静态地址为基础。

如上所述,shellcode不能使用Call CreateProcessA或jmp sub_40100000这样的指令,必须独立运行才能找到所需的 API 函数并手动解析地址。换句话说,要找到使用的DLL需要基于内存中对象的结构。这也是它被称为位置无关代码(PIC)的原因。

示例:要调用GetProcAddress,shellcode 需要找到Kernel32.dllDLL 的地址。

操作流程如下:

2.1  PEB - 过程环境块

因PEB 对象总是被加载到内存的同一个地址FS:[0x30],所以 shellcode 可以使用。

执行步骤:

  1. 转到 PEB 对象。

  2. 传递PEB_LDR_DATA对象到InMemoryOrderModuleList链表,其中包含有关进程加载模块的信息。在此之后,shellcode 将保存所需模块(通常Kernel32.dll是第三个对象)。

  3. DllBase 使用该字段查找所需 DLL 的基地址。

  4. 找到它的导出表。

  5. 找到想要的功能(如GetProcAddress)。

  6. 使用函数获取函数的地址GetProcAddress。

  7. 最终,使用合适的参数运行想要的功能。

2.2  使用SEH—结构化异常处理

该技术是通过输入TIB(线程信息块)的第一个属性来访问SEH链的底部,它有一个常数地址--FS:[0x0]。该地址包含Kernel32.dll模块的默认异常处理程序。要定位所需模块的地址,可以返回内存地址,直到找到模块的入口点为止。(使用MZ签名或0x5A4D为例)。

2.3  使用TEB——线程环境块

与 SEH 技术一样,可以访问 TEB 对象,该对象在内存中有固定的位置 — FS:[0x18]. 通过这个对象可以进入 SEH 链,如上所述。

2.4  TopStack

该方法依赖于在堆栈中具有所需 API 函数的所需 DLL 的地址,所以并不常见。

2.5  通过哈希查找API 函数

这种技术也被称为SFHA(Stephen Fewer’s Hash API)。它使用4个字节来表示DAX寄存器中的DLL!WinAPI内部函数的Hash值。然后向该地址发送JMP调用该函数。需要注意哪个函数从EAX被调用,以及得到了哪些参数(可以在MSDN中查看)。接下来比较内存中的实际值。例如,如果一个shellcode调用Win_Exec函数,将通过每一个DLL!WinApi使用其他技术之一,并带有其他参数(可以通过寄存器调用前的PUSH指令识别)。当输入参数的内存地址时就可以知道该地址的内容是什么(也许是PS1脚本或编码命令)。

03shellcode检测

对shellcode有所了解之后,下面探讨如何检测 shellcode。

首先注意去掉混淆,解密一个混淆或加密的脚本,以暴露出shellcode真实代码。

3.1  使用行为模式

如上所述,shellcode 是表示指令的 Opcodes 序列。因此可以找到这个序列并对其进行检查。

如果有恶意程序的源代码运行 shellcode(如 PowerShell 或 JavaScript),可以寻找可能代表Opcodes的值/变量/字符串,该方式有利于找到shellcode本身。

下面来看这条指令:mov ebp, esp。shellcode使用的字符序列可以有多种格式:

  • 十六进制值:8B EC

  • 反斜杠十六进制值:\x8B\EC

  • Unicode 百分比: %u8B%EC

  • 反斜杠 Unicode:\u8B\uEC

  • Array:[0x8B, 0xEC]

重点关注这些字符的序列可以代表 CPU 指令。

04转储 shellcode

在检测到潜在的 shellcode 后,将其转储到二进制文件是第一步。

  • base64dump.py工具 — 允许查找可能包含 shellcode 的部分并将其转储到二进制文件 ( .bin) 中,以便对其进行分析
  • 参数:
  1. pu — 允许搜索用于百分比 Unicode 编码 ( %u) 的字符串。

  2. bu — 允许搜索用于反斜杠 Unicode 编码 ( \u) 的字符串。

  3. hex — 允许搜索用作十六进制值的字符串。

  4. base64 — 允许使用 Base64 编码搜索字符串。

base64dump.py -e {param} {file} -s {sectionID} -d > {outFile.bin}

允许通过 ID 定位想要的部分,并将其转储到二进制文件中。大多数情况下将选择最大的部分

base 64 dump . py { param }{ file }- s { section ID }- a

显示所选部分的十六进制视图。

  • objdump.pytool — 允许在提取 shellcode 时转储。

  • Using a Hex-Editor — Hex-Editor 可用于删除不相关的部分,剩下的 shellcode代码可以保存到.bin文件中。

05如何分析shellcode

可以通过两种主要方式分析 shellcode :静态分析和动态分析。

5.1  静态分析——代码分析

通过静态分析,包含 shellcode 的二进制文件将被转换为可执行文件,并被加载到反汇编程序(如 IDA PRO)中。然后被分析为可执行文件。

用法:

shellcode2exe.py {file.bin}shellcode2exe.bat {32\64} {file.bin} {file.exe}

5.2  动态分析

scdbg工具--允许模拟shellcode的执行,以便找到它所使用的API函数,这可以表明shellcode的许多行为。

scdbg -s {steps} -f {file.bin}
  • 运行GUI scdbg工具并向其启动二进制文件。

  • 使用FindSC将在加载的二进制文件中找到shellcode的开头。

jmp2it工具--允许在一个专门的进程中执行shellcode,该进程作为可执行文件的 "外壳"。因此可以将调试器附加到运行的进程中,便于分析人员调试shellcode。

  • jmp2it {file.bin} {offset}—offset表示 shellcode 从二进制入口点的偏移量(0x0用于开始)。

shellcode_launcher.exe--与之前的工具类似。

# 系统安全 # 数据安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录