Unlink Attack

什么是Unlik Attack

  • 比较古老的一种攻击技术
  • 之前的一些CTF比赛中出过这类题目
    • DEFCON CTF 2014 - Baby’s First: 1 – heap
      • Linux x86二进制程序,之前的Doug Lea’s malloc是静态链接,可以进行简单的Unlik Attack
    • PlaidCTF 2014 - Pwnables200 – ezhp
      • Linux x86二进制程序,使用一个链表来自行管理分配的内存区域,可以进行Unlik Attack
    • DEFCON CTF 2013 - Exploitation5 – yolo
      • FreeBSD x64二进制程序,自己实现的内存管理机制,可以进行Unlik Attack
  • 堆溢出时,如果下面是free状态的chunk,fd/bk可以被覆盖
    • 这种情况就存在Unlink Attack的可能性

fd/bk 是什么

  • free区域,为了再次利用时的高速,使用了双向链表结构
    • 这是为了快速寻找分散在各个地方的free区块
  • 为此产生了fd/bk指针
    • 各个chunk也存在prev_size和size变量,在图中省略了

正常的free()

  • 假设紧接着P之前的P2是使用中状态
    • 从P2开始,加上自身的size可以知道P的地址
  • 如果在此状态下执行free(P2) ,那么将会产生两个连续的free区域
  • 这将产生一个大的free块,需要从列表中暂时删除P
    • 这是free()内部进行的unlink
    • P2被free时,下面的P也会被unlink,这一点很重要

合并成一个大的free块(然后再次插入相应的列表)

exploit的流程

  • 在前面的内存进行堆溢出,覆盖fd
    • 使其指向X
  • 进行free(P2)的时候,相连接的P被unlink
  • 此时,BK和X在链表中相连

忆往昔

  • DEFCON CTF 2014预选赛出过的一道题,就是利用这样的技巧
    • Baby’s First: 1 - heap
    • 使用旧时代的libc,并没有太严格的限制
  • 但是,时代变了

看今朝

  • 2004年之后libc中的free(),无法进行这样的Unlink Attack
    • P->fd->bk == P
    • P->bk->fd == P
  • 加入了这样的判断,如果不满足将产生错误

P->fd->bk = X->bk != P ,unlink之前就会产生错误