freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

任意代码保护与内核代码注入的那些事儿
Alpha_h4ck 2018-06-24 13:00:23 500505

严正声明:本文仅限于技术探讨,严禁用于其他用途。

1.png任意代码保护与内核代码注入的那些事儿

写在前面的话

类似 WannaCry 和 Slingshot 这样的恶意软件最常用的一种攻击技术就是内核代码注入,在近期刚刚发布的 Windows 10 Creators 更新中,微软引入了一种针对远程代码执行的新型缓解技术-任意代码守护卫士(ArbitraryCode Guard)。在这篇文章中,我们将详细介绍Arbitrary Code Guard的工作机制,并利用内核代码注入攻击来测试这项缓解技术的有效性。

Arbitrary Code Guard(任意代码守护卫士)

微软将Arbitrary Code Guard(ACG)作为一个可选功能添加进了Windows操作系统中,它可以用来检测和防止下列情况的出现:

1.   现有代码被恶意修改;

2.   向一个数据段中写入并执行代码;

为了实现这两个目标,ACG会强制执行这条规则:内存不能同时拥有写入权限(W)和执行权限(X)。

ACG配合上代码完整性保护机制(Code Integrity Guard),Windows就可以防止攻击者将不安全或不可信的代码加载进内存之中了。

下面给出的是一份代码注入样本,它会将进程内存的状态修改为ACG想要防止出现的状态:

任意代码保护与内核代码注入的那些事儿

我们可以看到,这些注入了代码的页面同时拥有执行和写入属性。

ACG的工作流程

当系统为特定进程创建好缓解方案时,会以下列注册表路径向注册表中添加一个键:

HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Image File Execution Options

接下来,Windows会在进程创建的过程中完成缓解方案的相关设置,下面给出的是进程创建过程中的调用栈:

nt!PspAllocateProcess+0xb4b
nt!NtCreateUserProcess+0x723
nt!KiSystemServiceCopyEnd+0x13
ntdll!NtCreateUserProcess+0x14
KERNELBASE!CreateProcessInternalW+0x1b3f
KERNELBASE!CreateProcessW

下面给出的是PspAllocateProcess函数的部分代码:

任意代码保护与内核代码注入的那些事儿

其中,下面这两个函数主要负责加载缓解选项:

 PspReadIFEOMitigationOptions
 PspReadIFEOMitigationAuditOptions

这些函数会从注册表中读取下列键值:

HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Image File Execution Options

我们可以在进程监视器中看到以下活动:

任意代码保护与内核代码注入的那些事儿

接下来,MitigationsFlagsValues的值将会存储在EPROCESS结构体中:

任意代码保护与内核代码注入的那些事儿

ACG如何检测和屏蔽动态代码?

正如之前的介绍,ACG会监控内存的分配情况,并防止同时拥有写入和执行权限,当我们尝试分配虚拟内存时,调用栈如下:

nt!MiArbitraryCodeBlocked+0x30
nt!MiAllocateVirtualMemory+0x96d
nt!NtAllocateVirtualMemory+0x44
nt!KiSystemServiceCopyEnd+0x13
ntdll+0xa05c4

此时将会调用MiArbitraryCodeBlocked函数,该函数的功能如下图所示:

任意代码保护与内核代码注入的那些事儿

我们可以看到,这个函数负责检测EPROCESS中的缓解选项,并判断是否允许分配虚拟内存。下面给出的是这个函数的流程图:

任意代码保护与内核代码注入的那些事儿

该函数主要实现了下面三件事情:

1.   获取EPROCESS,检测是否启用了缓解选项,并将MitigationsFlags分配进EPROCESS(偏移量0x828)。

2.   检测ETHREAD中的CrossThreadFlags(0x6d0),以确定线程是否拥有内存分配权限或绕过缓解方案。

3.   跟踪缓解结果,返回状态TATUS_DYNAMIC_CODE_BLOCKED(0xC0000604)。

内核代码注入

接下来我们一起看一看,如果我们尝试向内核注入代码时,ACG的表现如何。这里我们会使用恶意软件常用的两种内核代码注入技术:

1.   创建一个新的线程并加载一个动态链接库文件(DLL);

2.   使用一个异步程序调用(APC)来向现有线程中加载一个DLL;

在这两种技术中,下面几个步骤是通用的:

1.   绑定目标进程;

2.   获取Ntdll地址;

3.   获取LdrLoadDll地址;

4.   通过shellcode分配虚拟内存;

5.   通过shellcode调用LdrLoadDll;

在使用新的线程实现shellocde注入时,我们需要使用NtCreateThreadEx并在shellcode中调用LdrLoadDll。另一方面,如果我们想要使用一个APC来注入shellocde,我们则需要在相应线程中使用APC函数并通过shellcode调用LdrLoadDll。

在这两种注入方法中,我们需要在分配虚拟内存时同时分配写入和执行权限,并执行shellcode。正如之前所说的,ACG可以通过防止同时分配写入和执行权限来屏蔽代码注入。下面给出的是负责分配虚拟内存的代码:

任意代码保护与内核代码注入的那些事儿

在调用ZwAllocateVirtualMemory之后设置断点(MiArbitraryCodeBlocked)。,我们将能够在windbg中看到下列信息:

任意代码保护与内核代码注入的那些事儿

返回值为STATUS_DYNAMIC_CODE_BLOCKED,因此这两种代码注入技术都无法绕过ACG。

总结

对于防止用户模式或内核模式下的代码注入来说,ACG是一种非常好的选择,但ACG目前只是一种可选项,因此如果目标设备(进程)没有开启ACG的话,攻击者仍然能够实现代码注入。

参考资料

1.   Windows10 缓解方案改进(2016年美国黑帽黑客大会):【点我获取

2.   破解ACG的那些事儿(2017年Ekoparty安全大会):【点我获取

* 参考来源:countercraft,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

# 任意代码保护 # 内核代码注入
本文为 Alpha_h4ck 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
Alpha_h4ck LV.10
好好学习,天天向上
  • 2359 文章数
  • 1023 关注者
Tetragon:一款基于eBPF的运行时环境安全监控工具
2025-01-21
DroneXtract:一款针对无人机的网络安全数字取证工具
2025-01-21
CNAPPgoat:一款针对云环境的安全实践靶场
2025-01-21
文章目录