拖了好久,但是在期间做了几道pwn题目,发现堆原来也没有想象中的难。

  fastbin_dup_into_stack

  这个说白了,就是利用double free可以进行任意地址的写,说是任意地址不准确,这个任意地址需要先进行布局!这个例子演示的是将一个堆分配到栈上。

  先上一个简化版的源码:

 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 int main() {
5 unsigned long long stack_var = 0x21;
6 fprintf(stderr, "Allocating 3 buffers.\n");
7 char *a = malloc(9);
8 char *b = malloc(9);
9 char *c = malloc(9);
10 strcpy(a, "AAAAAAAA");
11 strcpy(b, "BBBBBBBB");
12 strcpy(c, "CCCCCCCC");
13 fprintf(stderr, "1st malloc(9) %p points to %s\n", a, a);
14 fprintf(stderr, "2nd malloc(9) %p points to %s\n", b, b);
15 fprintf(stderr, "3rd malloc(9) %p points to %s\n", c, c);
16 fprintf(stderr, "Freeing the first one %p.\n", a);
17 free(a);
18 fprintf(stderr, "Then freeing another one %p.\n", b);
19 free(b);
20 fprintf(stderr, "Freeing the first one %p again.\n", a);
21 free(a);
22 fprintf(stderr, "Allocating 4 buffers.\n");
23 unsigned long long *d = malloc(9);
24 *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
25 fprintf(stderr, "4nd malloc(9) %p points to %p\n", d, &d);
26 char *e = malloc(9);
27 strcpy(e, "EEEEEEEE");
28 fprintf(stderr, "5nd malloc(9) %p points to %s\n", e, e);
29 char *f = malloc(9);
30 strcpy(f, "FFFFFFFF");
31 fprintf(stderr, "6rd malloc(9) %p points to %s\n", f, f);
32 char *g = malloc(9);
33 strcpy(g, "GGGGGGGG");
34 fprintf(stderr, "7th malloc(9) %p points to %s\n", g, g);
35 }

  用pwndbg一步步调试看看:

  在22行的地方下个断点。

  然后进行先进行

  d=malloc(9)

  *d=栈地址

  这里的这个栈地址,不是随便的地址,而是

减去0x8的位置。

  这里的目的就是要让这里的0x7fffffffda38作为chunk的prev_size字段,然后让stack_var这个八个字节作为chunk的size字段,因为在从fastbins中取空间的时候,在2.23的libc中是会检查size字段,需要size字段合适,如果size字段不对,就不会分配成功。

  接下来就是再分配两个chunk,这个时候最后一个chunk就被分配到栈上面了。

  虽然图片中的代码是向堆写内容,但是其实我们写入的地址是栈,这样就实现了有条件的任意地址写!

  

fastbin_dup_consolidate

  在前面我们说到,在libc2.23版本下,double free是有检测,会检测表头是不是上次被free的chunk头,这个检测好像在2.27版本就没了。。。还没有学习到那里,就先不谈了,这里说一下这个例子能干嘛。这个例子也是可以绕过doublefree的检测,但是不是我们前面讲的

  free(a)

  free(b)

  free(a)

  先看源码:

 1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5 int main()
6 {
7 void *p1 = malloc(0x10);
8 void *p2 = malloc(0x10);
9 strcpy(p1, "AAAAAAAA");
10 strcpy(p2, "BBBBBBBB");
11 fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1,p2);
12 fprintf(stderr, "Now free p1!\n");
13 free(p1);
14 void *p3 = malloc(0x400);
15 fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
16 fprintf(stderr, "In malloc_consolidate(), p1 is moved to theunsorted bin.\n");
17 free(p1);
18 fprintf(stderr, "Trigger the double free vulnerability!\n");
19 fprintf(stderr, "We can pass the check in malloc() since p1is not fast top.\n");
20 void *p4 = malloc(0x10);
21 strcpy(p4, "CCCCCCC");
22 void *p5 = malloc(0x10);
23 strcpy(p5, "DDDDDDDD");
24 fprintf(stderr, "Now p1 is in unsorted bin and fast bin. Sowe'will get it twice: %p %p\n", p4, p5);
25 }

  

  我们先在14行下一个断点看看:

    

  此时的申请的chunk0已经被放到fastbins里面了这个时候时候我们

  malloc(0x400)

  这里我们发现,原来在fastbins的chunk0跑到了samllbins

  malloc(0x400),就是在分配large chunk

  

  large bins

  chunk 的指针数组, 每个元素是一条双向循环链表的头部, 但同一条链表中块的大小不一定相同, 按照从大到小的顺序排列,每个bin保存一定 大小范围的块。主要保存大小 1024 字节以上的块。

  由于此时 p1 已经不在 fastbins 的顶部,可以再次释放 p1

  这个时候我们发现chunk0也就是p1,又在fastbins里面,又在smallbins里面,当我们再次创建chunk的时候,第一次会从fastbins里面提取出chunk,第二次会从smallbins里面拿出chunk,所以这里的p4 p5都指向chunk0

  虽然写到这里就完了,但是我还是有一点点不太明白。

  说一下我现在的理解吧,就是我要申请一个large chunk,我首先会看看unsorted bin中有没有合适的chunk,我就会将fast bins中的chunk合并到unsorted bin中,但是由于我们申请的这个chunk太大了,即使把faatbins的chunk合并过来也不满足,所以我这里就按照大小,又把合并完的这个chunk放回到smallbins或者largebins。

  嗯嗯,目前就这个理解。刚刚测试了一下,确实会合并fastbins的chunk,合并完之后判断这个chunk是属于smalllibs还是largebins,再按规则放!

  这篇博客就先到这里啦!

how2heap学习(二)的更多相关文章

  1. emberjs学习二(ember-data和localstorage_adapter)

    emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...

  2. ReactJS入门学习二

    ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...

  3. TweenMax动画库学习(二)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  4. Hbase深入学习(二) 安装hbase

    Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...

  5. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  6. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  7. Quartz学习--二 Hello Quartz! 和源码分析

    Quartz学习--二  Hello Quartz! 和源码分析 三.  Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...

  8. SpringCloud学习(二):微服务入门实战项目搭建

    一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...

  9. DjangoRestFramework学习二之序列化组件、视图组件 serializer modelserializer

      DjangoRestFramework学习二之序列化组件.视图组件   本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组 ...

随机推荐

  1. 【BugFix】K8S节点NOT READY状态,错误信息:network plugin is not ready: cni config uninitialized

    错误现象 runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: netw ...

  2. [spojSUBLEX]Lexicographical Substring Search

    建立后缀自动机,对于同一个节点,出现次数是相同的(right的大小),同时满足单调性(长度越长出现次数越少),所以只需要考虑最长的串即可. PS:似乎也并不需要求依次后缀的max,不知道为什么-- 1 ...

  3. 【JavaSE】字符编码和存储编码

    字符编码和存储编码 2019-07-15  22:34:51  by冲冲 1. 英文字母和中文汉字在不同字符集编码下的字节数不同. 英文字母 字节数 : 1; 编码:GB2312 字节数 : 1; 编 ...

  4. vue局部过滤器和全局过滤器

    全局过滤器在main.js中写 //注册全局过滤器 Vue.filter('wholeMoneyFormat',(value)=>{   return '¥'+Number(value).toF ...

  5. Codeforces 1461F - Mathematical Expression(分类讨论+找性质+dp)

    现场 1 小时 44 分钟过掉此题,祭之 大力分类讨论. 如果 \(|s|=1\),那么显然所有位置都只能填上这个字符,因为你只能这么填. scanf("%d",&n);m ...

  6. 洛谷 P5527 - [Ynoi2012] NOIP2016 人生巅峰(抽屉原理+bitset 优化背包)

    洛谷题面传送门 一道挺有意思的题,想到了某一步就很简单,想不到就很毒瘤( 首先看到这样的设问我们显然可以想到背包,具体来说题目等价于对于每个满足 \(i\in[l,r]\) 的 \(a_i\) 赋上一 ...

  7. Codeforces 193D - Two Segments(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 感觉这个 *2900 并不难啊,为什么我没想出来呢 awa 顺便膜拜 ycx 一眼秒掉此题 %%% 首先碰到这类题有两种思路,一是枚举两个 ...

  8. DirectX12 3D 游戏开发与实战第六章内容

    利用Direct3D绘制几何体 学习目标 探索用于定义.存储和绘制几何体数据的Direct接口和方法 学习编写简单的顶点着色器和像素着色器 了解如何用渲染流水线状态对象来配置渲染流水线 理解怎样创建常 ...

  9. 【k8s】使用Terraform一键部署EKS集群

    本文适用范文 使用AWS海外账号 对aws.terraform.k8s有一定的了解 新建一个独立的VPC Terraform简介 terraform是一个云端的资源编排工具,官方对自己的定位:Terr ...

  10. PAML 选择压力的计算

    简介 PAML(Phylogenetic Analysis by Maximum Likelihood)是伦敦大学的杨子恒(Yang Ziheng)教 授开发的一套基于最大似然估计来对蛋白质和核酸序列 ...