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. LOJ3053 十二省联考2019 希望 容斥、树形DP、长链剖分

    传送门 官方题解其实讲的挺清楚了,就是锅有点多-- 一些有启发性的部分分 L=N 一个经典(反正我是不会)的容斥:最后的答案=对于每个点能够以它作为集合点的方案数-对于每条边能够以其两个端点作为集合点 ...

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

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

  3. Redisson 分布式锁

    Redisson_百度百科https://baike.baidu.com/item/Redisson/20856570 redission 分布式锁 - 穆穆兔兔 - 博客园https://www.c ...

  4. Spring Boot的web开发

    web开发的自动配置类:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration 自动配置的ViewResolver 视图的 ...

  5. 映美FP-530K+打印发票卡纸

    最近打发票卡纸了几次,只能作废掉,硬件不太好排查,卡纸都是在发票的中间位置,我在卡纸的时候观察了好几次,打开打印机盖子,直接裸露这样看里面的打印状况,目前发现了两种卡纸位置. 如图,一种是后面的黑色塑 ...

  6. fullpage.js参数参考

    fullpage函数里面的参数: //Navigationmenu: false,//绑定菜单,设定的相关属性与anchors的值对应后,菜单可以控制滚动,默认为false.anchors:['fir ...

  7. 洛谷P2634 聪明可可

    还是点分治 树上问题真有趣ovo,这道题统计模3为0的距离,可以把重心的子树分开统计,也可以一次性统计,然后容斥原理减掉重复的.. 其他的过程就是点分治的板子啦. #include <bits/ ...

  8. 使用@property

    @property装饰器就是负责把一个方法变成属性调用的,既能检查参数,又可以用类似属性这样简单的方式来访问类的变量 class Student(object): @property def scor ...

  9. FastDFS分布式文件系统客户端安装

    软件安装前提:服务器已配置好LNMP环境安装libfastcommon见FastDFS服务器安装文档(http://www.cnblogs.com/Mrhuangrui/p/8316481.html) ...

  10. jmeter5.1测试dubbo接口

    dubbo接口功能介绍 客户端输入uncleyong(当然,也可以是其他字符串),服务端返回hello uncleyong 开发dubbo服务jmeter客户端 idea中创建模块dubbo_jmet ...