【Java代码审计】OFCMS 1.1.3 审计

0x00 前言

看 版本 看 控制器 看 过滤器
https://forum.butian.net/share/1229
从补天看到的java 代码审计文章,跟着学习复现。

0x01 环境搭建

1.1 cms下载地址

https://gitee.com/oufu/ofcms/tree/V1.1.3/

1.2 idea部署项目

https://blog.csdn.net/Alexz__/article/details/116229266
https://forum.butian.net/share/1229
https://blog.csdn.net/Alexz__/article/details/116272080?spm=1001.2014.3001.5502

感谢两位师傅的笔记

1.3 服务启动成功

在这里插入图片描述

1.4 程序自动安装(失败)

在这里插入图片描述

在这里插入图片描述
爆出语法错误

1.5 尝试手动部署 (成功)

1.5.1 创建库导入.sql文件

首先在MySQL中创建空的ofcms数据库,然后将 ofcms-V1.1.3/doc/sql/ofcms-v1.1.3.sql文件导入到自己创建的数据库中

在这里插入图片描述

在这里插入图片描述

1.5.2 修改数据库配置文件并改名

将数据库配置文件ofcms-V1.1.3/ofcms-admin/src/main/resources/dev/conf/db-config.properties文件名修改为db.properties,然后修改文件中的数据库配置信息
在这里插入图片描述
在这里插入图片描述

1.5.3 重新启动项目

重新启动项目

在这里插入图片描述

1.5.4 访问后台

,访问程序后台地址:
http://localhost:8080/ofcms_admin_war/admin/index.html

默认账号和密码:admin/123456
在这里插入图片描述

0x02 漏洞挖掘

拿到框架 先看

  1. pom.xml的依赖 dependency
  2. ofcms-V1.1.3\ofcms-admin\src\main\webapp\WEB-INF\web.xml 过滤器 filter
  3. 全局搜索关键字 配合 网页 功能点灰盒 审计

2.1 sql注入

2.1.1 漏洞位置

后台->系统设置->代码生成->增加 可以输入sql语句
在这里插入图片描述
在这里插入图片描述

2.1.2 定位代码

对应控制器处理方法为
com.ofsoft.cms.admin.controller.system.SystemGenerateController类的create()方法
在这里插入图片描述

2.1.3 分析传参处理

在create方法中 先用getPara()方法 获取用户的输入sql的值
该方法位于 com.jfinal.core.Crontroller类中
在这里插入图片描述
getPara方法 就是使用request.getParameter(name)来获取http协议提交过来的数据 返回string类型的数据
这里并没有对用户输入的内容进行过滤

再看create方法,紧接着调用Db.update(sql); 方法执行输入的sql语句,跟进方法
跟踪到
com.jfinal.plugin.activerecord.DbPro类的update方法执行的sql语句
在这里插入图片描述
看到这里使用了预编译的方法,但是我们可以直接输入整条sql语句执行,不使用占位符(?, ?, ?),所以这里预编译处理将起不到作用。

2.2.4 payload

update of_cms_link set link_name=updatexml(1,concat(0x7e,(user())),0) where link_id = 4

在这里插入图片描述
在这里插入图片描述

从响应包可以看到SQL语法报错信息,在报错信息中显示了当前数据库用户信息

2.2 SSTI模板注入

在pom.xml文件的时候发现存在模引擎freemarker的包依赖信息,该模模板引擎存在ssti模板注入。
https://www.cnblogs.com/Eleven-Liu/p/12747908.html

在这里插入图片描述

2.2.1 漏洞位置

后台->模板设置->模板文件->模板目录->修改index.html

2.2.2 定位代码

对应的控制器处理方法为 com.ofsoft.cms.admin.controller.cms.TemplateController类的save方法

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();
    }

2.2.3 分析传参处理

我们修改的模板在 file_content
在这里插入图片描述
使用String fileContent =getRequest().getParameter(“file_content”); 接收我们输入的file_content参数内容,
fileContent = fileContent.replace("<", “<”).replace(">", “>”);
将 内容中的 &lt 和&gt 替换为< 和 > (即html解码)
File file = new File(pathFile, fileName);
FileUtils.writeString(file, fileContent);
将内容写入原来的文件名中。
发现并没有做任何的过滤。

2.2.4 payload

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

在管理后台修改 index.html 模板文件的内容,插入我们的payload并保存

在这里插入图片描述

访问首页 http://localhost:8080/ofcms_admin_war/
弹出计算器

在这里插入图片描述

2.3 文件上传

2.3.1 漏洞位置

后台->模板设置->模板文件->模板目录->修改index.html

2.3.2 定位代码

在 com.ofsoft.cms.admin.controller.cms.TemplateController类的save方法中还存在任意文件上传漏洞

2.3.3 分析传参

在这里插入图片描述
可以看到对 res_path dirs file_name file_content 参数 都是用户输入的 可以控制的 并且没有进行任何的过滤处理。

我们就可以抓包
对文件名修改 或者 添加…/ 跳转目录 在static静态资源目录下 写下js马
文件内容 进行 修改 写入恶意的jsp文件

2.3.4 上传冰蝎马

(1)抓包

在这里插入图片描述

(2)修改file_content 为冰蝎马的url编码

全url编码也可以
在这里插入图片描述

(3)修改file_name = …/…/…/static/shell.jsp

从index.html跳转到 static 需要三个…/
在这里插入图片描述
上传成功
在这里插入图片描述
在这里插入图片描述

2.3.5 冰蝎连接

连接成功
在这里插入图片描述

2.4 XXE漏洞

2.4.1 漏洞位置

在com.ofsoft.cms.admin.controller.ReprotAction类的expReport方法中
在这里插入图片描述

2.4.2 分析传参

(1)getParamsMap() 有传参
后边将输入的 值传递给 hm 和 jrxmlFileName
服务器接收用户输入的j参数后,拼接生成文件路径,这里没有进行过滤,可以穿越到其它目录,但是限制了文件后缀为jrxml。

在这里插入图片描述

(2)定位 getParamsMap()方法 没有过滤
在这里插入图片描述

(3)接下来会调用JasperCompileManager.compileReport()方法,跟进该方法看看
在这里插入图片描述

(4)在compileReport方法中又调用了JRXmlLoader.load()方法,继续跟踪
在这里插入图片描述
(5)一直跟到调用JRXmlLoader.loadXML()方法,在loadXML方法中调用了Digester类的parse解析我们的XML文档内容,默认是没有禁用外部实体解析的,所以这里是存在XXE漏洞的

2.4.3 漏洞利用

(1)利用之前的文件上传漏洞 写入一个 jrxml 后缀的文件
在这里插入图片描述

%xxe; ]>

在这里插入图片描述
(2)访问漏洞url xxe成功
http://localhost:8080/ofcms_admin_war/admin/reprot/expReport.html?j=…/…/static/xxe
在这里插入图片描述

2.5 存储型xss (前台新闻留言处)

2.5.1 漏洞位置

http://localhost:8080/ofcms_admin_war/
新闻中心- 任选一条新闻–下方的用户评论功能
在这里插入图片描述
在这里插入图片描述

2.5.2 分析代码传参

在save方法中 调用了getParamsMap方法,获取用户提交的所有参数。 又调用 getRealIp()方法 获取到ip,写入 params参数的comment_ip 键 中。
之后 调用 Db.update()方法将数据更新到数据库中。
没有对用户输入的数据进行过滤。

在这里插入图片描述

2.5.3 xss 测试

抓取用户评论的请求数据包,修改comment_content内容为

payload:<script>alert(1)</script>,提交数据包。
在这里插入图片描述
弹窗成功
在这里插入图片描述

0x03 总结

跟着 百度 用idea部署了 ofcms 项目 。
看着补天大佬文章学习 审计。
依赖 版本 控制器 过滤器
有无可控传参 有无过滤
getPara 获取请求中的参数
审计了
(1)sql注入 用了预编译方法,但是没有指定sql语句 及占位符 。 传参为整段sql语句,达成报错注入。
(2) ssti模板注入 因为freemarker 依赖 存在 该类注入。 并且 接收到传参后 没有进行 检查过滤 直接写入文件 导致存在该类漏洞。
(3) 任意文件上传,同ssti模板注入处一个功能点,没有对上传的任何参数 内容进行检查过滤,导致可以跳目录 上传 jsp马。
(4) xxe漏洞 在一处接收传参 点后 分析 loadXML方法中 调用了 Digester类的parse解析了 xml文档的内容。 并且 默认没有禁用外部实体解析 导致存在XXE漏洞。
(5)存储型漏洞 获取到用户输入的参数 直接写入数据库中 没有进行过滤。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ConstraintLayout是一种强大的布局方式,它可以用于在Android应用程序中创建复杂的布局。虽然可以使用XML来编写ConstraintLayout布局,但是同样可以使用Java代码来创建ConstraintLayout布局。 以下是使用Java代码创建ConstraintLayout布局的示例: 1. 首先,在您的项目中添加以下依赖项: ``` implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support.constraint:constraint-layout-solver:1.1.3' ``` 2. 创建一个新的ConstraintLayout对象并将其设置为Activity的根视图: ```java ConstraintLayout layout = new ConstraintLayout(this); setContentView(layout); ``` 3. 创建视图并将其添加到ConstraintLayout中。例如,创建一个TextView并将其添加到布局中: ```java TextView textView = new TextView(this); textView.setText("Hello, World!"); layout.addView(textView); ``` 4. 使用ConstraintSet对象定义约束。例如,将TextView位于布局的顶部和居中: ```java ConstraintSet set = new ConstraintSet(); set.constrainHeight(textView.getId(), ConstraintSet.WRAP_CONTENT); set.constrainWidth(textView.getId(), ConstraintSet.WRAP_CONTENT); set.connect(textView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0); set.connect(textView.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0); set.centerHorizontally(textView.getId(), ConstraintSet.PARENT_ID); set.applyTo(layout); ``` 5. 最后,将约束应用于布局: ```java set.applyTo(layout); ``` 这些是使用Java代码创建ConstraintLayout布局的基本步骤。您可以将这些步骤扩展到创建复杂的布局。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值