[原创]Large bin attack--LCTF2017-2ez4u--writeup
Large bin attack--LCTF2017-2ez4u--writeup
技巧性很强的一道题,当时自己写的思路和官方的不一样,后面看着官方的wp看了半天才把思路看懂。
large bin 分配的过程
这道题很关键的一个点在于伪造large bin chunk,并将该chunk分配出来,从而实现空间复用,所以先解释下large bin分配的过程,源代码如下:
/*
If a large request, scan through the chunks of current bin in
sorted order to find smallest that fits. Use the skip list for this.
*/
if (!in_smallbin_range (nb))
{
bin = bin_at (av, idx);
/* skip scan if empty or largest chunk is too small */
if ((victim = first (bin)) != bin && //获取链表的第一个chunk
(unsigned long) (victim->size) >= (unsigned long) (nb))
{
victim = victim->bk_nextsize; //反向遍历,chunk size链表,直到找到第一个大于等于所需chunk大小的chunk退出循环
while (((unsigned long) (size = chunksize (victim)) <
(unsigned long) (nb)))
victim = victim->bk_nextsize;
/* Avoid removing the first entry for a size so that the skip
list does not have to be rerouted. */
if (victim != last (bin) && victim->size == victim->fd->size)
victim = victim->fd;
remainder_size = size - nb;
unlink (av, victim, bck, fwd); //large bin的unlink操作
/* Exhaust */
if (remainder_size < MINSIZE)
{
set_inuse_bit_at_offset (victim, size);
if (av != &main_arena)
victim->size |= NON_MAIN_ARENA;
}
/* Split */
else
{
remainder = chunk_at_offset (victim, nb);
/* We cannot assume the unsorted list is empty and therefore
have to perform a complete insert here. */
bck = unsorted_chunks (av);
fwd = bck->fd;
if (__glibc_unlikely (fwd->bk != bck))
{
errstr = "malloc(): corrupted unsorted chunks";
goto errout;
}
remainder->bk = bck;
remainder->fd = fwd;
bck->fd = remainder;
fwd->bk = remainder;
if (!in_smallbin_range (remainder_size))
{
remainder->fd_nextsize = NULL;
remainder->bk_nextsize = NULL;
}
set_head (victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head (remainder, remainder_size | PREV_INUSE);
set_foot (remainder, remainder_size);
}
check_malloced_chunk (av, victim, nb);
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
}
}
有关堆的管理与结构不多说,需要强调下的是,large bin数组里的不再是存储大小一样chunk,而是可以存储等差数列变化的chunk块。large bin chunk结构体中的fd_nextsize和bk_nextsize俩个字段是有意义的,large bins中空闲chunk是按照大小排序的,但同一个大小的chunk可能有多个,增加这俩个字段可以加快遍历空闲chunk,fd_nextsize指向下一个比当前chunk大小大的第一个空闲块,bk_nextsize指向前一个比当前chunk大小小的第一个空闲chunk。
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
复制成功
