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

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

写在前面的话

类似 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会在进程创建的过程中完成缓解方案的相关设置,下面给出的是进程创建过程中的调用栈:

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

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

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

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

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

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

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

此时将会调用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的话,攻击者仍然能够实现代码注入。

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

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2018-06-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

redis 学习笔记(6)-cluster集群搭建

上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,...

23650
来自专栏大数据实战演练

Nginx安装配置及使用

-bash:warning:setlocale:LC_CTYPE:cannot change locale(en_US.UTF-8):Nosuch fileor...

46720
来自专栏菩提树下的杨过

redis 学习笔记(6)-cluster集群搭建

上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,...

22250
来自专栏緣來來來

Django配置缓存机制

Django 官方关于cache的介绍:https://docs.djangoproject.com/en/dev/topics/cache/

15810
来自专栏.net core新时代

nginx+iis实现负载均衡

  最近在研究分布式系统架构方面的知识,包括负载均衡,数据库读写分离,分布式缓存redis等。本篇先从负载均衡服务架构入手,关于负载均衡百度百科的定义如下:负载...

37580
来自专栏知无涯

PHP5.4+Apache2.2+Mysql5.0+PHPMyAdmin3.2.5安装配置

543110
来自专栏雪胖纸的玩蛇日常

django2+uwsgi+nginx上线部署到服务器Ubuntu16.04(最新最详细版)

36260
来自专栏芋道源码1024

快速测试 API 接口的新技能

在日常开发过程中,我们或多或少都涉及到 API 接口的测试。例如,有的小伙伴使用 Chrome 的 Postman 插件,或者使用火狐的 restclient ...

11900
来自专栏运维小白

11.24 静态元素过期时间

配置静态元素过期时间目录概要 浏览器访问网站的图片时会把静态的文件缓存在本地电脑里,这样下次再访问时就不用去远程下载了 增加配置 <IfModule mod_e...

19190
来自专栏编程坑太多

『高级篇』docker之Python开发信息服务(11)

PS:thrift的开发流程是: 先定义thrift的文件,然后通过命令生成对应的python代码。通过实现定义的thrift方法,来完成thrift的调用。

31630

扫码关注云+社区

领取腾讯云代金券