突破壁垒:FreeMarker模板引擎中的SSTI漏洞实现远程代码执行
2023年,我在使用旧版FreeMarker模板引擎的应用中发现了一个重大漏洞。该版本存在服务器端模板注入(SSTI)漏洞,使我能够实现远程代码执行(RCE)。报告问题后,公司立即实施了沙箱机制来缓解SSTI攻击风险。但由于仍在使用FreeMarker 3.2.30以下版本,存在已知的沙箱绕过漏洞。本文将深入分析这一发现,重点展示绕过沙箱机制的具体步骤。
FreeMarker模板引擎工作原理
FreeMarker是一款广泛采用的模板引擎,主要用于Java应用中将表现逻辑与业务逻辑分离。它允许开发者创建包含静态内容和动态占位符的模板,这些模板可以通过Java对象或数据库查询等数据源填充,最终生成动态输出。
HTML转PDF的工作流程如下:
- HTML结构定义:在FreeMarker模板文件中定义HTML结构,包括内容、格式和样式
- FreeMarker指令:使用
<#
开头的指令动态填充数据,包括集合遍历、条件渲染和变量访问 - 指令块:在指令中定义可条件执行或循环的代码块
- HTML渲染:将模板与数据合并生成最终HTML
- PDF转换:使用HTML转PDF工具将生成的HTML转为PDF文档
漏洞发现过程
在应用测试阶段,我观察到<#if>
、<#list>
等标签的使用,确认应用使用了FreeMarker引擎。通过以下测试代码验证了引擎行为:
|
|
这些测试验证了引擎对特殊字符的处理、变量声明和基础运算能力。接着使用以下代码确认引擎版本:
|
|
确认版本低于2.3.30,存在SSTI漏洞(CVE-2021-25770)。
漏洞利用
freemarker.template.utility.Execute
类允许在模板中执行外部命令。构造如下payload可读取/etc/passwd
文件:
|
|
公司随后引入了沙箱环境作为防护措施。沙箱限制了模板引擎的操作能力,提供了安全执行环境。但旧版本仍存在绕过可能。
沙箱绕过技术
验证特殊字符处理和运算能力后,构建绕过payload:
|
|
该payload通过反射获取类加载器,加载关键类并最终执行命令,成功绕过沙箱防护。