复现
https://tprce/index.php?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
漏洞分析
从payload入手,在app处下断点跟入, thinkphp/library/think/Request.php
681行,处理兼容模式的url请求:
在thinkphp/library/think/route/Rule.php
947行
可以看到其以/
分割,分割成模块/控制器/操作方法
路由解析,分发到对应模块/控制器/操作方法thinkphp/library/think/route/dispatch/Url.php
37行
thinkphp/library/think/route/dispatch/Module.php
84行 exec()
,实例化控制器
跟入该文件135行,该函数利用反射机制调用类方法,从而进行代码执行1
$data = $this->app->invokeReflectMethod($instance, $reflect, $vars);
-> thinkphp/library/think/Container.php
347行 invokeFunction()
:
到这里就已经任意代码执行了。
第一次接触反射机制,记录一下自己的理解,简单来说反射即根据目的地找来源,也就是根据已经实例化的对象来找其所属的类和类中的方法
以上为ThinkPHP5.1.x的rce分析,ThinkPHP5.0.x有一些差异,以后来填坑。
修复
路由解析过程中没有对控制器的命名规则进行检测,导致我们可以操作任意控制器,官方修复加了正则只允许字符传入:
参考: