时光荏苒,记忆犹新!
WordPress 是世界上最受欢迎的内容管理系统, 超过 40% 的网站都在使用它。这种广泛采用使其成为威胁参与者和安全研究人员的首要目标,他们通过他们的公共漏洞赏金计划报告安全问题而获得报酬。
漏洞经纪人也非常有兴趣获取未修补的漏洞,使他们能够接管 WordPress 实例,有时会为关键漏洞提供高达 300,000 美元的报价。因此,WordPress 有一个经过严格审查的代码库,预计研究人员不会再在其中找到唾手可得的成果。我之前对该目标的研究需要广泛的专业知识和努力来发现安全问题。
这篇博文描述了 WordPress 的 pingbacks 实现中一个非常简单的漏洞。虽然此漏洞对 WordPress 的大多数用户的影响很小,但相关的易受攻击的代码模式值得记录,因为它也可能存在于大多数 Web 应用程序中。这篇博文的目的是宣传这种模式并提高认识。
该漏洞已于 1 月 21 日报告给 WordPress;尚无修复方法。请参阅补丁部分以获得有关适用于您的 WordPress 实例的潜在补救措施的指导。
这是我和我的团队第一次发布有关未修补漏洞的详细信息,这个决定并非草率做出。大约六年前的 2017 年 1 月,另一位研究人员和多年来的许多其他人首次报告了这个问题。在我的报告和进一步调查之后,我还可以识别出多篇公共博客文章,这些文章记录了与我今天要介绍的行为相同的行为。
由于其原样的低影响、之前的发布以及将其链接到第三方软件中的其他漏洞的需要,我相信这个版本不会危及 WordPress 用户,只会帮助他们加强他们的实例。
在不依赖其他易受攻击的服务的情况下,我无法通用地确定利用此行为来接管易受攻击实例的方法。
它可以减轻对受影响组织内部网络中其他漏洞的利用,例如使用最近的 Confluence OGNL 注入之一.
Pingbacks 是博客作者在其他“朋友”博客引用给定文章时得到通知和显示的一种方式:它们与评论一起显示,可以自由接受或拒绝。在幕后,博客必须相互执行 HTTP 请求以识别链接的存在。访问者也可以触发此机制。
此功能受到广泛批评,因为它使攻击者能够通过恶意要求数千个博客检查单个受害服务器上的 pingback 来执行分布式拒绝服务攻击。由于社交和社区功能在个人博客方面的重要性,因此在 WordPress 实例上默认情况下仍启用 Pingbacks。但是,预计这些请求不会发送到同一服务器或本地网段上托管的其他内部服务。
pingback 功能在 WordPress 的 XML-RPC API 上公开。提醒一下,这是一个需要 XML 文档的 API 端点,客户端可以在其中选择要调用的函数和参数。
其中一个实现的方法是pingback.ping
,期望参数pagelinkedfrom
和pagelinkedto
:第一个是引用第二个的文章的地址。
pagelinkedto
必须指向本地实例的现有文章,此处http://blog.tld/?p=1
,以及pagelinkedfrom
应包含指向 的链接的外部 URL pagelinkedto
。
以下是对此端点的请求:
HTTP
POST /xmlrpc.php HTTP/1.1
2个
主机:blog.tld [...]
3个
的
4个
<方法调用>
5个
<方法名>pingback.ping</方法名>
6个
<参数>
7
<参数>
8个
<value><string>http://evil.tld</string></value>
9
</参数>
10
<参数>
11
<value><string>http://blog.tld/?p=1</string></value>
12
</参数>
13
</参数>
14
</方法调用>
WordPress 核心方法 wp_http_validate_url() 对用户提供的 URL 运行几个检查以降低滥用风险。例如:
目的地不能包含用户名和密码;
主机名不得包含以下字符:#:?[]
域名不应指向本地或私有 IP 地址,如 127.0.0.1、192.168.* 等。
URL 的目标端口必须是 80、443 或 8080。
第三步可能涉及解析域名(如果 URL 中存在)(例如,http://foo.bar.tld
)。在这种情况下,远程服务器的 IP 地址是通过解析 URL [1]并稍后在验证它以排除非公共 IP 范围之前解析它[2]获得的:
src/wp-includes/http.php
PHP1个
<?
2个
的
3个
$parsed_url = parse_url ( $url ); // [1]
4个
// [...]
5个
$ip = gethostbyname ( $host ); // [2]
6个
// [...]
7
如果($ip === $host){
8个
// gethostbyname() 的错误条件
9
返回 假;
10
}
11
// IP 验证发生在这里
12
}
验证代码看起来正确执行,并且 URL 现在被认为是可信的。接下来发生什么?
两个 HTTP 客户端可以在基于可用的 PHP 功能验证 URL 后处理 pingback 请求:Requests_Transport_cURL
和Requests_Transport_fsockopen
. 它们都是Requests库的一部分,在 WordPress 保护伞下独立开发。
让我们看看后者的实现。我知道它使用名称中的 PHP 流 API。它在传输级别运行,客户端必须手动制作 HTTP 请求。使用 再次解析 URL parse_url()
,然后使用其主机部分创建与 PHP 流 API 兼容的目标(例如,tcp://host:port
):
wp-includes/Requests/Transport/fsockopen.php
PHP1个
<?
2个
的
3个
公共 函数 请求( $url , $headers = array (), $data = array (), $options = array ()) {
4个
// [...]
5个
$url_parts = parse_url ( $url );
6个
// [...]
7
$host = $url_parts [ '主机' ];
8个
// [...]
9
否则{
10
$remote_socket = 'tcp://'。$主机;
11
}
12
// [...]
13
$remote_socket。= ':'。$url_parts [ '端口' ];
在更远的地方,这个目的地被用来创建一个新的流stream_socket_client()
,并且 HTTP 请求被制作并写入它:
wp-includes/Requests/Transport/fsockopen.php
PHP1个
<?
2个
的
3个
$socket = stream_socket_client ( $remote_socket , $errno , $errstr , ceil ( $options [ 'connect_timeout' ]), STREAM_CLIENT_CONNECT , $context );
4个
// [...]
5个
$out = sprintf ( "%s %s HTTP/%.1F\r\n" , $options [ 'type' ], $path , $options [ 'protocol_version' ]);
6个
// [...]
7
if ( ! isset ( $case_insensitive_headers [ 'Host' ])) {
8个
$出。= sprintf ( '主机: %s' , $url_parts [ '主机' ]);
9
// [...]
10
}
11
// [...]
12
fwrite ( $socket , $out );
正如我们所看到的,这个过程意味着另一个 DNS 解析,因此stream_socket_client()
可以识别主机的 IP 来发送数据包。
另一个 HTTP 客户端 cURL 的行为非常相似,这里不再赘述。
这种构造有一个问题:HTTP 客户端必须重新解析 URL 并重新解析主机名才能发送其请求。同时,攻击者可能已将域更改为指向与之前验证的地址不同的地址!
此错误类也称为 Time-of-Check-Time-of-Use:资源经过验证但可以在其有效使用之前进行更改。在针对服务器端请求伪造 (SSRF) 的缓解措施中发现此类漏洞很常见。
我用下图总结了这些连续的步骤:
我审核了代码,希望找到允许到达非预期端口或执行 POST 请求但未成功的解析器差异错误:初始 URL 验证步骤具有足够的限制性以防止它们被利用。如前所述,攻击者必须将此行为与另一个漏洞联系起来才能显着影响目标组织的安全。
在撰写本出版物时,我不知道有任何可用的公共补丁;以上详细信息基于在披露过程中与我们共享的中间补丁。
解决此类漏洞需要保留经过验证的数据,直到它用于执行 HTTP 请求。它不应在验证步骤后被丢弃或转换。
WordPress 维护者通过引入第二个可选参数来遵循这条路径wp_http_validate_url()
。该参数通过引用传递,包含 WordPress 执行验证的 IP 地址。最终代码稍微冗长一些,以适应旧版本的 PHP,但主要思想就在这里。
作为临时解决方法,我建议系统管理员删除pingback.ping
XML-RPC 端点的处理程序。一种方法是更新正在使用的主题的 functions.php 以引入以下调用:
PHP1个
<?
2个
的
3个
add_filter ( 'xmlrpc_methods' ,函数( $methods ) {
4个
取消设置($methods [ 'pingback.ping' ]);
5个
返回 $方法;
6个
});
也可以xmlrpc.php
在 Web 服务器级别阻止访问。
日期 | 行动 |
---|---|
2022-01-21 | 我和我的团队按照 90 天披露政策将漏洞提交给维护人员。 |
2022-01-21 | 我提交的内容被归类为与最初(恰好)5 年前(2017 年 1 月 21 日)发送的报告重复。 |
2022-04-11 | WordPress 要求将我们 90 天的披露政策延长 30 天,因为他们需要更多时间来处理反向移植。我同意。 |
2022-05-23 | 维护者分享了 WordPress 5.9.3 的补丁。 |
2022-06-01 | 我和我的团队对补丁提供了积极的反馈。 |
2022-07-16 | 我和我的团队传达了我们打算在 9 月 6 日发布此出版物的意图。 |
2022-09-01 | 最后要注意即将出版的出版物。 |
2022-09-06 | 这篇文章是在我们报告后 228 天和另一位研究人员首次报告后 2054 天发布的。 |
在本文中,我描述了一个影响 WordPress Core 的盲目 SSRF 漏洞。虽然在这种情况下影响很小,但这是一种广泛存在的易受攻击的代码模式,即使在大型项目中,我和我的团队也会继续遇到这种情况。我鼓励开发人员检查他们自己的代码库是否存在此类代码漏洞,正如我所展示的那样,这种代码漏洞甚至可以隐藏在非常流行和经过严格审查的代码中。
本文由本站原创或投稿者首发,转载请注明来源!
本文链接:http://www.ziti66.com/net/html/174.html
下面有请小扒菜。。。
本站投稿暂时请将内容发送至指定邮箱,审核内容健康后放出,原创内容将优先置顶展现!
邮箱:liye1122#126.com
❤安全运行天 Copyright © 2018-2025 66字体网 版权所有.
本站采用创作共用版权 CC BY-NC-SA 3.0 CN 许可协议,转载或复制请注明出处