AtomBombing 利用分析

发布于 2024-09-17 03:09:50 字数 6434 浏览 24 评论 0

0x00 前言

2016 年 10 月,网络安全公司 EnSilo 的研究团队公开了一个支持所有 Windows 系统的代码注入方法,将其命名为 AtomBombing。据说该方法能够绕过大多数的安全软件,并且利用的系统缺陷很难被修复。

于是,本文将要根据开源代码和资料,学习原理,测试功能,分析利用思路,总结防御方法

学习资料:https://blog.ensilo.com/atombombing-brand-new-code-injection-for-windows

作者:Tal Liberman

POC:https://github.com/BreakingMalwareResearch/atom-bombing/

0x01 简介

本文将要介绍以下内容:

  • AtomBombing 实现方法
  • 关键技术
  • 防御思路

0x02 基础知识

1、Atom Table

是一个存储字符串和相应标识符的系统定义表

应用程序将一个字符串放入一个 Atom 表中,并接收一个 16 位整数(WORD) 作为标识(称为 Atom),可通过该标识访问字符串内容,实现进程间的数据交换

分类:

(1) Global Atom Table

所有应用程序可用

当一个进程将一个字符串保存到 Global Atom Table 时,系统生成一个在系统范围内唯一的 atom,来标示该字符串。在系统范围之内所有的进程都可以通过该 atom(索引) 来获得这个字符串,从而实现进程间的数据交换

(2) Local Atom Table

只有当前程序可用,相当于定义一个全局变量,如果程序多次使用该变量,使用 Local Atom Table 仅需要一次内存操作

参考资料:https://msdn.microsoft.com/en-us/library/ms649053

常用 API:

添加一个 Global Atom:

ATOM WINAPI GlobalAddAtom(_In_ LPCTSTR lpString);

删除一个 Global Atom:

ATOM WINAPI GlobalDeleteAtom(_In_ ATOM nAtom);

查找指定字符串对应的 Global Atom:

ATOM WINAPI GlobalFindAtom(_In_ LPCTSTR lpString);

获取指定 atom 对应的字符串:

UINT WINAPI GlobalGetAtomName(
  _In_  ATOM   nAtom,
  _Out_ LPTSTR lpBuffer,
  _In_  int    nSize
);

注:

使用实例可参考如下连接:https://github.com/sinmx/Windows2K/blob/661d000d50637ed6fab2329d30e31775046588a9/private/windows/base/client/tatom.c

2、APC 注入

APC 全称 asynchronous procedure call,即异步过程调用

APC 注入原理:

当线程处于警戒状态时,会检查 APC 队列,如果 APC 队列被插入函数指针,该函数将会得到执行

APC 注入细节:

(1) 当线程调用 SleepEx、SignalObjectAndWait、MsgWaitForMultipleObjectsEx,WaitForMultipleObjectsEx 或者 WaitForSingleObjectEx 函数时,会切换到警戒状态(alertable state)

注:警戒状态可参考:https://msdn.microsoft.com/en-us/library/windows/desktop/aa363772(v=vs.85).aspx

(2) 当线程进入警戒状态时,会循环检查线程中的 APC 队列,如果 APC 队列中存在函数指针,那么就会调用该函数

(3) 使用 QueueUserAPC 函数向 APC 队列插入函数指针 Loadlibrary(),实现加载 DLL

(4) 注入成功后,警戒状态结束,程序继续运行,有可能造成程序不稳定,导致程序崩溃

(5) 如果没有删除 APC 队列,不能反复注入同一函数

(6) 使用 APC 注入,需要目标进程中至少有一个线程处于警戒状态或者能够进入警戒状态,否则无法实现 APC 注入

注:大部分系统进程都满足条件,支持 APC 注入

可供参考的 APC 注入代码:https://github.com/3gstudent/Inject-dll-by-APC

3、shellcode

在漏洞利用中,shellCode 是指输入到存在漏洞的程序中的代码

相当于一个二进制代码框架,最终会将程序的流程跳转到 payload

4、payload

主要功能代码(常见的如下载执行、反弹 shell、新建用户等),包含在 shellCode 中

0x03 实现方法

1、将任意数据写入目标进程地址空间中的任意位置(Write-What-Where)

通过读写 atom 向目标进程传递 shellcode

自身进程通过 GlobalAddAtom 将 shellcode 添加到 Global Atom Table 中,目标进程调用 GlobalGetAtomName 即可从 Global Atom Table 中获取 shellcode

所以接下来的关键是如何使目标进程调用 GlobalGetAtomName

Tal Liberman 的思路是通过 APC 注入,使目标进程调用 GlobalGetAtomName

但是这里遇到了一个难题,QueueUserAPC 函数只能向目标进程传入一个参数,而 GlobalGetAtomName 需要三个参数

于是 Tal Liberman 调试了 QueueUserAPC 函数,发现通过 NtQueueApcThread 函数能够传递三个参数

该问题得到解决

2、执行 shellcode

目标进程调用 GlobalGetAtomName 从 Global Atom Table 中获取 shellcode 后,需要先保存 shellcode 再执行

第一种实现方法: 找到一段 RWX 的内存存储并执行

不通用,目前的系统保护机制很难找到这样的内存空间

第二种实现方法: 调用 VirtualAllocEx 分配一段内存

常用方法

注:

其他常见方法如通过 VirtualProtect 将 shellcode 的内存属性设置为可读可写可执行,然后跳到 shellcode 继续执行在这里的效果并不好,因为需要考虑使用 QueueUserAPC 函数传入参数的问题

所以 Tal Liberman 尝试了第三种方法: 找到一段 RW 的内存写入数据,构造 ROP 链实现 shellcode 的执行

寻找一段 RW 的内存并不难,Tal Liberman 选择了 KERNELBASE 数据段后未使用的空间

ROP 链实现了以下功能:

  1. 申请 RWX 内存
  2. 将 shellcode 从 RW 内存处拷贝到 RWX 内存储
  3. 执行

注:

在 ROP 链的构造上,Tal Liberman 提供了自己的思路,尽可能简化 ROP 链,优化思路值得学习

3、恢复执行

注入后需要恢复目标进程的执行,使用未公开的函数 ZwContinue

0x04 实际测试

测试系统: Win7 x86

安装 python,安装 pefile(easy_install pefile)

编译生成 AtomBombing.exe、AtomBombingShellcode.exe 和 AtomBombingShellcode.h

注:AtomBombingShellcode.h 由 \AtomBombingShellcode\Scripts\Post_Link.py 生成,可在 AtomBombingShellcode 工程中的后期生成事件中查看具体参数,如下图

Alt text

启动 chrome.exe,执行 AtomBombing.exe,注入成功,如下图

Alt text

Alt text

补充:

Windows 8.1 update 3 和 Windows 10 添加了一个新的保护机制 CFG(Control Flow Guard),CFG 的绕过可参考如下链接:https://blog.ensilo.com/atombombing-cfg-protected-processes

0x05 利用分析

综合公开资料和实际测试,可以将 AtomBombing 理解为一个 APC 注入的升级版: 利用 Atom Table 传递 shellcode,通过 NtQueueApcThread 实现 APC 注入,shellcode 采用构造 ROP 链的方式,实现了申请内存、写入 payload(弹出计算器) 并执行的功能

Atom Table 支持 Windows 全平台,并且短期内该功能不会被取消,也不存在修复措施,所以可以在某种程度上理解为不存在修复 AtomBombing 的补丁

但是,想实现 AtomBombing 的利用,需要综合考虑多个问题(如获取处于警戒状态的线程、通过 NtQueueApcThread 传入参数、寻找 RX 内存,构造 ROP 链等),利用门槛较高

并不适用于所有进程(目标进程中至少有一个线程处于警戒状态或者能够进入警戒状态)

能绕过部分杀毒软件,但不能绕过所有的杀毒软件(使用 NtQueueApcThread 进行注入)

0x06 检测防御

将 AtomBombing 理解为 APC 注入的升级版,所以参照 APC 注入的防御方法即可,攻击者首先需要获得系统的执行权限,并找到符合条件的进程

检测:

监控 NtQueueApcThread 函数的调用

0x07 小结

本文介绍了 AtomBombing 的实现思路和关键技术,经过实际测试,得出最终结论,AtomBombing 是一种新的 DLL 注入方法,可以理解为一个 APC 注入的升级版: 利用 Atom Table 传递 shellcode,通过 NtQueueApcThread 实现 APC 注入,shellcode 采用构造 ROP 链的方式,实现了申请内存、写入 payload(弹出计算器) 并执行的功能

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

大海や

暂无简介

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文