Heap Overflow
Last updated
Last updated
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE) 学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
堆溢出就像一个 栈溢出 但发生在堆中。基本上,这意味着在堆中保留了一些空间来存储数据,而 存储的数据大于保留的空间。
在栈溢出中,我们知道一些寄存器,如指令指针或栈帧,将从栈中恢复,并且可能会滥用这一点。在堆溢出的情况下,默认情况下堆块中没有存储任何敏感信息,可以被溢出。然而,它可能包含敏感信息或指针,因此这种漏洞的 严重性 取决于 哪些数据可能被覆盖 以及攻击者如何利用这一点。
为了找到溢出偏移量,您可以使用与 栈溢出 相同的模式。
在栈溢出中,触发漏洞时栈中将存在的排列和数据是相当可靠的。这是因为栈是线性的,总是增加在碰撞内存中,在 程序运行的特定位置,栈内存通常存储类似类型的数据,并且它具有一些特定的结构,末尾有一些指向每个函数使用的栈部分的指针。
然而,在堆溢出的情况下,使用的内存不是线性的,而是 分配的块通常位于内存的不同位置(而不是一个接一个),因为 bins 和 zones 按大小分隔分配,并且因为 先前释放的内存在分配新块之前被使用。因此,很难知道将与易受堆溢出影响的对象发生碰撞的对象。因此,当发现堆溢出时,需要找到一种 可靠的方法使所需对象在内存中紧挨着可以溢出的对象。
用于此的一种技术是 Heap Grooming,例如在 这篇文章中。文章解释了当 iOS 内核中的一个区域没有足够的内存来存储内存块时,它通过一个内核页面扩展,并且该页面被分割成预期大小的块,这些块将按顺序使用(直到 iOS 版本 9.2,然后这些块以随机方式使用,以增加这些攻击的利用难度)。
因此,在发生堆溢出的前一篇文章中,为了强制溢出的对象与受害者对象发生碰撞,多个 kallocs
被多个线程强制执行,以确保所有空闲块都被填满,并且创建一个新页面。
为了强制用特定大小的对象填充,与 iOS mach 端口相关的离线分配是一个理想的候选者。通过精确设置消息的大小,可以准确指定 kalloc
分配的大小,当相应的 mach 端口被销毁时,相应的分配将立即释放回 kfree
。
然后,这些占位符中的一些可以被 释放。kalloc.4096
空闲列表以后进先出顺序释放元素,这基本上意味着如果一些占位符被释放,而利用尝试在尝试分配易受溢出影响的对象时分配多个受害者对象,则该对象很可能会被一个受害者对象跟随。
在 此页面 中,可以找到一个基本的堆溢出仿真,展示了如何通过覆盖下一个块的 prev in use 位和 prev size 的位置来 合并一个已使用的块(使其认为是未使用的)并 再次分配它,能够覆盖在不同指针中使用的数据。
另一个来自 protostar heap 0 的示例展示了一个非常基本的 CTF 示例,其中 堆溢出 可以被滥用以调用赢家函数以 获取标志。
在 protostar heap 1 示例中,可以看到如何通过滥用缓冲区溢出来 在一个临近块中覆盖一个地址,该地址将写入 来自用户的任意数据。
在页面 https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ 中,您可以找到一个堆溢出示例,其中要执行的命令存储在溢出块的下一个块中。因此,可以通过用简单的利用覆盖它来修改执行的命令,例如:
我们利用整数溢出漏洞来获取堆溢出。
我们破坏指向溢出块内 struct
的函数指针,以设置如 system
的函数并获得代码执行。
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE) 学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)