github源代码地址

这里只分析glibc2.25堆分配的特性,为了方便调试编译时使用

gcc -g -no-pie <input_file_name> -o <output_file_name>

0.fastbin_dup_consolidate

  glibc在分配一个large chunk时会先检查是否存在fastbins,如果存在则合并fastbins到unsortedbins,并根据unsortedbins大小将其划入small bins或large bins。所以第一次free后p1会划入small bins,第二次可以free的原因是double free只检查fastbins的头节点和所释放的堆是否一致。malloc两次依次从fastbins和smallbins取出p1

1.fastbin_dup_into_stack

 源代码中11行要输出的值和48行的指针赋值不一致,都改成+或-就行了

  double free的一种利用,这种攻击的本质是我们可以控制一个存在于fast bin的堆的内容。free(a),free(b),free(a).然后malloc两次,这时fastbins中只有a,但此时a的chunk内容我们可控,所以此时伪造a的fd,在栈中伪造size,此时fastbin内容就变为a->a.fd,此时我们malloc两次,第二次就会得到a.fd的地址,造成任意地址写。

PS:关于Fastbin的LIFO。malloc fastbin大小的堆时取fastbin头结点直接指向的堆,向fastbin链表添加堆时也是添加到头结点的位置。如果是取堆和放堆都在链表结束位置,则取堆和放堆都需要遍历一遍fastbin,O(n)复杂度;而直接在fastbin头部取堆和放堆只需要修改头结点指针就行,O(1)复杂度

2.house_of_einherjar

  off by one的一种利用。假设我们有两个分配的堆p0和p1,其中p0位于物理低地址,此时p0和p1共享p1的prev_size域;假设此时存在一个off by one,则我们可以覆盖p1 size的pre_inuse为0(空闲)。由于glibc为了减少碎片化会进行后向合并,所以会得到下一个空闲堆为chunk_at_offset(p1,(long)prev_size),由于p1的prev_size域我们可控,随意修改prev_size为p1和ptr的偏移offset就可以得到ptr地址处的堆。修改后得到下一个空闲堆的效果为chunk_at_offset(p1,(long)offset),offset=p1-ptr

3.house_of_force

  top_chunk域可以溢出的一种利用。具体操作是覆盖top_chunk的size域为一个大整数(-1),以保证我们无论申请多大的内存都不需要调用mmap。计算malloc返回需要任意地址写的地址和top_chunk的偏移offset,这里得到的offset一定是一个负数(相当于一个整型溢出),然后此时我们malloc(offset),由于offset大小的chunk属于largebins,此时unsortedbins和largebins都为空,所以从topchunk得到这个chunk,所以new_ptr会得到top_chunk的地址。

offset的计算过程:

/*
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = dest - 2sizeof(long) - old_top - 2sizeof(long)
* req = dest - old_top - 4*sizeof(long)
*/

  此时我们再次malloc一个任意大小的堆,第二次malloc时top_chunk如下。所以此时malloc会得到dest的原因是与av->top的更新有关,以下有计算过程


pwndbg> print ctr_chunk


$2 = (void *) 0x602080 <bss_var>


pwndbg> print ptr_top


$3 = (intptr_t *) 0x603110


pwndbg> x/20xg 0x603110


0x603110:    0x0000000000000000      0xffffffffffffef61


0x603120:    0x0000000000000000      0x0000000000000000


0x603130:    0x0000000000000000      0x0000000000000000


0x603140:    0x0000000000000000      0x0000000000000000


0x603150:    0x0000000000000000      0x0000000000000000


0x603160:    0x0000000000000000      0x0000000000000000


0x603170:    0x0000000000000000      0x0000000000000000


0x603180:    0x0000000000000000      0x0000000000000000


0x603190:    0x0000000000000000      0x0000000000000000


0x6031a0:    0x0000000000000000      0x0000000000000000



av->top=chunk_at_offset(victim,nb)


0x603110+0xffffffffffffef50+4*sizeof(long)=0x602080

 

一个细节的地方:malloc(256)而malloc_usable_size()=264的原因是当前chunk数据域+next_chunk'pre_size。

这种利用方式能成功的原因是unsortedbins和largebins为空时申请largechunk会从top_chunk分配,利用一个leak得到dest和top_chunk的偏移就可以在下一次malloc时实现dest的写。

4.house_of_lore

  需要控制victim(smallbin最后一个chunk)的bk和stack_buffer的fd(stack中伪造堆)。具体操作是申请一个>fastbin大小的堆victim(例,64bit100;另,victim堆头起始记为victim_header),stack_buffer的fd覆盖为victim_header(绕过smallbin的双向链表检测)。

smallbin的双向链表检测

// 获取 small bin 中倒数第二个 chunk 。
bck = victim->bk;
// 检查 bck->fd 是不是 victim,防止伪造
if (__glibc_unlikely(bck->fd != victim)) {
errstr = "malloc(): smallbin double linked list corrupted";
goto errout;
}
// 设置 victim 对应的 inuse 位
set_inuse_bit_at_offset(victim, nb);
// 修改 small bin 链表,将 small bin 的最后一个 chunk 取出来
bin->bk = bck;
bck->fd = bin;

  此时我们malloc()一个chunk为了防止free(victim)时victim和top_chunk合并(victim释放后放入unsortedbin的条件是size>max(fastbin)&&victim不与top_chunk紧邻)。此时free(victim) victim链入unsortedbin,然后我们malloc()一个和victim大小不等且大小大于smallbin的堆,这样victim会被链入smallbin。我们修改victim->bk=stack_buffer,这样smallbin的变为stack_buffer->victim,此时malloc一个victim大小的堆就会得到victim,然后再次malloc就会得到stack_buffer。

这种利用的原理还是伪造堆利用smallbin分配FIFO,只不过如何绕过victim和top_chunk合并,如何让victim链入smallbin,都是比较细节的问题,还是需要对glibc堆分配有很深的理解

5.house_of_orange

 无法使用free的一种堆利用。利用当前top_chunk不满足申请堆大小,old top chunk会被链入unsortedbin(glibc在尝试得到申请大小堆的时候会依次检测fastbin、smallbins、unsortedbin、largebins,从这些bin得不到申请大小的堆会从topchunk获得,但这里topchunk也不满足,所以执行topchunk拓展;因为我们需要以brk方式扩展,所以接下来就是绕过brk扩展的check)

        ) Top chunk + size has to be page aligned
) Top chunk's prev_inuse bit has to be set.

即伪造的size页对齐,size的PRE_INUSE位置1。如此得到链入unsortedbin的old top chunk

  然后修改old top chunk的bk指针为io_list_all,利用一次任意地址写修改io_list_all为system,修改io_list_all前八字节为"/bin/sh"得到shell。

这里是如何触发一次任意地址写没看懂,有时间补,QAQ

6.house_of_spirit

  这个针对fastbin的攻击是在栈上构造fake_chunk,伪造堆指针free(fake_chunk)实现fake_chunk地址写。难点在于构造fake_chunk过程需要绕过一些检测

1)因为堆大小是fastbin范围,所以pre_inuse位固定;但是ISMMAP要覆盖为1(MMAP分配的堆和SBRK处理方式不一样),例子中NON_MAIN_ARENA位是0

2)fake_chunk 16字节对齐,size在fastbin范围内

3)fake chunk的next chunk的大小范围:> 2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for the main arena),以绕过nextsize的完整性检查

  满足以上条件构造fake_chunk后free(fake_chunk)再malloc() fake_chunk'size-chunk_header大小的堆就可以实现fake_chunk地址处的写

7.overlapping_chunks

  malloc三个unsortedbin范围堆P1,P2,P3;假设有一个溢出可以导致覆盖P2的size为P2+P3大小,free(P2),malloc(P2+P3-8)使malloc返回P2,由于此时P2堆大小为P2+P3,所以此时P3内容可控。

8.overlapping_chunks_2

  跟上一个的区别是先修改溢出堆的size,使其包含下一chunk,记fake_chunk,然后free(fake_chunk),malloc()fake_chunk size域大小的堆实现堆的覆写。利用的过程中注意不要使free的堆和top_chunk合并

how2heap学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. Nginx(三)------nginx 反向代理

    Nginx 服务器的反向代理服务是其最常用的重要功能,由反向代理服务也可以衍生出很多与此相关的 Nginx 服务器重要功能,比如后面会介绍的负载均衡.本篇博客我们会先介绍 Nginx 的反向代理,当然 ...

  2. Winform让扫描枪听话,防止在有焦点的地方就扫码输入的尴尬

    关注点: 1.扫描枪在扫描到条码后会在有焦点的地方显示扫描到的条码并且可设置扫码后添加回车换行让我很尴尬 2.怎样拦截扫码输入,扫描到条码就自动会嘀一声.不要这么智能行不行.瞎BB 需求详解 公司生产 ...

  3. adb.exe 已停止工作 解决

    netstat -aon|findstr 5037tasklist /fi "PID eq 10388"TASKKILL /F /IM PPAdbServer.exe

  4. 全局css控制<td>标签属性

    td { text-align: center; /*设置水平居中*/ vertical-align: middle; /*设置垂直居中*/    height:50px;             / ...

  5. 简单介绍Excel单元格行列指示的实现原理(俗称聚光灯功能)

    原始出处:www.cnblogs.com/Charltsing/p/CellLight.html QQ:564955427 Excel单元格行列指示的实现原理(俗称聚光灯功能) 单元格行列指示功能在录 ...

  6. Django中间件2

    前戏 我们在前面的课程中已经学会了给视图函数加装饰器来判断是用户是否登录,把没有登录的用户请求跳转到登录页面.我们通过给几个特定视图函数加装饰器实现了这个需求.但是以后添加的视图函数可能也需要加上装饰 ...

  7. 第二章· Redis管理实战

    数据类型 管理实战 数据类型 String: 字符串类型 Hash: 哈希类型 List: 列表类型 Set: 集合类型 Sorted set: 顺序集合类型 管理实战 通用操作

  8. springboot的热部署

    SpringBoot 4.SpringBoot 整合 devtools 实现热部署   一.添加 devtools 依赖 <!-- Spring boot 热部署 : 此热部署会遇到 java. ...

  9. Nginx整合tomcat,实现反向代理和负载均衡

    1.Nginx与Tomcat整合,通过Nginx反向代理Tomcat. Nginx安装路径为:/usr/local//nginx 首先切换路径到:/usr/local//nginx/conf通过命令  ...

  10. Scrapy 框架,持久化文件相关

    持久化相关 相关文件 items.py 数据结构模板文件.定义数据属性. pipelines.py 管道文件.接收数据(items),进行持久化操作. 持久化流程 1.爬虫文件爬取到数据后,需要将数据 ...