绕过Windows 10的CFG机制

0x00 前言

本文是2016年7月一些研究的结果,但是直到现在才能发布。在6月,Theori发布了一篇博文关于IE的漏洞MS16-063,他们写的利用是针对Windows7上IE 11版本,并且他们认为因为Windows 10 的CFG机制无法在Windows 10利用。本文描述了我如何在Windows 10利用,并绕过CFG,事实我还发现了另一种方法,会在将来发布。

0x01 理解CFG

控制流保护(CFG)是微软在Windows 8.1 update 3和Windows 10中实现的缓解措施,用来保护汇编级别的非直接调用。趋势已经公布了Windows 10上面关于CFG的很好的分析文章。已经有集中公布的绕过CFG的方法,但是这些方法主要的目标是CFG实现算法,但是我想从这个功能的弱点入手。因为Theori在他们博文中写的Windows 7上面的利用因为CFG的存在无法有效工作,让我们看下为什么并试图绕过它。

来自Theori的利用代码在Windows 10的IE中直接覆盖了虚函数表。因此问题是我们如何利用任意读写来绕过CFG。根据趋势的研究,CFG被函数LdrValidateUserCallTarget调用来验证一个函数的调用是否用了非直接调用:

加载到EDX中的指针是验证位图的基本指针,在这种情况下是:

然后,被验证的函数将其地址加载到ECX中,如果kernel32!VirtualProtectStub作为示例,则在这种情况下的地址是:

然后地址右移8位,用于装入保存该地址有效位的DWORD值,在这种情况下:

然后函数地址右移3位,并执行位测试,这本质上对位移地址进行模数0x20操作,然后是验证位图的DWORD中检查的位,因此在这种情况下:

因此相关位在偏移0x14处:

这意味着它是可靠的。因此VirtualProtect的调用地址是可靠的,然而这没有真的解决问题,它的参数也必须由攻击者提供。正常情况应该是用ROP链,但是任何不是从函数开始的字节都是无效的。因此解决方案是找到一个函数在被调用的地方的参数是可以控制的,并且函数的功能可以给攻击者利用。这需要在利用中非常仔细。

0x02 在Windows 10中利用

在Theori提供的利用,代码是通过stack pivot小配件覆盖TypedArray的虚函数表,因此这个没有其他可能了,研究TypedArray提供的函数是值得的,发现下面两个函数比较有用:

他们的偏移是0x7c和0x188,他们能从javascript代码中直接调用,并且HasItem有个可以控制的参数,同时Subarray有两个用户可控制的参数。然而问题是它们都不返回除布尔值之外的任何数据。此外,所选择的函数必须采用相同数量的参数,否则堆栈不平衡将会引发异常。我搜索的API应该暴露一个指针能用来覆盖返回地址,以便可以绕过CFG。

我定位的可用的API是RtlCaptureContext,由kernel32.dll、kernelbase.dll和ntdll.dll导出,这个API有一个指向CONTEXT结构的参数:

CONTEXT结构储存了转储的所有的寄存器(包括ESP),而且输入值仅仅是一个缓冲区的指针。看一下TypedArray对象的内存布局:

第一个DWORD值是虚函数表指针,能够被覆盖创建一个假的虚函数表,在偏移0x7c处存储API RtlCaptureContext的地址,同时偏移0x20是TypedArray指向的真实数据的指针:

因为泄漏这个缓冲区的地址也是可能的,它能提供RtlCaptureContext的参数。为了完成夹的虚函数表,不得不创建一个指针指向偏移0x7c处的ntdll!RtlCaptureContext,这意味着泄露了RtlCaptureContext的地址,继而意味这泄露了ntdll.dll的地址。执行此操作的默认路径是使用vtable的地址,它是一个指向jscript9.dll的指针:

从这个指针往回0x1000个字节,搜索MZ头,继而查找到指向kernelbase.dll的导入表。做同样的操作能偶获得kernelbase.dll的基址,然后再获得ntdll.dll的导入表指针并再次获得其基址,然后从导出函数中找到RtlCaptureContext。尽管这个方法是可靠的但是有个缺陷,如果在系统中装了EMET,将触发来自jscript9.dll的代码的崩溃,因为从PE头或导出表读取数据不被允许,为了绕过EMET我使用了一个不同的技术。记住每一个非直接调用都被CFG保护,因为jscript9.dll的函数被CFG保护了,所以不能调用直接指向ntdll的函数。一个在虚表中偏移0x10的函数如下:

用原始读操作,指向ntdll.dll的指针能通过以下函数找到:

通过ntdll.dll的指针得到RtlCaptureContext的地址,不通过读取导出表而是使用搜索特征和哈希找到并读取。RtlCaptureContext看起来如下:

前0x30字节总是相同的并且很特殊,因此可以用哈希碰撞找到函数地址:

函数可以使用指向ntdll.dll的指针作为参数。

把上面的都整合到一起:

 

从这偏移0x200包含了RtlCaptureContext的结果,看起来如下:

 

从上面可以清楚地看出堆栈指针已经泄漏,现在找到一个能控制执行的地址是个问题。看下栈顶显示:

那就是当前函数的返回地址,这个地址位于与RtlCaptureContext信息中的偏移0x9C处的泄漏指针相距0x40字节的偏移处。运气好,这个偏移对于其他简单函数将是相同的,所以应该可以写入并使其覆盖其自己的返回地址,从而绕过CFG。

利用补充如下:

运行时显示EIP控制:

而且,在偏移0x40和0x44的写入现在位于栈顶,允许创建一个stack pivot和ROP链,一种方法是用POP EAX接着XCHG EAX,ESP。

0x03 微软缓解措施

Microsoft已经声明,堆栈上的损坏返回地来绕过CFG是一个已知的设计限制,因此无法修复或领取任何种类的赏金,如下所示:

 

正如那个所说,微软做了两个事情来缓解这个技术,首先在未来的Windows 10版本中,RFG将被实现,阻止堆栈损坏以给予执行控制的方式。另一个是在Windows 10的周年版发布中引入敏感的API的介绍,它仅保护微软Edge,但是上述情况无法保护,但是他能阻止微软Edge中的RtlCaptureContext。Poc代码可以在这找到:https://github.com/MortenSchenk/RtlCaptureContext-CFG-Bypass。

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/148381.html<

(0)
运维的头像运维
上一篇2025-03-12 03:18
下一篇 2025-03-12 03:19

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注