前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[ Windows 10 x64中的RFG(Return Flow Guard)技术研究 ]8

[ Windows 10 x64中的RFG(Return Flow Guard)技术研究 ]8

作者头像
franket
发布2022-06-29 16:51:50
5331
发布2022-06-29 16:51:50
举报
文章被收录于专栏:技术杂记
代码语言:javascript
复制
 我们可以控制参数2指向待测试的内存,让其拷贝到我们分配的一段内存空间,即参数1,如果成功说明待测试内存可读。否则说明不可读。当然这里
面有一个风险,待测试的目标内存如果刚好是很长的一个串结尾。而参数1不够长则会出现问题。

   同样,我们也可以是GlobalLock函数来达到一样的目的。这个函数也是可以bypass CFG保护的,而且只需要一个参数更方便控制。

LPVOID WINAPI GlobalLock(
  _In_ HGLOBAL hMem
);


   还有就是我们如果可以在Edge中分配出512G的内存空间,那么这个新分配出的空间将靠近在“影子栈”区域,这会方便我们搜索时尽量减少预测的数
据长度。

  但不够幸运的是,在15016版本的时候Edge已经把这些函数都加入到CFG防护的列表当中了。也就是说这一类的函数都不能进行读内存的利用了。同样
的原因NtQueryVirtualMemory/VirtualQueryEx 也都很早的被加入了CFG的sensitive API列表里面,这似乎也可以说明不存在更上一层的调用路
径回去调用这2个API去获得内存块的具体信息。所以脚本层面的利用已经非常困难的了。


   另外,就是可以考虑可以修改RFG的异常时的跳转问题。在RFG比较失败的情况下会跳向对应_guard_ss_verify_failure:

	00007ff7`58e526e2 644c8b1c24      mov     r11,qword ptr fs:[rsp]
	00007ff7`58e526e7 4c3b1c24        cmp     r11,qword ptr [rsp] 
	00007ff7`58e526eb 0f85ef350100    jne     MicrosoftEdgeCP!_guard_ss_verify_failure (00007ff7`58e65ce0)
	00007ff7`58e526f1  c3             ret  

	//跳向这里
	MicrosoftEdgeCP!_guard_ss_verify_failure:
	00007ffb`c52b0580 4d33db         xor     r11,r11
	00007ffb`c52b0583 ff25e7f33800    jmp     qword ptr [chakra!_guard_ss_verify_failure_fptr (00007ffb`c563f970)]
	00007ffb`c52b0589 cc              int     3

	//我们查看这里的信息
	0:011> x chakra!_guard_ss_verify_failure_fptr
	00007ffa`0495f970 chakra!_guard_ss_verify_failure_fptr = <no type information>
	 
	//替换
	0:011> dqs  chakra!_guard_ss_verify_failure_fptr 
	00007ffa`0495f970  00007ffa`238fe8c0 ntdll!LdrpHandleInvalidReturnAddress//替换这里的指针
	00007ffa`0495f978  00007ffa`238fe910 ntdll!RtlGuardVerifyReachableStackPointer
	00007ffa`0495f980  00000000`00000000
	00007ffa`0495f988  00007ffa`04323a60 chakra!jscriptinfo_IID_Lookup+0x2a60
	00007ffa`0495f990  00007ffa`04323a70 chakra!jscriptinfo_IID_Lookup+0x2a70 

	chakra!_guard_ss_verify_failure_fptr 所在内存区域的属性
	Usage:                  Image
	Base Address:           00007ffa`04904000
	End Address:            00007ffa`04a9e000
	Region Size:            00000000`0019a000 (   1.602 MB)
	State:                  00001000          MEM_COMMIT
	Protect:                00000002          PAGE_READONLY
	Type:                   01000000          MEM_IMAGE
	Allocation Base:        00007ffa`04320000
	Allocation Protect:     00000080          PAGE_EXECUTE_WRITECOPY

   如果有办法修改 chakra!_guard_ss_verify_failure_fptr的内存属性为可写,将其LdrpHandleInvalidReturnAddress指针替换为我们的一个控制的
 函数,这样也可以绕过RFG。

   总之,在详细分析过后,就是RFG的整体防护情况来看是具有很高的强度防御来应对ROP/控制流劫持等攻击。但其实我们都知道,CFG的弱点是可以通过直接的修改函数栈
上的return地址来绕开,避免寻找直接的方法绕过。RFG的开启,CFG才形成了真正意义上的完整性防护。单纯的内存破坏层面的利用在DEP+ASLR+CFG+RFG的配合下必
将变得越来越难突破。


[0x04].致谢

   最后,非常感谢我的同事Sun Bing在RFG研究方面给予的非常重要的提示和帮助,一同调试研究了非常多的技术细节,才得以使得本篇文章得到了整理和汇总。


注意: 
   微软已经从漏洞悬赏计划里面撤掉了RFG防护,仅作为一个Research Project。说明RFG设计本身存在一个很大的问题。接下来会发生什么谁也不知道了。我们已经知道几个点上可能被
绕过的情况,但不确定是否是微软撤掉RFG的根本原因。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档