堆技巧 housr_of_spirit 绕过检查源码分析

House Of Spirit

  House of Spirit 是 the Maleficarum 中的一种技术。该技术的核心在于在目标位置处伪造 fastbin chunk ,并将其释放,从而达到分配指定地址的 chunk 的目的。

House Of Spirit 的检测绕过

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

fake chunk 的 ISMMAP

#if HAVE_MMAP   
    if (chunk_is_mmapped(p))       /* release mmapped memory. */
    {     /* see if the dynamic brk/mmap threshold needs adjusting */
        if (!mp_.no_dyn_threshold
            && p->size > mp_.mmap_threshold         
            && p->size <= DEFAULT_MMAP_THRESHOLD_MAX)       
        {         
            mp_.mmap_threshold = chunksize (p);
            mp_.trim_threshold = 2 * mp_.mmap_threshold;       
        }     
        munmap_chunk(p);     
    return;   
    }
 #endi

  可以看到, MMAP 位需要置 0 ,否则 free 会,调用 munmap_chunk() 函数 unmap 本 chunk ,达不到进入 fastbin 的目的。

fake chunk 的 size

if (*fb != NULL
    && __builtin_expect (fastbin_index(chunksize(*fb)) != idx, 0))               
    {         
        errstr = "invalid fastbin entry (free)";         
        goto errout;       
    }

  fake chunk 的 size 大小 需要满足对应的 fastbin 的 index ,同时也得对齐。

fack chunk 的 next chunk

if (__builtin_expect (chunk_at_offset (p, size)->size <= 2 * SIZE_SZ, 0)
    || __builtin_expect (chunksize (chunk_at_offset (p, size))>= av->system_mem, 0))       
    { 
#ifdef ATOMIC_FASTBINS         
    /* We might not have a lock at this point and concurrent modifications
       of system_mem might have let to a false positive.  Redo the test
       after getting the lock.  */
    if (have_lock
        || ({ assert (locked == 0);
              mutex_lock(&av->mutex);
              locked = 1;
              chunk_at_offset (p, size)->size <= 2 * SIZE_SZ                     
              || chunksize (chunk_at_offset (p, size)) >= av->system_mem;               
            })) 
#endif           
            {             
                errstr = "free(): invalid next size (fast)";             
                goto errout;           
            } 
#ifdef ATOMIC_FASTBINS         
            if (! have_lock)           
                {             
                    (void)mutex_unlock(&av->mutex);             
                    locked = 0;           
                } 
#endif       
    } 

 &emsp;为了绕过 if 判断,我们需要让 next chunk 的大小不能小于 2 * size_sz ,同时也不能大于 av->system_mem 。

fake chunk 对应的 fastbin 链表头部

if (__builtin_expect (*fb == p, 0))       
    {         
        errstr = "double free or corruption (fasttop)";         
        goto errout;       
    } 

 &emsp;fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况。

fack chunk 的地址

  fake chunk 地址需要对齐, MALLOC_ALIGN_MASK

内容来源

ctf-wiki-fastbin

posted @ 2020-02-24 15:39  PwnKi  阅读(320)  评论(0编辑  收藏  举报