Private Data是一个512G大小的内存空间,起始地址是0x0000180~00000000. 我们可以看见,其中有很多是Read/Write属性的内存区块。
在这些区块间插入很多reserved属性的内存区域。仔细看可以发现,这些大小44k,48k的区域就是不同线程的“影子栈”的区域。这里我们可以看
到MS采取的一个技巧就是存在一个大小是279G左右的reserved区域从180~00000000开始。其实这个reserved区域在每个进程它都大小不同,
我把它叫做“随机的reserved”区域,目的就是使得后面的“影子栈”区域变得更随机化,因为它的大小不同,导致“影子栈”分配的地址有变化。
因为这些“影子栈”区域是存在的vadroot树中,显然,我们如果能找到用户态的API也是通过解析vadroot来获得信息,我们就有可能获得影
子栈的内存信息,进而通过修改这块区域的数据来绕过RFG的防护。NtQueryVirtualMemory或者VirtualQueryEx都满足上述要求,NtQueryVirtualMemory
实际上是后者的最终的调用。 这样,我们利用这样的API满足下面2个条件就可以获得“影子栈”的区域了。
1 连续的内存类型是MEM_PRIVATE , protection 是READ/WRITE属性。
2 连续的内存大小是44k ~ 48k 大小,中间夹杂reversed属性的内存。
满足上面条件就可以判断出搜索到的了一块“影子栈”区域了。 但目前情况是,NtQueryVirtualMemory/VirtualQueryEx
在浏览器Edge中都是被CFG保护的函数,我们不能利用这2个API来获得“影子栈”区域。
我这里面说一种情况供大家参考(因为后续版本已经改变了这样的影子栈结构,这样的猜测已经意义不大了),假设浏览器中我有一个能任意
地址读写漏洞,那么要猜测到这个“影子栈”地址需要怎么样的复杂性呢?
首先我们知道这片大小512G的“影子栈”区间是在进程创建时分配出来的,在开启RFG保护后,每一个线程创建时都在这片区间内提交一个部分内存
区域当作“影子栈”。反复的测试,我发现这片大的区域差不多分布在如下几个区域:
ULONG64 nShadowAddr[] = { 0x00000200~00000000, 0x00000280~00000000, 0x00000300~00000000, 0x00000180~00000000 };
我们以0x000001c2~BAFF5000大小是44k的这个“影子栈”举例,
1 显然,“影子栈”地址的开头5位是0,是不需要猜测的,结尾3位也是0,也是不需要测试的。因此对于上边界就是从200,280,180,300开始的一块内存
区域,仅需要猜4次。
2 多数“影子栈”以F5结尾,所以这个2位我不去猜,我默认猜测的区域以F5结尾。
3 因为总大小固定为512G左右,故“随机的reserved“区域只能出现为0~100G,100~200G,200~300G,300G~400G. 500G = 0x80~00000000 ,
故“随机的reserved”出现的大小仅可能是10~00000000,20~0000000,30~0000000,40~0000000,50~0000000,60~0000000,70~0000000这样的边界。
以180~00000000 为例,“影子栈”可能的边界就是18+(0~7)介于{18,1F}这个区域,只需要遍历7次。
总结,就是开头8位我都不需要猜,1c2我不需要测,结尾的F5我也不需要测。其实我只需要测试中间的3位,为什么是BAF,当然还是不能避免依次
遍历200,280,300开始的上边界,直道遇到180的边界开始猜测{18~1F}区域以F5结尾的可读写内存区域。0x000001c2~BAFF5000这个“影子栈”地址
在一定的技巧下猜测可以在大概不到1分钟的情况下获得一个“影子栈”的边界,写程序测试如下,
not found a readable memory of target process at 000001C2B11F5000
not found a readable memory of target process at 000001C2B21F5000
not found a readable memory of target process at 000001C2B31F5000
not found a readable memory of target process at 000001C2B41F5000
not found a readable memory of target process at 000001C2B51F5000
not found a readable memory of target process at 000001C2B61F5000
not found a readable memory of target process at 000001C2B71F5000
not found a readable memory of target process at 000001C2B81F5000
not found a readable memory of target process at 000001C2B91F5000
not found a readable memory of target process at 000001C2BA1F5000
not found a readable memory of target process at 000001C2BB1F5000
.....>>> found a readable memory of target process at 000001C2BC1F5000
Message:[10]
Message:[11]
PID:596,read process handle:0
read a buff of target process:
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。