突破屏障:FreeMarker模板引擎中的SSTI远程代码执行漏洞分析
2023年,我在一个使用旧版FreeMarker模板引擎的应用程序中发现了一个重大漏洞。该版本存在服务器端模板注入漏洞,使我能够实现远程代码执行。在报告该问题后,公司立即采取了行动,通过实施沙箱机制来降低SSTI攻击的风险。然而,由于公司仍在使用FreeMarker版本<3.2.30,存在已知的漏洞利用方法可以绕过已实施的沙箱。
FreeMarker模板引擎概述
FreeMarker是一个广泛采用的模板引擎,主要用于基于Java的应用程序中,用于将表示逻辑与业务逻辑分离。它使开发人员能够创建结合静态内容和动态元素或占位符的模板。这些模板可以用来自不同来源的数据填充,包括Java对象或数据库查询,从而生成动态输出。
HTML转PDF转换流程
使用FreeMarker进行HTML到PDF转换的过程遵循结构化流程:
- HTML结构定义:在FreeMarker模板文件中定义所需的HTML结构
- FreeMarker指令:使用FreeMarker指令动态填充HTML模板数据
- 指令块:在FreeMarker指令中定义条件执行或迭代的代码块
- HTML渲染:通过将模板与提供的数据合并来渲染FreeMarker模板
- HTML到PDF转换:使用合适的转换工具将HTML输出转换为PDF文档
漏洞发现过程
在应用程序测试阶段,我观察到使用了<#if>
、<#list>
、</#list>
和</#else>
等标签。这些标签提示了应用程序使用的底层技术。经过进一步调查,发现应用程序正在使用FreeMarker模板引擎。
初始测试
我使用以下代码片段评估模板引擎的行为:
|
|
版本确认
通过以下代码确认引擎版本:
|
|
结果显示引擎版本低于2.3.30,存在SSTI漏洞。
漏洞利用
基本Payload构造
freemarker.template.utility.Execute
类提供了执行外部命令的能力:
|
|
沙箱绕过技术
公司实施沙箱后,需要构造更复杂的Payload:
|
|
技术细节分析
类加载器操作
- 通过
article.class.protectionDomain.classLoader
获取类加载器 - 使用反射加载
ObjectWrapper
和Execute
类
字段访问和实例创建
- 获取
DEFAULT_WRAPPER
静态字段值 - 创建新的包装器实例并执行命令
结论
该漏洞演示了即使实施了安全措施,如果使用的软件版本存在已知漏洞,攻击者仍然可能通过精心构造的Payload绕过防护机制。及时更新软件版本和实施多层次的安全防护至关重要。
感谢Bhavuk Jain的审阅。