CFG保护机制校验逻辑分析

CFG(Control Flow Guard)是微软推出的漏洞利用缓解机制,从Windows 8.1开始引入,并且需要编译器的支持,编译器的版本为Virtual Studio 2015 Updated 2版本以上。

在开启了CFG支持以后,编译生成exe程序中,所有间接调用前面都会插入一个_guard_check_icall的检查函数,如果系统不支持CFG机制,则该函数不会生效。

如:

eax,[esi]
ecx, eax
call _guard_check_icall  // CFG检查函数
call eax

_guard_check_icall函数的地址,在PE程序被系统加载的时候会被替换成nt!LdrpValidateUserCallTarget函数的地址
nt!LdrpValidateUserCallTarget函数的参数就是上面ecx的值,也就是间接调用的函数地址

校验逻辑如下:

1)间接调用函数地址共4字节,取高3字节的值加上CFGBitmap表的基址,得到CFGBitmap表中的值
2)判断间接调用地址是否0x10对齐:
2.1) 如果是对齐的,函数地址的第4-8位的值,就是上面获取的CFGBitmap表值的位偏移
2.2) 如果不是对齐的,函数地址的第4-8位的值,再或上1,得到的值就是CFGBitmap表值的位偏移
3)验证CFGBitmap表值的位偏移处的bit位,如果是1,则说明这个函数是有效的,否则产生异常

在PE结构的loadConfig信息中保存了:

1)_guard_check_icall的函数地址
2)CFGBitmap表的RVA,这里面是该程序的每个函数的RVA转换成1bit的值,制作成的一个CFGBitmap表
3)CFGBitmap中函数的数量

假设目标函数地址为:0x01321380

二进制表示为:
0000 0001 0011 0010 0001 0011 1000 0000

通过对目标地址右移8位,获取高3字节的值: 0x13213(0x01321380 >> 8 )
通过对目标地址右移3位,再取5位的值作为结果:0x264270(0x01321380 >> 3)

0x264270的二进制表示为:
0000 0000 0010 0110 0100 0010 0111 0000

取前5位作为offset:
1 0000

也就是等于对原目标函数地址的二进制位取前4-8位:
0000 0001 0011 0010 0001 0011 1000 0 000

等于16进制的0x10,10进制的16
在这里插入图片描述

现在我们得到两个值,一个是 0x132130x10

假设CFGBitmap的基址+0x13213*4 的位置取4字节内容是0x11010044

这个值就是对应目标函数的CFGBitmap,它的二进制位表示为:
0x11010044 = 0001 0001 0000 0001 0000 0000 0100 0100

在二进制位的第16位的位置,因为是从0开始数,也就是第17位:
0001 0001 0000 000 1 0000 0000 0100 0100

判断这一位是否为1,如果为1,就说明目标函数地址有效。否则产生异常。

通过IDA查看nt!LdrpValidateUserCallTarget函数:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值