接上篇《深入考察解释型语言背后隐藏的攻击面,Part 1(上)》本文将与读者一起深入探究解释型语言背后隐藏的攻击面。通常,在高级语言的内存管理功能的实现代码中,存在一个相对脆弱的基于C/C++的攻击面。这种问题可能存在于语言本身的核心实现中,也可能存在于将向高级语言提供基于C/C++的库的第三方语言生态系统中。在上一篇文章中,我们介绍了与此密切相关的C格式化字符串漏洞知识。在本文中,我们将介绍这些底层实现如何影响解释型语言的安全性。Perl格式化的幽灵(CVE-2005-3962)解释型语言提供自己的格式化函数并不少见,尤其是Perl通过其较低级别的Perl_sv_vcatpvfn函数提供格式化支持。这些低级CAPI为高级PerlAPI提供了很多核心格式化支持。它的格式化支持在句法上有点类似于C,因为它还支持直接参数访问的概念,在Perl中称为“精确格式索引”,以及格式标识符%n。当我们考虑到存在明显易受格式字符串错误影响的基于Perl的远程服务应用程序时,了解Perl的内置格式化支持变得非常有趣。然而,由于没有办法在Perl级别直接利用这些漏洞,安全研究界并没有花太多精力尝试利用它们,而是普遍将它们视为“只是一个漏洞”。2005年前后,CVE-2005-3962的作者(JackLouis)确定了这些漏洞的可利用性后,我对Perl格式字符串漏洞进行了更深入的研究。在测试JackLouis在Webmin中发现的Perl格式字符串错误时,他在Perl解释器中遇到了一些可观察到的崩溃。事实证明,攻击者确实可以通过Perl_sv_vcatpvfn中格式支持的C级实现来利用基于Perl的格式字符串漏洞。Perl格式字符串的参数存储在指向参数结构(称为svargs)的指针数组中,格式说明符(例如%1$n)被赋予确切的格式索引,用于从中检索指向参数结构的适当指针参数数组。当从数组中检索关联的参数结构指针时,Perl将根据格式字符串中可用的参数数量,确保提供的索引不超过数组的上限。这里的参数count其实是保存在一个有符号整型变量中的,即svmax。也就是说,如果格式字符串传递1个参数,svmax的值为1,并检查确切的格式索引值不超过1。如果攻击者提供格式字符串,则没有参数,svmax的值为0。但是,确切的格式索引也是一个带符号的32位整数,其值完全由攻击者提供的格式字符串控制。这意味着您可以将此参数数组索引设置为负值,这也将通过针对svmax的带符号上限检查。一旦理解了这一点,利用该漏洞就会变得相当简单。可以通过svargs数组索引直接索引任何指向攻击者控制的数据的指针。该攻击者控制的数据将被解释为包含指向值字段的指针的参数结构。结合熟悉的%n格式说明符,攻击者可以对受控位置执行受控写入。使用这样的写原语,可以覆盖任何可写进程内存的内容,这些内存可以以各种方式用于完整的进程控制。这是一个很好的例子,说明Perl格式化实现中的错误如何转化为安全漏洞。结合Webmin中的格式化字符串漏洞,攻击者可以对Webmin发起远程代码执行(RCE)攻击。我们得出的结论是,即使在高级语言级别看起来“只是一个错误”的问题也需要深入检查低级别对错误输入的处理,因为它们很可能会转化为高严重性漏洞-即使有人曾经认为这样的问题实际上是无法利用的。PHP解释器的无限潜力从攻击者的角度来看,他们一直在争夺的PHP解释器有很多版本。这是因为攻击者通常可以从解释器控制和远程API输入的角度对其进行攻击:对于前者,攻击者可以执行任意PHP代码;对于后者,攻击者可以提供具有潜在漏洞的PHPAPI恶意输入。利用PHP解释器的一个更有趣的示例是反序列化攻击。因为攻击者已经在PHP逻辑层和核心解释器层攻破了PHP的反序列化API。人们普遍认为反序列化不受信任的用户提供的数据是一个坏主意。在远程应用程序的上下文中,任意对象反序列化可能会导致相对简单的PHP任意执行,具体取决于应用程序命名空间中可用和允许的类。这个话题超越了语言界限,我们在几乎所有支持反序列化的语言和应用程序框架中都看到了相同的概念。攻击者实现任意PHP执行后,他们可能会发现自己受到受限解释器配置的约束,此时他们通常会探索解除这些限制的方法。历史上流行的一种方法是利用PHP解释器本身的错误。最近可以在https://bugs.php.net/bug.php?id=76047找到此类攻击的示例,其中可以利用debugbacktrace()函数中的释放后使用(UAF)漏洞获得对服务器本身的PHP解释器的完全控制,并删除所有配置限制。有时,即使提供了受控的PHP反序列化原语,也无法将其转化为任意PHP执行能力,因为攻击者无法知道哪些类可用,或者由于应用程序命名空间中的某些限制。这时候从上层跳水到代码层下层,很有可能找到突破口。由于存在大量内存管理不善问题,PHP的反序列化API长期以来一直是模糊测试和解释器漏洞的热门研究目标。通过在反序列化API的解释器实现级别利用内存管理不善,坚定的攻击者可以将原本无法利用的漏洞转变为完全可利用的漏洞。事实上,已经有很多通过这个攻击面远程利用PHP应用程序的实际例子。最近的一个例子出现在RuslanHabolov的一篇优秀文章中,该文章描述了他们如何利用低级PHP解释器错误和高级PHPAPI交互来发起针对众所周知的现实世界目标的RCE攻击。通过PHP反序列化在较高和较低级别实现的混合攻击面是解释语言垂直攻击面的另一个很好的例子。将C引入Python:CVE-2014-1912漏洞出于本文的目的,我们的第三个也是最后一个示例是CVE-2014-1912漏洞。该漏洞存在于Python的socket.recvfrom_into函数中。Python2.5中引入的socket.recvfrom_into的预期用途是将数据接收到指定的Python字节数组中。但是,由于该函数缺少显式检查,因此无法确保接收数据的目标缓冲区足够大以容纳指定数量的传入数据。例如socket.recvfrom_into(bytearray(256),512)会触发内存损坏问题。后来,人们用下面的代码修复了它:diff-re6358103fe4fModules/socketmodule.c---a/Modules/socketmodule.cWedJan0820:44:372014-0800+++b/Modules/socketmodule.cSunJan1213:21:192014-0800@@-2877,6+2877,14@@recvlen=buflen;}+/*检查缓冲区是否足够大*/+if(buflen
