Windows堆dword shoot

Windows NT堆dword shoot

本文总结自《0day安全:软件漏洞分析技术》,加上了一些笔者的愚见。

前置知识

在这里插入图片描述

在用户态的NT堆中,Windows系统使用链表来维护一个堆中的空闲内存:

在这里插入图片描述

从Windows 7开始,Lookaside被低碎片堆(LFH)取代,但链表思想得以延续。

如果要分配一块内存,就要从空闲链表中移出一个节点:

int remove (ListNode * node)      
{ 
	node -> blink -> flink = node -> flink; 
	node -> flink -> blink = node -> blink; 
	return 0; 
}

攻击原理

以通过修改函数返回地址实现劫持为例说明dword shoot的攻击原理。

假设内存中有一个边界检查不严格的堆块H1,我们可以通过堆溢出覆盖与H1相邻的堆块H2的块首,这样就修改了H2的blink和flink。H2在被分配时,原本会执行:

	node -> blink -> flink = node -> flink; 
	node -> flink -> blink = node -> blink; 

但是我们修改blink为堆栈中函数的返回地址(Target),修改flink为shell code的地址(payload),于是就使得:

// node -> blink -> flink = node -> flink;
*(Target) = payload;

这样就实现了任意地址写,当函数返回时,就执行了payload。

现代Windows相关防护机制

在现代版本的Windows中,启用了多种策略缓解堆溢出。这里提一下段堆机制,它和NT堆有许多差异,具体查看笔者的另一篇文章:

Windows堆管理:https://blog.csdn.net/Oorchi/article/details/161770852?spm=1001.2014.3001.5501

块首指针加密

块首中的指针(如Flink/Blink)可能被加密(与堆基址、全局Cookie进行异或),直接读取或预测其值几乎不可能。

元数据与用户数据分离

部分元数据(如块大小、状态)存储在独立的元数据区域,而非紧邻用户数据。

分配偏移随机化

在LFH中,每次分配的实际地址会在一个“桶”内随机偏移。

链表修改验证

链表操作前验证Flink->Blink == node && Blink->Flink == node

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值