off_by_one(null)/unlink

Off-By-One

这个漏洞是一种特殊的溢出漏洞,指的是向堆中写入数据时,写入的字节数超过了这个堆块所申请的字节数仅仅一个字节,造成原因就是边界。

边界验证不严通常包括:

  • 使用循环语句向堆块中写入数据时,循环的次数设置错误(这在 C 语言初学者中很常见)导致多写入了一个字节。
  • 字符串操作不合适

越界导致覆盖到了下一个 chunk 的 size 位,

off-by-one 四种利用思路:

溢出字节为可控制任意字节:通过修改大小造成块结构之间出现重叠,从而泄露其他块数据,或是覆盖其他块数据。

1、扩展 free chunk

  • 从 chunk0 通过 off-by-one 修改 chunk1(free) 的 size ,使其包含住 chunk2 ,再申请回 chunk1 造成 chunk2 的重叠。

2、扩展 malloc chunk

  • 从 chunk0 通过 off-by-one 溢出修改 chunk1(已分配) 的 size,使其覆盖 chunk2 ,再 free 掉 chunk1,造成 chunk2 的重叠。

off-by-null

这个算是 off-by-one 的特殊情况,只是溢出的字节被限制为 null

  • 溢出字节为 NULL 字节:在 size 为 0x100 的时候,溢出 NULL 字节可以使得 prev_in_use 位被清,这样前块会被认为是 free 块。
    (1) 这时可以选择使用 unlink 方法进行处理。
    (2) 这时 prev_size 域就会启用,就可以伪造 prev_size ,从而造成块之间发生重叠。此方法的关键在于 unlink 的时候没有检查按照 prev_size 找到的块的大小与prev_size 是否一致。

3、收缩 free chunk

  • 先把 chunk1 给 free 掉通过chunk0 利用 off-by-null 将 free chunk1 改小,但 chunk2 的 prev_size 不会变。此时 chunk1 的 size 和 chunk2 的 prev_size 之间有一段差距了,再申请到这个差距域内的 chunk3 ,再 free 掉 chunk2 ,会造成 chunk2 与 chunk1 合并。然而这里面还有 chunk3 ,再次申请足够大小的 chunk4(size需要包裹chunk3),造成 chunk3 的重叠

4、house of einherjar

  • 通过 chunk0 利用 off-by-null 修改 chunk1 的 prev_size 为 chunk1_size,chunk1 的 prev_inuse 位为0 伪造 chunk0 为free 状态,此时 free 掉 chunk1 ,造成 chunk1 与 chunk0 合并,再次申请一定 size 的 chunk,实现 chunk0 的重叠。

unlink

unlink 用来将一个双向链表(只存储空闲的 chunk)中的一个元素取出来,可能在以下地方使用

malloc
从恰好大小合适的 large bin 中获取 chunk。
这里需要注意的是 fastbin 与 small bin 就没有使用 unlink,这就是为什么漏洞会经常出现在它们这里的原因。
依次遍历处理 unsorted bin 时也没有使用 unlink 的。
从比请求的 chunk 所在的 bin 大的 bin 中取 chunk。

Free
后向合并,合并物理相邻低地址空闲 chunk。
前向合并,合并物理相邻高地址空闲 chunk(除了 top chunk)。

malloc_consolidate
后向合并,合并物理相邻低地址空闲 chunk。
前向合并,合并物理相邻高地址空闲 chunk(除了 top chunk)。

realloc
前向扩展,合并物理相邻高地址空闲 chunk(除了top chunk)。

关于unlink的漏洞利用效果最终是 chunk 指针指向自己前方三个内存单元处

《off_by_one(null)/unlink》有1条评论

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据