首页
社区
课程
招聘
[翻译]堆溢出技术:Malloc Maleficarum之The House of Lore
发表于: 2017-3-7 20:38 3541

[翻译]堆溢出技术:Malloc Maleficarum之The House of Lore

2017-3-7 20:38
3541

当我在回顾House of Prime的草稿的时候,我想到了House of Lore. 当我第一次搞House of Prime的时候,我主要关注如何利用一个在fastbin code中的高av->max_fast所允许的特别覆盖。在重新考虑这个问题的时候,我意识到,在我第一次采取可能的覆盖目标的时候,我完全忽视了破坏一个bin条目的可能性。

      事实证明,由于av->max_fast很大,并且bin代码永远不会被执行,因此不可能利用House of Prime 中损坏的bin条目。然而,当我仔细搞清楚了这个过程之后,我意识到如果一个binav->max_fast不大时被破坏,那么我们就可以控制malloc请求的返回值。

      在这个阶段,我开始考虑将bin损坏应用到一个一般的malloc块溢出。问题是一个线性的malloc chunk块溢出是否可以导致bin的破坏。事实证明,答案是可以的,而且还很简单。进一步,如果我们控制堆的能力有限,或者没有其他的House技术可以使用,那么这种类型的bin corruption 事实上就非常有效。

      House of Lore 通过将一个bin的入口破坏来生效,这样可以随后使得malloc返回一个任意的chunk。这里介绍两种使得bin破坏的方法,对应于溢出小的和大的bin entry。一般方法包括重写之前由free处理的linked list的数据。在这个意义上,The House of Lore技术就和“Vudo Malloc Tricks”中提到的frontlink技术比较像了。

      The House of Lore技术的条件相当特别。从根本上说,该方法针对已经由free处理的chunk。因为这一点,我们有理由假设chunk不会再次被free函数调用。这就意味着,为了利用这样的溢出,我们只能利用malloc了。这是House of Force所独有的特点。在第一种方法中,我们将会利用smallbin 分配的代码:

因此,假设我们调用malloc的时候,申请超过av->max_fast(默认72)个字节,那么我们就可以到达smallbin检查的地方了。其中,in_smallbin_range()宏仅仅检查请求大小是否小于smallbin chunk的最大值(默认512字节)。Chunk的大小可能是在av->max_fastsmallbin的最大值之间的任何一个大小。在这种意义上说,smallbins是独特的。这就意味着对于任何给定的值,smallbin_index()算出来的bin,如果非空,就一定会包含一个适应于请求大小的chunk

      我们应当注意,当一个chunk被传递到free的时候,它并不会直接回到它对应的bin中。它会首先被放在unsorted chunk bin中。如果接下来请求的数据大小不能够被已知的smallbin chunk或者未排序的chunk满足的话,然后,未排序的chunk才会被排序并且放到对应的bin中。对于House of Lore的目的,溢出一个没有排序的chunk并没有什么用。因此,我们有必要确保要被溢出的块已经在之前的malloc中被排序到一个bin中了。

      注意,为了执行到实际的smallbin unlink代码。对应于目前请求的大小来说,smallbin_index()计算出来的结果bin中应至少有一个chunk。假设一个数据大小为 Nsmall chunk之前被传递给free,并且,他已经进入了绝对大小为N+8的块的相应smallbin中。假设我们可以使用任意数据来溢出该chunk。同样假设,我们可以随后触发调用请求大小为Nmalloc

      如果上面所有的条件都可以被满足,那么我们就可以到达smallbin unlink 的代码。当一个chunkunsorted bin 中被移出去后,他会被放到对应的small 或者large bin的开头。当一个chunk从一个bin中取下来的时候,例如在smallbin unlink 代码中,它从bin的尾部拿出来。这就是last()宏所做的事情,找到请求bin的最后一个入口。因此,实际上,在smallbin unlink代码中的victim chunk是从bin->bk中取下来的。这意味着,为了到达我们的victim chunk,我们或许需要重复执行多次申请N 个字节的malloc操作。

      需要强调的是,House of Lore的目标是控制bin->bk的值,但是,在这一阶段,只有victim->bk被控制。因此,假设我们可以触发一个导致溢出的victim chunk 被传递给smallbin unlink代码的malloc,由于我们控制了victim->bk,我们自然就控制了bck的值。由于bin->bk随后被设置为bckbin->bk就可以被任意控制了。由于bck->fdunlink 程序中的最后阶段被设置,bck必须指向一块可写的内存。

      然后,问题就在于如何利用smallbin 损坏。由于我们所利用的去得到bin->bk的控制的malloc调用很快就将victim chunk返回给了应用,我们至少需要调用多次请求同样大小的malloc调用。由于bin->bk在我们的掌控之下,因此,last(bin)victim同样也在。唯一阻止把一个任意victim chunk返回给应用的是由victim->bck设置的bck必须指向可写的内存。

      这排除了将victim chunk指向GOT或者.dtors 入口。取而代之的,我们必须将victim指向栈上,这样的话,victim->bk就指向了可写内存,同时和保存的返回地址足够近。这样的话,他就可以被应用的一般操作覆盖。或者,有可能会去采取一个与应用程序相关的方法,例如,使用目标函数使用的指针。无论使用哪一种方法,在某种程度上,应用所使用的任意的malloc chunk必须被我们所控制。

      对于House of Lore技术,其唯一有意思的场景是溢出的chunk很大。在这里,大意味着比smallbin chunk的最大值还要大。同时,对于被溢出的chunk来说,它有必要在之前被free执行,并且已经被malloc放到了largebin中。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//