PRELOADER

当前文章 : 《发现0day并在Mozilla的AWS网络上执行远程代码攻击》

12/2/2019 —— 

发现0day并在Mozilla的AWS网络上执行远程代码攻击

原文链接:https://blog.assetnote.io/bug-bounty/2019/03/19/rce-on-mozilla-zero-day-webpagetest/

当Assetnote Continuous Security(CS)监控网络攻击时,它主要使用的工具是WebPageTest

WebPageTest是一个网站性能测试工具,可让您测试任何给定URL/主机的网络相关指标。

虽然可以通过修改settings.ini文件来启用基本身份验证,但建议阻止任何匿名访问。Assetnote CS识别的大多数WebPageTest部署都是

未经身份验证的,WebPageTest提供的测试工具阵列可以通过服务器端请求伪造(通常称为SSRF,但对于WebPageTest,它是一个功能)进攻性地用于访问内部资源)。

2017年11月,Assetnote CS在Mozilla的AWS环境中发现了以下资产:

  1. wpt-vpn.stage.mozaws.net
  2. wpt1.dev.mozaws.net

这两个都是WebPageTest的实例,不需要身份验证,这是Assetnote CS第一次检测到它的漏洞奖励。与Mathias合作,我们审核了源代码,

在短短几个小时内,我们就能够创建一个导致远程代码执行的攻击链。

虽然在发现时它是0day,但我们与Mozilla和WebPageTest团队合作,将漏洞进行修复处理。

修订本博客文章中列出的错误的提交在2018年1月17日的提交中被推送。

引起我们注意的代码库中的第一件事就是能够通过上传和提取任意Zip文件/www/work/workdone.php

此脚本包含一些限制127.0.0.1以外来源访问的逻辑,如下面的代码片段所示:

...
!strcmp($_SERVER['REMOTE_ADDR'], "127.0.0.1")
...

我们稍后再回过头来看看。

在同一个文件中,我们发现了另一个潜在的向量 - 逻辑来上传任意Zip并将其提取到已知位置:

第133 - 136行:/www/work/workdone.php

if (isset($_FILES['file']['tmp_name'])) {
  ExtractZipFile($_FILES['file']['tmp_name'], $testPath);
  CompressTextFiles($testPath);
}

如果我们可以欺骗我们的IP来自127.0.0.1,似乎我们可以通过这个向量获得代码执行。

但是,由于/www/work/workdone.php中的第321行,我们发现它并不像我们想象的那么简单:

SecureDir($testPath);

SecureDir函数的逻辑可以在/www/common_lib.inc中的第2322-239行中找到:

1. /**
1. * Make sure there are no risky files in the given directory and make everything no-execute
1. *
1. * @param mixed $path
1. */
1. function SecureDir($path) {
1. $files = scandir($path);
1. foreach ($files as $file) {
1. $filepath = "$path/$file";
1. if (is_file($filepath)) {
1. $parts = pathinfo($file);
1. $ext = strtolower($parts['extension']);
1. if (strpos($ext, 'php') === false &&
1. strpos($ext, 'pl') === false &&
1. strpos($ext, 'py') === false &&
1. strpos($ext, 'cgi') === false &&
1. strpos($ext, 'asp') === false &&
1. strpos($ext, 'js') === false &&
1. strpos($ext, 'rb') === false &&
1. strpos($ext, 'htaccess') === false &&
1. strpos($ext, 'jar') === false) {
1. @chmod($filepath, 0666);
1. } else {
1. @chmod($filepath, 0666);// just in case the unlink fails for some reason
1. unlink($filepath);
1. }
1. } elseif ($file != '.' && $file != '..' && is_dir($filepath)) {
1. SecureDir($filepath);
1. }
1. }
1. }

由于SecureDir函数在代码流前后之间发生变化,因此存在可利用的条件竞争漏洞,其中提取到Web服务器的PHP文件在被删除之前可以在短时间内访问。

链的第一个预请求者相当容易,因为https://google.com通过WebPageTest接口运行Traceroute可以获得有效的测试ID

wpt-vpn.stage.mozaws.net:

上图是使用WebPageTest运行traceroute的结果展示

运行traceroute后,WebPageTest将我们重定向到包含后续步骤中使用的测试ID的URL:

http://wpt-vpn.stage.mozaws.net/result/ 171124_GW_9 /

但是我们仍然需要以某种方式欺骗我们127.0.0.1以便访问此脚本中的易受攻击的函数。

我们通过利用以下逻辑来满足这个条件:

第70行:/www/common.inc

1. if (isset($_SERVER["HTTP_FASTLY_CLIENT_IP"]))
1.   $_SERVER["REMOTE_ADDR"] = $_SERVER["HTTP_FASTLY_CLIENT_IP"];

这允许我们作为远程用户$_SERVER["REMOTE_ADDR"]通过发送FASTLY-CLIENT-IP请求标头来任意设置127.0.0.1

将所有这些元素组合在一起,我们能够设置两个Burp Intruder攻击,最终获得代码执行。

一个Burp Intruder攻击用于上传恶意Zip文件,另一个尝试访问提取的PHP文件,而它存在于系统上。我们当时利用条件竞争的解决方案是将Burp Intruder的线程简单地提升到~200。

今天,由于发送请求的速度,使用Turbo Intruder等工具,可以使此漏洞利用更加可靠。

我们能够使用这种技术在Mozilla上实现代码执行,如下面的屏幕截图所示:

上图为wpt-vpn.stage.mozaws.net的phpinfo()输出

我们首次报告此漏洞的Bugzilla报告现已公开,可在此处查看。该报告包含彻底的复制步骤,对于希望重新创建这些错误的测试人员来说应该足够了。

作为Mozilla的bug赏金计划的一部分,我们获得了500美元。