【pwn学习】堆溢出(一)
文章目录
- 什么是堆溢出
- 基本示例
- 堆分配函数
- 堆填充长度
- 堆攻击总结
学习这部分之前,如果对堆的基础还不甚了解可以参考一下下面的学习笔记
- Linux堆管理基础知识(一)
- Linux堆管理基础知识(二)- 数据结构
什么是堆溢出
堆溢出是指程序向某堆块(chunk)中写入的字节数超过了堆块本身可使用的字节数,因而导致了数据溢出,并覆盖到物理地址相邻的高地址的下一个堆块。这里之所以是可使用而不是用户申请的字节数,是因为堆管理器会对用户所申请的字节数进行调整,这也导致可利用的字节数大于等于用户申请的字节数。
ptmalloc 分配出来的大小是对齐的。这个长度一般是字长的 2 倍,比如 32 位系统是 8 个字节,64 位系统是 16 个字节。但是对于不大于 2 倍字长的请求,malloc 会直接返回 2 倍字长的块也就是最小 chunk,比如 64 位系统执行
malloc(0)
会返回用户区域为 16 字节的块。
因此,要利用堆溢出要满足两个前提
- 程序向堆上写数据;
- 写入的数据大小没有被控制;
与栈溢出的不同在于,堆上没有返回地址等让攻击者直接控制执行流程的数据,因此一般我们无法通过堆溢出来控制EIP。所以攻击人用来利用的方式一般如下
- 覆盖与其物理相邻的下一个chunk的内容。
- prev_size;
- Size.
- Chunk content
- 利用堆中的机制(如 Unlink等)来实现任意地址写入(Write-Anything-Anywhere)或控制堆块中的内容等效果,从而来控制程序的执行流。
基本示例
// example-1.c
#include <stdio.h>int main(void)
{char *chunk;chunk=malloc(30);puts("Get input:");gets(chunk);return 0;
}
利用gdb调试,malloc执行后chunk的mem指针eax=0x804d1a0
。
Allocated_chunk
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Size of previous chunk, if unallocated (P clear) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Size of chunk, in bytes |A|M|P|mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| User data starts here... .. .. (malloc_usable_size() bytes) .. | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| (size of chunk, but used for application data) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Size of next chunk, in bytes |A|0|1|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
查看内存,根据allocated_chunk的结构,储存地址的上面4个字节是chunk的size。
pwndbg> x/30x 0x804d1a0-0x4
0x804d19c: 0x00000031 0x00000000 0x00000000 0x00000000
0x804d1ac: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1bc: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1cc: 0x00000411 0x20746547 0x75706e69 0x000a3a74
0x804d1dc: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1ec: 0x00000000 0x00000000 0x00000000 0x00000000
执行gets,输入100个‘a’后查看内存
pwndbg> x/30x 0x804d1a0-0x4
0x804d19c: 0x00000031 0x61616161 0x61616161 0x61616161
0x804d1ac: 0x61616161 0x61616161 0x61616161 0x61616161
0x804d1bc: 0x61616161 0x61616161 0x61616161 0x61616161
0x804d1cc: 0x61616161 0x61616161 0x61616161 0x61616161
0x804d1dc: 0x61616161 0x61616161 0x61616161 0x61616161
0x804d1ec: 0x61616161 0x61616161 0x61616161 0x61616161
0x804d1fc: 0x61616161 0x61616161 0x00000000 0x00000000
0x804d20c: 0x00000000 0x00000000
可以发现原chunk后面跟的内存被覆盖了。
堆分配函数
- calloc
calloc 与malloc的功能类似,都是用来分配内存的。calloc 与 malloc 的区别是 calloc 在分配后会自动进行清空,这对于某些信息泄露漏洞的利用来说是致命的。
calloc(0x20);
//等同于
ptr=malloc(0x20);
memset(ptr,0,0x20);
- relloc
realloc 函数可以身兼 malloc 和 free 两个函数的功能。
当 realloc(ptr,size) 的 size 不等于 ptr 的 size 时
- 如果申请 size > 原来 size
- 如果 chunk 与 top chunk 相邻,直接扩展这个 chunk 到新 size 大小
- 如果 chunk 与 top chunk 不相邻,相当于 free(ptr),malloc(new_size)
- 如果申请 size < 原来 size
- 如果相差不足以容得下一个最小 chunk(64 位下 32 个字节,32 位下 16 个字节),则保持不变
- 如果相差可以容得下一个最小 chunk,则切割原 chunk 为两部分,free 掉后一部分
- 如果申请 size > 原来 size
当 realloc(ptr,size) 的 size 等于 0 时,相当于 free(ptr)
当 realloc(ptr,size) 的 size 等于 ptr 的 size,不进行任何操作
堆填充长度
填充长度 = 要覆盖的地址 - 开始写入的地址
利用基本示例,来尝试一下,以下示例均为32位程序
- Malloc(0)
32位下最小的chunk大小为16个字节,而64位下最小的chunk大小为32个字节。
而chunk的大小包含了prev_size
4个字节和 size
4个字节,因此此时分配的空间大小为8个字节。
那么此时可利用的空间就是8个字节了吗?
并不是。chunk的prev_size
只有前一个chunk处于释放状态时才起作用,否则时可以用来给前一个chunk作为存储空间的。因此当malloc的参数是0时,实际的利用空间有12个字节。
pwndbg> x/20x 0x804d190
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000011
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00021e59
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000000
- malloc(24)
chunk在分配空间的时候是以最小的chunk大小(16字节)增长的,24 = 16 + 8 因此,正好分配了24个字节的空间。但此时的利用空间还要包含前一个chunk的prev_size
,因此实际利用空间为28个
pwndbg> x/20x 0x804d190
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000021
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000411
0x804d1c0: 0x20746547 0x75706e69 0x000a3a74 0x00000000
- Malloc(28)
此时的内存分配和上一的分析是一样的,由于可利用空间的大小满足用户的申请空间,因此不需要额外增加内存空间。
pwndbg> x/20x 0x804d190
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000021
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000411
0x804d1c0: 0x20746547 0x75706e69 0x000a3a74 0x00000000
- Malloc(29)
此时可利用空间增了一个最小chunk的大小
pwndbg> x/20x 0x804d190
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000031
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1c0: 0x00000000 0x00000000 0x00000000 0x00021e39
0x804d1d0: 0x00000000 0x00000000 0x00000000 0x00000000
堆攻击总结
接下来一段时间将按照heap-exploitation book介绍的顺序来学习堆溢出攻击。
攻击方式 | 目标 | 技巧 |
---|---|---|
First Fit | This is not an attack, it just demonstrates the nature of glibc’s allocator | |
Double Free |
Making malloc return an already allocated fastchunk
|
Disrupt the fastbin by freeing a chunk twice |
Forging chunks |
Making malloc return a nearly arbitrary pointer
|
Disrupting fastbin link structure |
Unlink Exploit | Getting (nearly)arbitrary write access |
Freeing a corrupted chunk and exploiting unlink
|
Shrinking Free Chunks |
Making malloc return a chunk overlapping with an already allocated chunk
|
Corrupting a free chunk by decreasing its size |
House of Spirit |
Making malloc return a nearly arbitrary pointer
|
Forcing freeing of a crafted fake chunk |
House of Lore |
Making malloc return a nearly arbitrary pointer
|
Disrupting smallbin link structure |
House of Force |
Making malloc return a nearly arbitrary pointer
|
Overflowing into top chunk’s header |
House of Einherjar |
Making malloc return a nearly arbitrary pointer
|
Overflowing a single byte into the next chunk |
【pwn学习】堆溢出(一)相关推荐
- 《0Day安全》之堆溢出
最近重读<0Day安全>,由于栈溢出比较简单,所以直接从堆溢出开始读起. 在学习堆溢出之前,需要读者对堆的结构有一定的了解.先写一个小程序,分配一个新的堆来供我们研究它的结构,代码如下 # ...
- pwn学习总结(五) —— 堆溢出经典题型整理
pwn学习总结(五) -- 堆溢出经典题型整理 fastbin + 栈溢出 fastbin + 函数构造 fastbin + 堆执行 fastbin + malloc_hook fastbin + 栈 ...
- 【pwn学习】堆溢出(三)- Unlink和UAF
前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...
- linux 堆溢出 pwn 指南,新手科普 | CTF PWN堆溢出总结
学习汇总 序言 自从加入RTIS交流群, 在7o8v师傅,gd大佬的帮助下,PWN学习之路进入加速度.下面是八周学习的总结,基本上是按照how2heap路线走的.由于八周内容全写,篇幅太长,这里只讲述 ...
- 堆溢出-House of orange 学习笔记(看雪论坛)
https://www.jianshu.com/p/4b0a73f321f9 前几天把House of orange重新学习了一下,比照着glibc malloc的源码好好分析了一下,希望做到真正做到 ...
- pwn学习总结(四)—— 堆基础知识(持续更新)
pwn学习总结(四)-- 堆基础知识(持续更新) 前言 chunk 使用中(分配后) 空闲中(释放后) 堆块大小 空间复用 bins fastbin unsorted bin small bin 前言 ...
- 漏洞学习笔记——堆溢出原理
最近在学习堆的溢出原理,但是查了网上和书上的一些讲解,总是感觉缺少一些关键点.所以理解起来总是有点晕,经过努力的调试分析后,总结了下面的更为详细的堆溢出原理.如果不准确的地方,希望大佬可以提醒一哈~ ...
- pwn学习总结(二) —— 基础知识(持续更新)
pwn学习总结(二) -- 基础知识(持续更新) Canary PLT表&GOT表 格式化字符串漏洞 GCC编译参数 ASLR 危险函数 输入流 syscall条件 shellcode 其它 ...
- c++算术溢出_二进制安全之堆溢出(系列)——CTF环境配置
[重要通知]知了堂禁卫实验室全新上线!! 这里有安全体系的学习资源. 最前沿的原创文章.最新的漏洞挖掘原创!! 本期是"二进制安全之堆溢出"系列第一期,主要介绍CTF环境配置.安装 ...
最新文章
- Jieba分词原理与解析
- 华为harmonyos 2.0,华为王成录博士:HarmonyOS 2.0给消费者不一样的体验
- UI事件与内容,舞台与演员
- python 复制文件夹内容 并结构一致_Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法...
- PHP笔记-JavaScript中使用Smarty变量
- 线性表的顺序表示以及实现
- 开发更安全的asp.net应用程序一
- docker阿里云镜像加速器
- 1.1.1.1校园网_突破校园网限制,开启寝室Wifi
- latex,希腊字母,英文花体字
- 5G WIFI DFS介绍
- 差分 线宽 线距_需要做阻抗的信号线时应该怎样计算线宽、线距规则?
- Unit iptables.service could not be found
- 计算机系统加载失败怎么回事,驱动加载失败怎么办,驱动加载失败的原因和解决方法...
- 解决笔记本键盘禁用失败问题
- 微信发红包如何设计测试用例
- GANs奇思妙想TOP10榜单
- Android Miracast 花屏问题分析
- 缓存Cache-Control
- 利用高德地图通过给定坐标点画带箭头方向的路径