对Java CMS的审计的一次尝试
字数 2109 2025-08-26 22:11:35

Java CMS安全审计实战教学文档

1. 环境搭建

  1. 项目导入

    • 使用IDEA开发工具导入项目
    • MySQL中新建ofcms数据库
  2. 数据库配置

    • 修改ofcms-admin模块中的配置文件:
      • 路径:src/main/resources/conf/dev/conf/db-config.properties
      • 重命名为db.properties
      • 配置JDBC连接信息
  3. 数据库初始化

    • 两种方式可选:
      • 手工方式:执行doc/sql文件夹中的SQL文件
      • 自动方式(本文选择手工方式)
  4. 启动项目

    • 使用Tomcat容器启动项目
    • 管理后台默认凭证:admin/123456

2. 组件分析

2.1 FreeMarker模板引擎

  • 存在模板注入(SSTI)风险
  • 攻击场景:通过修改模板文件实现攻击

3. 漏洞审计

3.1 FreeMarker模板注入(SSTI)

漏洞位置

  • 后台模板编辑功能
  • 相关控制器:com.ofsoft.cms.admin.controller.cms.TemplateController#save

攻击流程

  1. 请求处理流程

    • Tomcat容器处理请求
    • Shiro组件进行鉴权(访问/admin路径)
    • 返回Tomcat进行Filter链调用
    • 最终调用save方法
  2. 关键代码分析

    // 获取res_path参数值并与"res"比较
    // 根据比较结果获取模板文件目录(resource或webapp下)
    // 获取模板文件相对路径(dirs)
    // 拼接模板文件目录和相对路径
    // 获取模板文件名和内容
    // 将编码复原为<>等符号
    // 调用FileUtils#writeString写入文件
    
  3. 漏洞利用

    • 修改模板文件内容为恶意代码
    • 例如:${ex("calc")}(执行计算器)
    • 访问404.html触发模板渲染
  4. 调用栈分析

    • 渲染流程最终调用Execute#exec执行命令
    • 关键调用链:
      FreeMarkerRender#render
      → Environment#process
      → MixedContent#accept
      → DollarVariable#accept
      → Expression#evalAndCoerceToString
      → Execute#exec
      

防御措施

  1. 添加WAF进行拦截
  2. 使用TemplateClassResolver限制可解析类
    • 文档参考:https://freemarker.apache.org/docs/api/freemarker/core/TemplateClassResolver.html
  3. 注意?api配置可能导致绕过

3.2 任意文件上传

漏洞位置

  • 模板编辑功能中的文件保存操作
  • 同一TemplateController#save方法

漏洞分析

  1. 关键问题

    • 无过滤措施:
      • 无路径穿越防护
      • 无文件后缀限制
      • 无危险函数检测
  2. 利用方式

    • 通过控制dirs参数实现目录穿越
    • 指定恶意文件名(如shell.jsp
    • 写入Web目录实现webshell上传

防御措施

  1. 禁止目录穿越
  2. 严格检测文件后缀名
  3. 部署webshell查杀机制

3.3 存储型XSS

漏洞位置

  • 评论功能
  • 相关控制器:CommentApi#save

漏洞分析

  1. 处理流程

    • 调用getParamsMap获取评论内容
    • 添加评论者IP地址
    • 执行Db.update方法存入数据库
  2. SQL处理细节

    • 使用预编译SQL防止注入
    • 但未对评论内容进行XSS过滤
    • 导致存储型XSS
  3. 影响范围

    • 几乎所有可评论位置都存在此漏洞
    • 新闻页面渲染时会执行恶意脚本

防御措施

  1. 严格校验写入数据库的内容
  2. 实现HTML实体编码
  3. 使用专业XSS过滤库

3.4 CSRF漏洞

漏洞表现

  • 所有操作均未使用CSRF-Token防护
  • 可通过构造恶意页面实现跨站请求伪造

防御措施

  1. 验证HTTP Referer字段
  2. 添加CSRF-Token机制
  3. HTTP头中添加自定义属性验证

3.5 SQL注入

漏洞位置

  • 后台代码生成功能
  • 相关控制器:SystemGenerateController#create

漏洞分析

  1. 执行流程

    • 获取sql参数值
    • 调用Db.update执行SQL
    • 通过DbPro#update方法最终执行
  2. 可利用的SQL类型

    • UPDATE
    • INSERT
    • DELETE
  3. 利用方式

    • 使用报错注入技术
    • 示例Payload:
      update of_cms_link set link_name = updatexml(1,concat(0x7e,(user())),0) where link_id = 4
      
  4. 问题根源

    • 虽然使用预编译但未发挥应有作用
    • 直接拼接用户输入执行

防御措施

  1. 严格过滤用户输入
  2. 使用最小权限数据库账户
  3. 实现SQL关键字过滤

4. 总结

4.1 漏洞汇总表

漏洞类型 风险等级 位置 防御建议
FreeMarker SSTI 高危 模板编辑功能 限制模板解析类
任意文件上传 高危 模板保存功能 路径/后缀名限制
存储型XSS 中危 评论功能 输入过滤/输出编码
CSRF 中危 全站操作 添加CSRF-Token
SQL注入 高危 代码生成功能 输入过滤/权限控制

4.2 通用防御建议

  1. 输入验证

    • 所有用户输入都应视为不可信的
    • 实现白名单验证机制
  2. 输出编码

    • 根据输出上下文进行适当编码
    • HTML/JavaScript/URL等不同场景使用不同编码
  3. 安全配置

    • 组件安全配置(如FreeMarker的TemplateClassResolver)
    • 最小权限原则
  4. 安全开发

    • 使用安全框架提供的基础功能
    • 定期安全代码审计
  5. 防御纵深

    • WAF防护
    • 定期漏洞扫描
    • 安全监控与日志审计
Java CMS安全审计实战教学文档 1. 环境搭建 项目导入 : 使用IDEA开发工具导入项目 MySQL中新建ofcms数据库 数据库配置 : 修改 ofcms-admin 模块中的配置文件: 路径: src/main/resources/conf/dev/conf/db-config.properties 重命名为 db.properties 配置JDBC连接信息 数据库初始化 : 两种方式可选: 手工方式:执行 doc/sql 文件夹中的SQL文件 自动方式(本文选择手工方式) 启动项目 : 使用Tomcat容器启动项目 管理后台默认凭证: admin/123456 2. 组件分析 2.1 FreeMarker模板引擎 存在模板注入(SSTI)风险 攻击场景:通过修改模板文件实现攻击 3. 漏洞审计 3.1 FreeMarker模板注入(SSTI) 漏洞位置 后台模板编辑功能 相关控制器: com.ofsoft.cms.admin.controller.cms.TemplateController#save 攻击流程 请求处理流程 : Tomcat容器处理请求 Shiro组件进行鉴权(访问 /admin 路径) 返回Tomcat进行Filter链调用 最终调用 save 方法 关键代码分析 : 漏洞利用 : 修改模板文件内容为恶意代码 例如: ${ex("calc")} (执行计算器) 访问404.html触发模板渲染 调用栈分析 : 渲染流程最终调用 Execute#exec 执行命令 关键调用链: 防御措施 添加WAF进行拦截 使用 TemplateClassResolver 限制可解析类 文档参考:https://freemarker.apache.org/docs/api/freemarker/core/TemplateClassResolver.html 注意 ?api 配置可能导致绕过 3.2 任意文件上传 漏洞位置 模板编辑功能中的文件保存操作 同一 TemplateController#save 方法 漏洞分析 关键问题 : 无过滤措施: 无路径穿越防护 无文件后缀限制 无危险函数检测 利用方式 : 通过控制 dirs 参数实现目录穿越 指定恶意文件名(如 shell.jsp ) 写入Web目录实现webshell上传 防御措施 禁止目录穿越 严格检测文件后缀名 部署webshell查杀机制 3.3 存储型XSS 漏洞位置 评论功能 相关控制器: CommentApi#save 漏洞分析 处理流程 : 调用 getParamsMap 获取评论内容 添加评论者IP地址 执行 Db.update 方法存入数据库 SQL处理细节 : 使用预编译SQL防止注入 但未对评论内容进行XSS过滤 导致存储型XSS 影响范围 : 几乎所有可评论位置都存在此漏洞 新闻页面渲染时会执行恶意脚本 防御措施 严格校验写入数据库的内容 实现HTML实体编码 使用专业XSS过滤库 3.4 CSRF漏洞 漏洞表现 所有操作均未使用CSRF-Token防护 可通过构造恶意页面实现跨站请求伪造 防御措施 验证HTTP Referer字段 添加CSRF-Token机制 HTTP头中添加自定义属性验证 3.5 SQL注入 漏洞位置 后台代码生成功能 相关控制器: SystemGenerateController#create 漏洞分析 执行流程 : 获取 sql 参数值 调用 Db.update 执行SQL 通过 DbPro#update 方法最终执行 可利用的SQL类型 : UPDATE INSERT DELETE 利用方式 : 使用报错注入技术 示例Payload: 问题根源 : 虽然使用预编译但未发挥应有作用 直接拼接用户输入执行 防御措施 严格过滤用户输入 使用最小权限数据库账户 实现SQL关键字过滤 4. 总结 4.1 漏洞汇总表 | 漏洞类型 | 风险等级 | 位置 | 防御建议 | |---------|---------|------|---------| | FreeMarker SSTI | 高危 | 模板编辑功能 | 限制模板解析类 | | 任意文件上传 | 高危 | 模板保存功能 | 路径/后缀名限制 | | 存储型XSS | 中危 | 评论功能 | 输入过滤/输出编码 | | CSRF | 中危 | 全站操作 | 添加CSRF-Token | | SQL注入 | 高危 | 代码生成功能 | 输入过滤/权限控制 | 4.2 通用防御建议 输入验证 : 所有用户输入都应视为不可信的 实现白名单验证机制 输出编码 : 根据输出上下文进行适当编码 HTML/JavaScript/URL等不同场景使用不同编码 安全配置 : 组件安全配置(如FreeMarker的TemplateClassResolver) 最小权限原则 安全开发 : 使用安全框架提供的基础功能 定期安全代码审计 防御纵深 : WAF防护 定期漏洞扫描 安全监控与日志审计