Thinkphp框架filter参数漏洞解析

漏洞介绍

CNNVD编号:CNNVD-201812-489

漏洞介绍链接

noneCms github issue

nonecms的作者通过升级 thinkphp 框架的版本把漏洞修复了

查看 thinkphp/library/think/App.php 这个文件的修改历史可以发现

更新框架前是5.1.0

const VERSION = '5.1.0';

更新框架后是5.1.31

const VERSION = '5.1.31 LTS';

漏洞修复

漏洞出现在 NoneCMS/thinkphp/library/think/route/dispatch/Url.php 文件中的parseUrl方法里

            // 解析模块
            $module = $this->app->config('app_multi_module') ? array_shift($path) : null;
            if ($this->param['auto_search']) {
                $controller = $this->autoFindController($module, $path);
            } else {
                // 解析控制器
                $controller = !empty($path) ? array_shift($path) : null;
            }
    
            // 解析操作
            $action = !empty($path) ? array_shift($path) : null;
    
            // 解析额外参数
            if ($path) {
                if ($this->app['config']->get('url_param_type')) {
                    $var += $path;
                } else {
                    preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) {
                        $var[$match[1]] = strip_tags($match[2]);
                    }, implode('|', $path));
                }
            }

为了修复漏洞,thinkphp官方添加了新的代码

        if ($this->param['auto_search']) {
            $controller = $this->autoFindController($module, $path);
        } else {
            // 解析控制器
            $controller = !empty($path) ? array_shift($path) : null;
        }

        /**** 加入了这段代码 ****
        
        if ($controller && !preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
            throw new HttpException(404, 'controller not exists:' . $controller);
        }
        
        **** 加入了这段代码 ****/

        // 解析操作
        $action = !empty($path) ? array_shift($path) : null;

具体修改历史可以在以下链接找到

Url.php 修改历史

概括地说,就是把library/think/route/dispatch/Module.php 的代码移动到 library/think/route/dispatch/Url.php

$controller变量的校验代码经过多次改进之后,变成下面这个样子

    if ($controller && !preg_match('/^[A-Za-z][\w|\.]*$/', $controller)) {
        throw new HttpException(404, 'controller not exists:' . $controller);
    }

[A-Za-z][\w|\.]* 这个正则表达式的含义是 $controller 的第一个字符是字母A-Za-z。 [\w|\.] 匹配 a-zA-Z0-9_ 和 .。 例如可以匹配 a.b.abc123.., 所以严格来说, 这个正则表达式不是特别准确 。

漏洞运行

如果上面这段 $controller 变量的校验代码去掉并访问下面类似的链接,就会复现之前的漏洞。

   http://xxx.com/NoneCms/public/?s=index/\think\Request/input&filter=phpinfo&data=1

这时候变量 $controller 等于 \think\Request

当执行到文件 NoneCMS/thinkphp/library/think/Request.php 中的代码的时候, $filter = "phpinfo", $value = 1

    private function filterValue(&$value, $key, $filters)
    {
        $default = array_pop($filters);

        foreach ($filters as $filter) {
            if (is_callable($filter)) {
                // 调用函数或者方法过滤
                $value = call_user_func($filter, $value);

等于执行了以下代码,这样php运行环境的敏感信息就泄露了。适当构造URL参数就可以实现更多攻击和破解操作。

    $filter = "phpinfo";
    $value = 1;
    call_user_func($filter, $value);

总结

  1. 调用call_user_func函数时,要进行参数校验。
  2. 对于 HTTP GET 请求里的参数尽可能使用严格的正则表达式进行校验。
Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

微信扫一扫,分享到朋友圈

Thinkphp框架filter参数漏洞解析
返回顶部

Optimized by WPJAM Basic

显示

忘记密码?

显示

显示

获取验证码

Close