漏洞原理

/* consolidate backward */
if (!prev_inuse(p)) { // 检查了p位是否为0,然后后向合并
      prevsize = prev_size(p); 
      size += prevsize; // size重新计算
      p = chunk_at_offset(p, -((long) prevsize)); // 更新指针
      unlink(av, p, bck, fwd); // 有unlink,需要绕过检测
}
// 由代码可知,若是我们可以控制 prev_size和p段,就可以将chunk指向任意地方

图片来自ctf.wiki

image.png

适用范围

相应技巧

从原理中的 free的源代码中,可以发现我们还要绕过unlink的检查,其中高低版本的unlink条件不一样

FD = P->fd , BK = P->bk ==> FD->bk=P, BK->fd=P
// 多了一步
检测 chunksize(P)
chunksize (p) == prev_size (next_chunk (p))

总结

  1. 要有溢出漏洞可以修改 prev_size和 prev_inuse位
  2. 能够计算出 chunk和p的地址之间的差