文章目录

  • 什么是堆溢出
    • 基本示例
    • 堆分配函数
    • 堆填充长度
  • 堆攻击总结

学习这部分之前,如果对堆的基础还不甚了解可以参考一下下面的学习笔记

  • Linux堆管理基础知识(一)
  • Linux堆管理基础知识(二)- 数据结构

什么是堆溢出

堆溢出是指程序向某堆块(chunk)中写入的字节数超过了堆块本身可使用的字节数,因而导致了数据溢出,并覆盖到物理地址相邻的高地址的下一个堆块。这里之所以是可使用而不是用户申请的字节数,是因为堆管理器会对用户所申请的字节数进行调整,这也导致可利用的字节数大于等于用户申请的字节数。

ptmalloc 分配出来的大小是对齐的。这个长度一般是字长的 2 倍,比如 32 位系统是 8 个字节,64 位系统是 16 个字节。但是对于不大于 2 倍字长的请求,malloc 会直接返回 2 倍字长的块也就是最小 chunk,比如 64 位系统执行malloc(0)会返回用户区域为 16 字节的块。

因此,要利用堆溢出要满足两个前提

  • 程序向堆上写数据;
  • 写入的数据大小没有被控制;

与栈溢出的不同在于,堆上没有返回地址等让攻击者直接控制执行流程的数据,因此一般我们无法通过堆溢出来控制EIP。所以攻击人用来利用的方式一般如下

  1. 覆盖与其物理相邻的下一个chunk的内容。

    • prev_size;
    • Size.
    • Chunk content
  2. 利用堆中的机制(如 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 掉后一部分
  • 当 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个字节和 size4个字节,因此此时分配的空间大小为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学习】堆溢出(一)相关推荐

  1. 《0Day安全》之堆溢出

    最近重读<0Day安全>,由于栈溢出比较简单,所以直接从堆溢出开始读起. 在学习堆溢出之前,需要读者对堆的结构有一定的了解.先写一个小程序,分配一个新的堆来供我们研究它的结构,代码如下 # ...

  2. pwn学习总结(五) —— 堆溢出经典题型整理

    pwn学习总结(五) -- 堆溢出经典题型整理 fastbin + 栈溢出 fastbin + 函数构造 fastbin + 堆执行 fastbin + malloc_hook fastbin + 栈 ...

  3. 【pwn学习】堆溢出(三)- Unlink和UAF

    前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...

  4. linux 堆溢出 pwn 指南,新手科普 | CTF PWN堆溢出总结

    学习汇总 序言 自从加入RTIS交流群, 在7o8v师傅,gd大佬的帮助下,PWN学习之路进入加速度.下面是八周学习的总结,基本上是按照how2heap路线走的.由于八周内容全写,篇幅太长,这里只讲述 ...

  5. 堆溢出-House of orange 学习笔记(看雪论坛)

    https://www.jianshu.com/p/4b0a73f321f9 前几天把House of orange重新学习了一下,比照着glibc malloc的源码好好分析了一下,希望做到真正做到 ...

  6. pwn学习总结(四)—— 堆基础知识(持续更新)

    pwn学习总结(四)-- 堆基础知识(持续更新) 前言 chunk 使用中(分配后) 空闲中(释放后) 堆块大小 空间复用 bins fastbin unsorted bin small bin 前言 ...

  7. 漏洞学习笔记——堆溢出原理

    最近在学习堆的溢出原理,但是查了网上和书上的一些讲解,总是感觉缺少一些关键点.所以理解起来总是有点晕,经过努力的调试分析后,总结了下面的更为详细的堆溢出原理.如果不准确的地方,希望大佬可以提醒一哈~ ...

  8. pwn学习总结(二) —— 基础知识(持续更新)

    pwn学习总结(二) -- 基础知识(持续更新) Canary PLT表&GOT表 格式化字符串漏洞 GCC编译参数 ASLR 危险函数 输入流 syscall条件 shellcode 其它 ...

  9. c++算术溢出_二进制安全之堆溢出(系列)——CTF环境配置

    [重要通知]知了堂禁卫实验室全新上线!! 这里有安全体系的学习资源. 最前沿的原创文章.最新的漏洞挖掘原创!! 本期是"二进制安全之堆溢出"系列第一期,主要介绍CTF环境配置.安装 ...

最新文章

  1. Jieba分词原理与解析
  2. 华为harmonyos 2.0,华为王成录博士:HarmonyOS 2.0给消费者不一样的体验
  3. UI事件与内容,舞台与演员
  4. python 复制文件夹内容 并结构一致_Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法...
  5. PHP笔记-JavaScript中使用Smarty变量
  6. 线性表的顺序表示以及实现
  7. 开发更安全的asp.net应用程序一
  8. docker阿里云镜像加速器
  9. 1.1.1.1校园网_突破校园网限制,开启寝室Wifi
  10. latex,希腊字母,英文花体字
  11. 5G WIFI DFS介绍
  12. 差分 线宽 线距_需要做阻抗的信号线时应该怎样计算线宽、线距规则?
  13. Unit iptables.service could not be found
  14. 计算机系统加载失败怎么回事,驱动加载失败怎么办,驱动加载失败的原因和解决方法...
  15. 解决笔记本键盘禁用失败问题
  16. 微信发红包如何设计测试用例
  17. GANs奇思妙想TOP10榜单
  18. Android Miracast 花屏问题分析
  19. 缓存Cache-Control
  20. 利用高德地图通过给定坐标点画带箭头方向的路径

热门文章

  1. Linux学习笔记43——开机流程、模块管理与 Loader
  2. hahahahaha
  3. 微信小程序在线客服接入
  4. Pythom基础入门
  5. 鸿蒙手机真的出来会买吗,如果鸿蒙真的大批采用,你还会买华为手机吗?迟疑的瞬间答案明了!...
  6. 根据曲线曲率计算该曲率(曲线图)的积分
  7. 【Linux篇<Day12>】——逻辑卷管理、VDO卷、RAID磁盘阵列、进程管理
  8. 【读书】《正面管教》
  9. VS2019配置SFML
  10. PMP第八章重要知识点