thinkphp版本:v5.0.5
下载地址 https://www.thinkphp.cn/down/870.html
poc:?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
带poc访问index.php以后经过初始化以后,流程执行到App类中的run方法
在一百多行左右对路由信息进行了处理,跟入进去



跟进到module方法
一直到354行出现关键位置,绿色的注释的就是tp官方的修复代码。



在Loader类中对传入的恶意类进行反射


反射执行类方法

获取到参数

反射执行方法 call_usser_func_array
参数phpinfo


到这里 phpinfo执行成功

漏洞调用堆栈

漏洞产生的主要原因就是think框架应该是通过/
,来分割路由,但是因为没有考虑的情况,导致可以通过路由传入thinkApp这样的任意类, 然后再反射执行invokeFunction方法实现任意函数的执行。
官方的修复方法,也就是对路由里面的特殊字符串进行过滤。
漏洞修复方案:
Thinkphp v5.0.x补丁:
library/think/App.php
$controller = strip_tags($result[1] ?: $config['default_controller']);
后添加
if (!preg_match('/^[A-Za-z](w)*$/', $controller)) {
throw new HttpException(404, 'controller not exists:' . $controller);
}
Thinkphp v5.1.x补丁:
library/think/route/dispatch/Module.php
$controller = strip_tags($result[1] ?: $this->rule->getConfig('default_controller'));
替换为
$controller = strip_tags($result[1] ?: $this->rule->getConfig('default_controller'));
if (!preg_match('/^[A-Za-z](w)*$/', $controller)) {
throw new HttpException(404, 'controller not exists:' . $controller);
}