最近在学习Java代码审计,找了一个Java写的CMS练练手
前言
最近在学习Java代码审计,找了一个Java写的CMS练练手
环境搭建
本次审计为MCMS 5.2.4版本:https://gitee.com/mingSoft/MCMS/tree/5.2.4/
目前官方已更新至5.2.5版本:https://gitee.com/mingSoft/MCMS/tree/5.2.5/
下载该CMS源码压缩包,解压后使用IDEA打开,修改下配置文件中数据库配置信息
在MySQL中创建一个数据库,然后将MCMS-5.2.4/doc/mcms-5.2.4.sql
文件导入数据库中
该CMS是基于SpringBoot框架的,SpringBoot内置了Tomcat,我们可以直接启动运行项目,下面来说说如何使用外置Tomcat运行该项目
编辑该CMS的pom.xml文件,修改打包方式为war包
<packaging>war</packaging>
在pom.xml文件中添加如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
修改启动类 src\main\java\net\mingsoft\MSApplication.java
@SpringBootApplication(scanBasePackages = {"net.mingsoft"})
@MapperScan(basePackages={"**.dao","com.baomidou.**.mapper"})
@ServletComponentScan(basePackages = {"net.mingsoft"})
public class MSApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MSApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MSApplication.class, args);
}
}
在项目结构中添加构件方式
新建一个Tomcat的运行配置
最后点击运行启动项目
漏洞分析
SQL注入
该CMS是使用MyBatis框架来进行数据库操作的,我们知道在MyBatis框架中配置SQL语句使用 ${}
写法拼接参数是容易产生SQL注入的。
根据CMS目录结构,我们可以知道MyBatis的SQL映射文件都放在dao目录下
使用快捷键Ctrl+Shift+F在当前路径下搜索关键字 $,勾选搜索XML后缀的文件
在搜索出来的结果中,我们可以看到在 src\main\java\net\mingsoft\cms\dao\IContentDao.xml 文件中配置的select查询语句使用 ${}
写法来拼接categoryId参数
这里select标签的id属性为query,即对应的调用方法为query方法,接下来我们来看映射接口类的该方法的定义,这里XML映射文件对应的映射接口类为 net.mingsoft.cms.dao.IContentDao
注意我们直接在 IContentDao 接口类中是看不到query方法的定义的,IContentDao 接口类是继承自 net.mingsoft.base.dao.IBaseDao 类的,query方法是父类定义的方法
根据分层架构设计,我们继续看业务层的代码,这里对应的是 net.mingsoft.cms.biz.IContentBiz 接口类,我们需要去看它的接口实现类 net.mingsoft.cms.biz.impl.ContentBizImpl,同样 ContentBizImpl 类继承了 net.mingsoft.base.biz.impl.BaseBizImpl 类,父类中定义了 query 方法
在代码中可以看到在这个query方法是调用了Dao层的query方法
接下来我们去看控制层的代码,对应的是net.mingsoft.cms.action.web.ContentAction 类,在该类的 list 方法中
可以接收前端用户输入的categoryId参数,这里前端传递的参数会自动对应到ContentBean对象的属性,所以用户输入的categoryId参数会对应到content对象的categoryId属性,接下来调用了query方法传递了用户输入的参数,这里未对前端用户输入的参数进行过滤,另外该CMS全局也没有针对SQL注入的过滤,所以是存在SQL注入漏洞的。
漏洞复现
直接访问接口URL:http://localhost:8080/ms_mcms_war_exploded/cms/content/list
POST提交如下payload:
categoryId=1' and updatexml(1,concat(0x7e,user(),0x7e),1) and '1
可以看到在报错信息中显示了当前数据库用户信息
文件上传
黑名单校验缺陷绕过
第一处文件上传:上传文件后缀名黑名单校验不严,可上传jspx后缀的文件,该文件类型是可以在Tomcat容器中被正常解析运行的
文件上传接口定义在 net\mingsoft\basic\action\web\FileAction.java 文件的 upload 方法中
在方法中接收用户上传的文件,最后又调用父类BaseFileAction中定义的 upload方法来处理上传文件
可以看到在方法的开头定义了一个数组,用来存储要过滤掉的文件类型,这里也就是采用黑名单的方式来进行校验上传文件后缀名。
我们来看看过滤掉了哪些文件类型,uploadFileDenied 其值为配置文件中 ms.upload.denied 项的值
查看配置文件,可以看到该CMS默认仅配置过滤 .exe .jsp 后缀名,没有考虑 .jspx 这种情况,所以是存在缺陷的
在upload方法接下来获取了上传文件的后缀名,在下面的代码中采用黑名单校验
过滤存在缺陷,导致可以上传 jspx 后缀的文件拿shell
漏洞复现
构造上传页面,该上传接口无需登录即可访问
<form method="POST" action="http://localhost:8080/ms_mcms_war_exploded/file/upload" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="submit">
</form>
上传一个jspx的冰蝎马
使用冰蝎连接我们的shell
压缩包上传解压拿Shell
第二处文件上传:程序提供了zip包解压的功能,未对压缩包中的文件进行校验,可上传包含jsp文件zip压缩包拿shell
解压zip模版文件接口定义在 net\mingsoft\basic\action\TemplateAction.java 文件中
在方法中使用 request.getParameter() 方法接收前端用户输入的fileUrl参数,接下来调用unzip()方法进行处理,该方法定义在同文件的第529-571行代码处
在unzip方法中是未过滤压缩包中文件后缀名不符合要求的文件
漏洞复现
首先将恶意jsp文件压缩成zip文件,然后通过上传接口上传该zip文件,上传成功后,访问zip包解压功能接口解压我们上传的压缩包,该接口需要登录后访问
使用冰蝎连接我们的shell
任意文件删除
程序提供了删除模板文件的接口,定义在 net\mingsoft\basic\action\TemplateAction.java 第232-248 行代码处
在delete方法中使用 request.getParameter() 方法接收前端用户输入的fileName参数,直接拼接路径,没有过滤 ../,最后调用 org.apache.commons.io.FileUtils类的deleteDirectory()方法,方法用于删除目录及其下面的所有文件。我们可以通过路径跳转符 ../ 来控制删除的路径,达到删除任意目录和文件的目的。
漏洞复现
删除upload目录及其下面的所有文件
模板注入
该CMS使用的模版引擎是freemarker,该模版引擎是存在模版注入的
登录管理后台,在后台模板管理界面,是可以修改模板文件内容的
插入命令执行的Payload
<#assign ex="freemarker.template.utility.Execute"?new()>
${ ex("calc") }
点击保存,点击左侧菜单栏中的内容管理 -> 静态化
点击生成主页
可以看到成功触发命令执行的Payload,弹出计算器
修改模板文件的功能代码定义在 net\mingsoft\basic\action\TemplateAction.java 文件中
可以看到对文件内容是没有进行过滤,可以往模板文件写入任何内容
生成主页功能的代码定义在 src\main\java\net\mingsoft\cms\action\GeneraterAction.java 文件中
在方法的最后调用了 CmsParserUtil 类 generate() 方法,跟进该方法
在方法中又调用了 ParserUtil 类的 rendering() 方法,而在这个方法中对模板文件进行解析加载,最后返回生成的内容。
在对模板渲染的过程中,执行了我们插入的恶意代码,触发命令执行。
总结
审计分析了该CMS的SQL注入、文件上传、任意文件删除、模板注入漏洞,在审计分析的过程中对Java代码审计有了更深的理解,提高审计技巧还是要多多练习才行!
- 本文作者: 好家伙
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/998
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!