环境搭建
MCMS 5.2.4:https://gitee.com/mingSoft/MCMS/tree/5.2.4/
利用 idea 打开项目
创建数据库 mcms,导入 doc/mcms-5.2.8.sql
修改 src/main/resources/application-dev.yml
中关于数据库设置参数
启动项目登录后台 http://localhost:8080/ms/login.do
,账户名:密码 msopen:msopen
漏洞分析
SQL注入
该cms的mybatis映射文件直接写在了dao层,由于${}
会有SQL注入问题,所以直接搜索${},发现query方法中,categoryId参数可能存在SQL注入
根据namespace可知该语句的映射接口类是net.mingsoft.cms.dao.IContentDao
<mapper namespace="net.mingsoft.cms.dao.IContentDao">
在IContentDao中并没有发现query方法,但他继承了IBaseDao
,而query就在其中
下面就要看哪里实现了query
方法,根据分层逻辑,业务层对应接口类为:net.mingsoft.cms.biz.IContentBiz
,而他的实现类是net.mingsoft.cms.biz.impl.ContentBizImpl
而其中没有调用该方法,所以向上找他的父类BaseBizImpl
接着找哪里调用了该方法,同样根据分层逻辑,找到了控制层的net.mingsoft.cms.action.web.ContentAction
,该层的接口为/cms/content
该类的list方法中,会调用contentBiz属性的query方法参数为content
- contentBiz是IContentBiz类型的,IContentBiz的实现类是ContentBizImpl,接着他的父类
BaseBizImpl
实现了query方法 - content属性是ContentBean类型的,而ContentBean的父类是CategoryEntity它定义了categoryId属性,并实现了对应的getter、setter方法
这里未对前端用户输入的参数进行过滤,另外该CMS全局也没有针对SQL注入的过滤,所以只需要传入categoryId参数,将查询语句闭合即可导致SQL注入
由于定义的是PostMapping,因此需要post传参
payload:
POST:categoryId=1' and updatexml(1,concat(0x7e,user(),0x7e),1) and '1
其它用${}的点,由于参数不可控故无法进行注入
文件上传
在net.mingsoft.basic.action.web.FileAction
提供了文件上传入口,并且路径文件名等都可控
跟进下边的upload()方法,主要是对文件的一些初始化操作,第一行设置了黑名单
而黑名单只限制了exe、jsp,可以用jspx绕过
编写一个上传入口
<form method="POST" action="http://127.0.0.1:8088/file/upload" enctype="multipart/form-data">
<input type="file" name="file">
<input type="rename" name="rename" value="false">
<input type="submit" name="submit">
</form>
成功上传jspx木马文件
解压压缩包getshell
net.mingsoft.basic.action.TemplateAction
通过fileUrl传入任意文件路径,对文件进行解压,在unzip方法中未对压缩包中的文件过滤
若我们通过上边的文件上传,传上去一个带有jsp木马的zip压缩包,即可通过该利用点解压出jsp的shell文件
先上传个shell.zip
在访问指定路径进行解压,成功获取到jsp shell
任意文件删除
net.mingsoft.basic.action.TemplateAction
通过fileName可以指定目录删除,并且不像文件上传等对…/进行限制,这就导致我们可以通过…/进行任意目录删除
默认路径为/template/appid,因此若要删除upload目录,则需传参fileName=../../upload
任意文件写入
net.mingsoft.basic.action.TemplateAction
的writeFileContent()方法,没有进行过滤,可以往模板文件写入任何内容
- fileName:新文件名
- oldFileName:旧文件名
- fileContent:文件内容
若设置文件名为shell.jspx,内容为一句话木马,在随便找一个原有文件进行替换,即可getshell,但需要注意,checkFileType会进行文件类型就检测,仍然是不能为exe和jsp,这也是为什么文件名设为shell.jspx的原因
模板注入
该cms模版引擎是freemarker,该模版引擎是存在模版注入的,结合上边的任意写,可以将下边内容写入html页面中
<#assign value="freemarker.template.utility.Execute"?new()>${value("calc.exe")}
之后生成主页时,会渲染该文件执行命令
简单分析下源码
访问指定路由后,会调用generate()生成主页
其中主要是对map进行一些初始化操作,并通过rendering()进行渲染
最后调用process()进行渲染,造成代码执行