ThinkPHP5核心类Request远程代码漏洞分析
字数 1549 2025-08-18 11:38:08

ThinkPHP5核心类Request远程代码执行漏洞分析

漏洞概述

2019年1月11日,ThinkPHP团队发布补丁修复了一处由于不安全的动态函数调用导致的远程代码执行漏洞。该漏洞危害程度非常高,默认条件下即可执行远程代码。

受影响版本:ThinkPHP5.0-5.0.23完整版

漏洞复现环境

  • ThinkPHP 5.0.22完整版
  • PHP 5.5.38
  • Apache

漏洞分析

关键漏洞点

漏洞关键点位于:thinkphp/library/think/Request.php:518

method函数的第二个if分支中,引入了外部可控的数据$_POST[Config::get('var_method')],而var_method的值为_method

攻击流程

  1. 构造函数覆盖:攻击者可以通过控制$options参数来覆盖Request类的filter属性、method属性以及get属性的值。

  2. param函数调用:在Request类的param函数中,当$this->mergeParam为空时,会调用$this->get(false)

  3. input函数调用$this->get函数末尾调用了$this->input函数,并将可控的$this->get传入。

  4. 过滤器获取$this->input函数调用$this->getFilter取得过滤器,其中$this->filter的值是攻击者可控的。

  5. 代码执行:在filterValue函数中,call_user_func函数的$filter$value参数都是可控的,导致代码执行。

完整利用链

  1. 入口点thinkphp/library/think/App.php:77run函数实例化Request类。

  2. 路由检测:调用routeCheck($request,$config),进而调用Route::check进行路由检测。

  3. 变量覆盖:通过method函数覆盖$this->filter$this->method$this->get属性。

  4. 路由规则:完整版比核心版多出的think-captcha/src/helper.php文件会调用\think\Route::get进行路由注册,改变self::$rules的值。

  5. 路由解析:当攻击者控制$methodget时,$rules的值就是captcha路由的规则,最终调用到self::parseRule函数。

  6. 命令执行:最终调用Request类的param方法,完成利用链。

版本差异

  • ThinkPHP5.0.2-5.0.23:可以使用同一个POC
  • ThinkPHP5.0-5.0.1:需要更改POC,因为Route.phprule函数中对$type的处理不同(5.0-5.0.1转换为大写,5.0.2-5.0.23转换为小写)

补丁分析

在ThinkPHP5.0.24中,增加了对$this->method的判断,不再允许自由调用类函数。

安全建议

  1. 升级版本:强烈建议用户升级到ThinkPHP5.0.24或更高版本
  2. 关闭debug模式:避免遭受攻击
  3. 输入过滤:对所有用户输入进行严格过滤和验证
  4. 最小权限原则:运行环境使用最小必要权限

技术总结

该漏洞本质上是由于ThinkPHP框架中Request类对用户输入处理不当,导致攻击者可以控制函数调用和参数,最终实现远程代码执行。完整版特有的captcha路由组件为攻击提供了必要的路由规则,这也是核心版不受影响的原因。

ThinkPHP5核心类Request远程代码执行漏洞分析 漏洞概述 2019年1月11日,ThinkPHP团队发布补丁修复了一处由于不安全的动态函数调用导致的远程代码执行漏洞。该漏洞危害程度非常高,默认条件下即可执行远程代码。 受影响版本 :ThinkPHP5.0-5.0.23完整版 漏洞复现环境 ThinkPHP 5.0.22完整版 PHP 5.5.38 Apache 漏洞分析 关键漏洞点 漏洞关键点位于: thinkphp/library/think/Request.php:518 在 method 函数的第二个if分支中,引入了外部可控的数据 $_POST[Config::get('var_method')] ,而 var_method 的值为 _method 。 攻击流程 构造函数覆盖 :攻击者可以通过控制 $options 参数来覆盖Request类的 filter 属性、 method 属性以及 get 属性的值。 param函数调用 :在Request类的 param 函数中,当 $this->mergeParam 为空时,会调用 $this->get(false) 。 input函数调用 : $this->get 函数末尾调用了 $this->input 函数,并将可控的 $this->get 传入。 过滤器获取 : $this->input 函数调用 $this->getFilter 取得过滤器,其中 $this->filter 的值是攻击者可控的。 代码执行 :在 filterValue 函数中, call_user_func 函数的 $filter 和 $value 参数都是可控的,导致代码执行。 完整利用链 入口点 : thinkphp/library/think/App.php:77 的 run 函数实例化Request类。 路由检测 :调用 routeCheck($request,$config) ,进而调用 Route::check 进行路由检测。 变量覆盖 :通过 method 函数覆盖 $this->filter 、 $this->method 、 $this->get 属性。 路由规则 :完整版比核心版多出的 think-captcha/src/helper.php 文件会调用 \think\Route::get 进行路由注册,改变 self::$rules 的值。 路由解析 :当攻击者控制 $method 为 get 时, $rules 的值就是captcha路由的规则,最终调用到 self::parseRule 函数。 命令执行 :最终调用Request类的 param 方法,完成利用链。 版本差异 ThinkPHP5.0.2-5.0.23 :可以使用同一个POC ThinkPHP5.0-5.0.1 :需要更改POC,因为 Route.php 的 rule 函数中对 $type 的处理不同(5.0-5.0.1转换为大写,5.0.2-5.0.23转换为小写) 补丁分析 在ThinkPHP5.0.24中,增加了对 $this->method 的判断,不再允许自由调用类函数。 安全建议 升级版本 :强烈建议用户升级到ThinkPHP5.0.24或更高版本 关闭debug模式 :避免遭受攻击 输入过滤 :对所有用户输入进行严格过滤和验证 最小权限原则 :运行环境使用最小必要权限 技术总结 该漏洞本质上是由于ThinkPHP框架中Request类对用户输入处理不当,导致攻击者可以控制函数调用和参数,最终实现远程代码执行。完整版特有的captcha路由组件为攻击提供了必要的路由规则,这也是核心版不受影响的原因。