在2001年底,"Vudo Malloc Tricks"和"Once Upon A free()"定义了Linux中的动态内存块溢出的开发。在2004年底,一系列关于GNU libc malloc的补丁实现了十多个强制性完整性断言,有效地地说明了现有的技术已经过时了。
正是由于这个原因,一个几乎不可能的小的建议,就是我打算展示Malloc Maleficarum。
●The House of Prime
●The House of Mind
●The House of Force
●The House of Lore
●The House of Spirit
●The House of Chaos
The House of Prime
首先介绍The House of Prime。一个艺术家有一幅画的第一次描边,一个作家总有过写出一首诗的第一行的经历。而对于我来说,在堆溢出发面,则是House of Prime。这是第一次突破,同时也表明了接下来一切都会水到渠成。可以说,这就是拒绝不可能,同时这也是相当困难的。由于这些原因,我觉得有必要将Prime放在Malloc Maleficarum的首要位置,而且,这也是它应得的。
从纯粹的技术角度出发,House of Prime或许是收集中最没有用的了。当条件允许的时候,使用House of Mind 或者House of Sprit 几乎可以说总是更好的。为了成功地使用House of Prime技术,我们必须释放两个由自己控制的不同size字段的chunk,然后触发对malloc的调用。
正如前面所说的,这个技术首先调用free函数释放由我们自己控制的内存。调用free函数会继续调用public_fREe,进而调用内部的函数_int_free。对于House Of Prime来说,public_fREe的细节相对来说不重要。因此我们只需要关注_int_free即可。这是它在glibc-2.3.5中的代码:
这就是fastbin的代码了。至于什么是fastbin以及为什么它们会被使用已经超出了本文的范围了。但是请记住,House of Prime的第一步就是覆盖fastbin的最大size,av->max_fast。为了达到这样的效果,从上面可以看出,我们必须首先提供具有较低下限大小的块。考虑到av->max_fast的默认值是72,我们就很容易知道fastbin代码主要是对于不大于这样大小的块进行操作。但是,也正是因为这个才会导致av-max_fast的损坏不会立即出现效果。
然而,House of Prime的挑战部分并不是去覆盖av->max_fast,而是如何利用覆盖进行任意代码执行。House of Prime通过覆盖特定线程变量arena_key来做到这一点。这就是House of Prime所需要的最难的条件。首先,arena_key仅仅在glibc中的malloc函数使用USE_ARENAS标志(默认使用)被编译的时候才存在。进一步,最重要的是,arena_key的地址一定会比真实的arena地址高。
为了覆盖arena_key,fastbin代码又会被利用。这对应着我们第二次调用free来释放我们可以控制大小的块。这在House of Prime的先决条件中已经列出来了。正常情况下,fastbin代码不能够写超过av->fastbin,但是既然av->max_fast在先前已经被破坏了,任何一个大小小于我们第一次使用的块的地址的chunk都会被这个fastbin 代码处理。因此,我们可以写到av->fastbins[fastbin_index(av->max_fast)],这样就有很大的范围来得到arena_key了。