单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析

作者:深圳市网安计算机安全检测技术有限公司 | 国际 2019/04/22 09:35:09 666
文章来源:https://www.4hou.com/vulnerable/17453.html

概述

       最近,Drupal发布了一组针对7.x和8.x版本的关键补丁。在更新中,包含对一组漏洞的修复,这些漏洞是我们最初在参与针对该目标的漏洞激励计划时提交的。这些漏洞可以实现代码执行,但前提条件是攻击者必须首先将三个恶意“图像”上传至目标服务器,并诱导经过身份验证的站点管理员点击精心设计的链接来实现代码执行。这并不是一个顺利的漏洞利用途径,因此我们也没有获得TIP的奖项。但是,这些漏洞可以被别有用心的攻击者用来发起有针对性的攻击,因此我们将对这些漏洞进行详细分析。下面是其中一个漏洞的演示视频:

       https://youtu.be/GT5LCO7D3SE

       通过对两个漏洞的组合利用,可以实现单次点击后的代码执行,这两个漏洞分别是ZDI-19-130以及Sam Thomas发现的ZDI-19-291。通过在注册用户帐户时上传个人资料图片,或者在评论中上传图像,可以轻松实现任意图像上传。当然,禁用用户注册和用户评论的Drupal站点不容易受到这些攻击媒介的影响,但我们还是建议这部分用户将Drupal服务器更新到最新版本。

       ZDI-19-130是一个PHP反序列化漏洞,通过利用该漏洞,攻击者可以获取站点Admin权限的远程代码执行。ZDI-19-291是一个持久的XSS漏洞,攻击者可以利用该漏洞来强制向管理员发出恶意请求,从而触发ZDI-19-130漏洞。

       ZDI-19-130的漏洞利用原理,是基于Thomas今年早些时候在Black Hat上发表的演讲(PDF),各位读者可以阅读该演讲的白皮书,也可以在这里观看他在BSidesMCR上发表过的同一个Black Hat演讲的视频。在演讲中,Thomas详细介绍了他发现的一个新的载体,通过Phar压缩包触发PHP反序列化漏洞。实质上,PHP Phar压缩包的元数据以PHP序列化对象的形式存储。Phar压缩包上的文件操作可以触发存储的元数据上的unserialization()(反序列化),最终可能导致代码执行。

       另一方面,ZDI-19-291是处理上传文件名过程中与Perl兼容的正则表达式(PCRE)相关的漏洞。当用户上传文件时,Drupal使用PRCE对文件名进行修改,以避免名称重复。在过去的8年中,包含PCRE漏洞的提交始终存在于代码库中,并且可能导致Drupal在多次上传时删除文件名的扩展名,从而允许攻击者上传任意HTML文件。

回顾:PHP对象注入起源

       早在2009年,也就是iPhone 3GS发布的同一年,Stefan Esser(@i0n1c)就证明PHP反序列化过程容易受到对象注入的影响,并且可以通过类似于ROP的代码重用技术(PDF)来进一步利用。后来,他创造了“面向属性编程”(Property Oriented Programming)(PDF)这一术语。在演示之前,PHP对象反序列化漏洞主要都是拒绝服务漏洞,或者难以利用的内存损坏漏洞。

       类似于ROP的首次亮相,POP链的构建需要手工进行,并且过程较为繁琐,没有太多的工具或文献可以用来参考。我所知道的唯一参考资料,就是Johannes Dahse等人在2014年发布的关于自动化POP链生成的优秀文章(PDF)。但遗憾的是,他们从未对外向公众们发布过他们的工具。

回顾:POP漏洞利用商品化

       PHP Generic Gadget Chains(PHPGGC)在2017年7月发布了.PHP Generic Gadget Chain库,它可以被认为类似于ysoserial Java反序列化漏洞Payload库。随着PHP框架和库的普及,以及PHP自动加载功能的帮助,PHP反序列化漏洞的利用最终变得非常简单。

漏洞利用:第一阶段(ZDI-19-291)

       我们使用下面的PHP代码,来测试Drupal源代码中的一部分。根据源代码中的注释,下面的代码段尝试分离文件名中ASCII控制字符的部分,这部分字符值小于0x20,并用下划线“_”字符替换它们。“/u”模式修饰符使得PHP引擎将PCRE模式和主字符串视为使用了UTF-8编码。据我们推测,该修饰符已经被添加到PCRE模式中,从而确保与UTF-8的兼容性。

单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析

       大家普遍会认为,UTF-8字符具有两个字节的长度。但与之相反,有效的UTF-8代码点可能是1-4个字节长度。UTF-8旨在向后兼容ASCII字符集。因此,在单字节代码点范围内,ASCII(8位字节0x00到0x7F)和UTF-8定义存在交集。0x80到0xF4之间的八位字节用于多字节UTF-8代码点编码。根据RFC3629中的标准,C0、C1、F5到FF的八位字节值永远不会出现在有效的UTF-8字符串中。

漏洞利用:第一阶段(测试)

单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析

       如果\xFF字节无效,并且\x80字节没有有效的前导字节,那么PHP将会抛出PREG_BAD_UTF8_ERROR错误,并且每个文档的$basename变量都将设置为NULL。

       在Drupal源代码中,在preg_replace()调用之后,不执行任何错误检查。当包含无效UTF-8字符文件名的图像两次上传至Drupal时,该函数将会运行,并将$basename变量松散地视为空字符串。最后,函数返回$destination,它被有效地设置为’_’.$counter++的结果。

单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析

       有了这个原语之后,攻击者可以通过用户注册功能,将GIF格式的个人资料图片上传至Drupal站点,并导致其扩展名被删除。Drupal现在将会使用如下路径和文件名:

/sites/default/files/pictures/<YYYY-MM>/_0

来替换:

/sites/default/files/pictures/<YYYY-MM>/profile_pic.gif

       尽管对上传的个人资料图片进行了检查,但在带有“.gif”扩展名的HTML文件中添加字符“GIF”,即可满足通过该检查所需的要求。

       同时,还有另一种方法能够上传恶意GIF文件,就是评论编辑器。在这种情况下,图像将在/sites/default/files/inline-images/_0中提供。然而,在默认Drupal配置的情况下,攻击者需要在评论的帖子发表之前注册用户帐户。

       当上述恶意行为,与通常在没有任何Content-Type标头的情况下提供图像的事实相结合后,攻击者可以将恶意GIF/HTML文件上传到Drupal服务器,并欺骗浏览器将恶意文件作为HTML网页呈现,具体方法是将它们与内容类型提示相链接。示例如下:

单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析

       总而言之,攻击者可以在目标Drupal站点上实现持久性XSS。攻击者可能利用该漏洞,强制具有管理员权限的用户通过诱使登录用户访问恶意链接的方式,来实现第二阶段的恶意查询。在这里可以找到可执行的PoC。

漏洞利用:第二阶段(ZDI-19-130)

       ZDI-19-130漏洞是通过位于/admin/config/media/file-system端点的file_temporary_path请求参数触发的反序列化漏洞。攻击者可以指定phar://流包装器(Wrapper)将file_temporary_path参数指向在攻击之前上传到Drupal服务器的恶意Phar压缩包。

       下面的system_check_directory()函数,是处理请求的表单回调函数。根据Thomas的演示,文件操作!is_dir($directory)足以导致PHP触发在Phar压缩包中的元数据的反序列化。通过POP链漏洞利用技术,攻击者可以使用精心设计的Phar压缩包,在Web服务器的环境中执行任意代码。

漏洞利用:第二阶段(多语言)

       在利用ZDI-19-130之前,我们必须将Phar压缩包上传到目标。具体而言,这可以通过在用户注册期间上传JPEG/Phar多语言文件作为用户个人资料图片来实现。下面是一个PoC的JPEG/Phar多语言文件,当它与ZDI-19-130漏洞利用共同使用时,将会在受害者主机上执行cat /etc/passwd命令。

       与JAR文件非常相似,Phar压缩包是将各种组件打包到单个压缩包文件中的集合。在PHP规范中,规定可以使用不同的压缩包格式来打包组件。在具体的漏洞利用中,我们使用基于TAR的Phar压缩包。

       要创建多语言文件,攻击者必须首先选择JPEG图像向量。然后,基于TAR的Phar压缩包完整存储在靠近JPEG文件开头的JPEG注释段中。当解析为TAR存档时,图像开始部分的JPEG段标记和注释段标记将导致第一个文件名的略微损坏。当对TAR文件进行校验并且修复时,一旦存储在TAR/Phar压缩包的第一个文件与包含POP链Payload的Phar元数据组件文件不对应,这种轻微的损坏对于漏洞利用的实际所需功能来说是无关紧要的。

漏洞组合利用

       我们回顾一下,攻击者必须首先将ZDI-19-130 JPEG/Phar多语言图像文件上传到目标服务器,并确定上传图像的位置。然后,攻击者必须两次上传ZDI-19-291 GIF/HTML图像XSS,以使得图像以没有扩展名的文件名形式存储在服务器上。最后,攻击者必须诱使网站管理员通过具有适当内容类型提示的链接,导航到目标服务器上托管的ZDI-19-291 GIF/HTML图像,以使浏览器将图像呈现为HTML页面,并触发漏洞的第二部分。如果一切顺利,攻击者将能够实现Web服务器上代码执行,并将得到反向Shell,如上面的演示视频所示。

总结

       Thomas提出了一种新颖的攻击载体,可以为攻击者打开许多新的大门。除非PHP决定修改Phar压缩包处理行为,否则程序员在通过文件操作符传递用户控制的数据时,需要格外警惕。由于将用户控制的数据传递到无害的文件操作符(例如:is_dir())并不会被视为高风险的操作,我们预计,后续将会出现更多利用此向量的漏洞。随着POP链漏洞利用工具集的推进,PHP反序列化漏洞将变得能被攻击者轻松利用。软件提供商应该将这一现状视为serialize()的最后一根稻草,并应该立即着手换用更安全的json_encode()替代方案。

       尽管我没有得到TIP的最终奖项,但在整个研究过程中我还是发现了严重的漏洞,并以非常投入的状态进行了深入分析。如果各位读者对TIP计划感兴趣,请关注我们的博客,这一系列活动的总奖金超过1000000美元,大家可能会发现一些非常值得关注的漏洞潜在领域。

       大家可以在Twitter上找到我@TrendyTofu,同时也可以关注团队,以获取最新的漏洞利用技术和安全补丁。

本文翻译自:https://www.thezdi.com/blog/2019/4/11/a-series-of-unfortunate-images-drupal-1-click-to-rce-exploit-chain-detailed  如若转载,请注明原文地址: https://www.4hou.com/vulnerable/17453.html


推荐关注

指导单位
广东省公安厅网络警察总队 广东省信息安全等级保护协调小组办公室