House of Lore Attack

首先我们看一下glibc 2.30中的源代码

if (in_smallbin_range (nb))
{
  idx = smallbin_index (nb);
  bin = bin_at (av, idx);

  if ((victim = last (bin)) != bin)
    {
      bck = victim->bk;
  if (__glibc_unlikely (bck->fd != victim))
    malloc_printerr ("malloc(): smallbin double linked list corrupted");
      set_inuse_bit_at_offset (victim, nb);
      bin->bk = bck;
      bck->fd = bin;

      if (av != &main_arena)
    set_non_main_arena (victim);
      check_malloced_chunk (av, victim, nb);
#if USE_TCACHE
  /* While we're here, if we see other chunks of the same size,
     stash them in the tcache.  */
  size_t tc_idx = csize2tidx (nb);
  if (tcache && tc_idx < mp_.tcache_bins)
    {
      mchunkptr tc_victim;

      /* While bin not empty and tcache not full, copy chunks over.  */
      while (tcache->counts[tc_idx] < mp_.tcache_count
         && (tc_victim = last (bin)) != bin)
    {
      if (tc_victim != 0)
        {
          bck = tc_victim->bk;
          set_inuse_bit_at_offset (tc_victim, nb);
          if (av != &main_arena)
        set_non_main_arena (tc_victim);
          bin->bk = bck;
          bck->fd = bin;

          tcache_put (tc_victim, tc_idx);
            }
    }
    }
#endif
      void *p = chunk2mem (victim);
      alloc_perturb (p, bytes);
      return p;
    }
}

从源代码中我们可以看出,如果我们控制了一块small binbk指针,就可以向任意的位置写入一个main_arena附近的地址,在small bin中加入指定的堆块,进而在内存中分配一个指定的chunk。当前前提是我们需要绕过下面的检查

bck = victim->bk;
if (__glibc_unlikely (bck->fd != victim))

这其中bck就是我们伪造的bk指针,因此我们只要在指定的位置写入一个堆内存地址(victim的地址),就可以绕过该检查。

Tcache Stashing Unlink Attack

从上面的代码中我们可以看到,在small bin分配之后,如果small bin链表中仍然存在堆块,并且对应的tcache list不为空的话,就会将small bin链表中所有的堆块放入到tcache中。当然要发生这种分配的方式必须可以越过tcache分配堆块,因为malloctcache中存在堆块的时候会首先在tcache中返回堆块,calloc则不经过tcache

注意此时加入tcache的部分没有进行安全检查。那么之后攻击方式与House of Lore Attack相同。但是这里需要注意的是tcache将所有的small bin加入tcache的特性

GeekPwn 2020 云靶场挑战赛热身赛 playthenew

该题目利用Tcache Stashing Unlink向指定位置写入了main_arena附近的地址,绕过程序的检查,从而向特定地址写入rop链,利用程序原有的函数调用执行rop

高校战疫网络安全分享赛 2020 twochunk

改题目利用Tcache Stashing Unlink,堆溢出,分配mmap_address处的内存,进行函数布局,利用程序原有的函数调用执行system

BUU 新春红包3

程序提供了四种功能add,delete,change,show,在删除的时候存在UAF漏洞。程序只提供特定大小的堆块分配0x10,0xf0,0x400,0x300。当用户输入是666的时候会提供一个栈溢出的函数,该函数的调用需要满足条件

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c212bdda-adc1-47cd-b118-6524ed2a90dd/Untitled.png

我们可以通过Tcache Stashing Unlink来讲mmap_address+0x800更改为main_arena附近的地址就可以绕过该检查。