Raye's Journey

thinkphp-rce分析

太惭愧了,今年一月份大火的thinkphp漏洞根本没关注,现在回过头来仔细分析下

开启debug模式

先放截图:

然后开始一步步来搞

php-storm如何调试就不细说了

thinkphp从这里开始启动,有机会一定要分析下thinkphp是如何运行的

这里F8一下先进入了一个autoload函数,具体作用不是很清楚

进入run函数之后,会先实例化一个$request
之后进行一些模块绑定的操作,之后进入self::routerCheck函数,进行URL路由检测

而self::routerCheck函数又会调用Route::check函数

Route::check函数中:

$url = str_replace($depr, '|', $url);

if (strpos($url, '|') && isset(self::$rules['alias'][strstr($url, '|', true)])) {
    // 检测路由别名
    $result = self::checkRouteAlias($request, $url, $depr);
    if (false !== $result) {
        return $result;
    }
}
$method = strtolower($request->method());
// 获取当前请求类型的路由规则
$rules = self::$rules[$method];
// 检测域名部署
if ($checkDomain) {
    self::checkDomain($request, $rules, $method);
}

这里最关键的就是$method = strtolower($request->method());

转过头来分析这个函数

   /**
     * 当前的请求类型
     * @access public
     * @param bool $method  true 获取原始请求类型
     * @return string
     */   
public function method($method = false)
    {
        if (true === $method) {
            // 获取原始请求类型
            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')])) {
                $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 = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
            }
        }
        return $this->method;
    }

此时我们看到调用了__construct方法

/**
 * 架构函数
 * @access protected
 * @param array $options 参数
 */
protected function __construct($options = [])
{
    foreach ($options as $name => $item) {
        if (property_exists($this, $name)) {
            $this->$name = $item;
        }
    }
    if (is_null($this->filter)) {
        $this->filter = Config::get('default_filter');
    }
    // 保存 php://input
    $this->input = file_get_contents('php://input');
}

>  cd ..