堆技巧 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