实战讲解 Java代码审计之 FreeMarker模版注入漏洞

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

闪石星曜CyberSecurity 2025-06-10 08:38

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

本篇为代码审计系列SSTI服务器端模板注入漏洞理论篇-FreeMarker第八篇,看完本篇你将掌握关于FreeMarker模版注入漏洞的代码视角原理剖析、基础挖掘漏洞核心能力,看完如有技术错误欢迎评论区指正。

文章引用了FreeMarker官方介绍:http://freemarker.foofun.cn/index.html
– FreeMarker概念

  • FreeMarker引擎

  • FreeMarker模版

  • 业务视角FreeMarker流程

  • 漏洞视角FreeMarker漏洞原理及防范

  • OFCMS 实战审计案例

FreeMarker模版注入漏洞

FreeMarker

FreeMarker由引擎+模版构成完整的业务流程,FreeMarker引擎加载Template+Javaobjects,Template模版为HTML模版。如下图所示:

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

1.1FreeMarker引擎

FreeMarker 是一款模板引擎:引擎用于加载FreeMarker模版与模版中的数据通过将模板文件与数据模型结合,生成最终的输出HTML内容。

1.2FreeMarker模版

模板编写为FreeMarker Template Language (FTL)。后端业务代码准备数据在填充在已经固定的HTML模版中,比如数据库查询和业务运算,之后模板显示数据库查询的结果或运算的结果数据。模版中包含如下内容:

文本:文本会照着原样来输出。

插值:这部分的输出会被计算的值来替换。插值由${and}所分隔的(或者#{and}

FTL标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。

注释:注释和HTML的注释也很相似,但它们是由<#–和–>来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

业务视角FreeMarker场景与流程

FreeMarker使用场景如下
– Web 开发
:与 Spring MVC、Struts 等框架集成,生成动态 HTML 页面

  • 电子邮件模板
    :生成动态邮件内容

  • 配置文件生成
    :根据环境或需求生成配置文件

  • 代码生成工具
    :在开发工具中生成代码文件

2.1FreeMarker使用流程

  • 引入FreeMarker模版

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

  • 引入FreeMarker配置
    :在SpringBoot中配置FreeMarkersrc/main/resources/application.properties

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

  • 引入FreeMarker配置
    :如为Spring MVC使用中applicationContext.xml编写即可

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

  • 引入FreeMarker配置
    :如为其他Web框架初始化模版配置,创建Configuration实例进行配置

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

  • FreeMarker模版文件
    :编写模版.ftl文件:(不一定非得是.ftl也可能是.html)

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

编写业务层代码:
– 创建数据模型
:可以使用 java.lang 和 java.util 包中的类,还有用户自定义的Java Bean来构建数据对象

  • 获取模版:
    freemarker.template.Template实例。典型的做法是从 Configuration 实例中获取一个Template 实例

  • 合并模版和数据模型
    :数据模型+模板=输出

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

漏洞视角Freemarker模版原理及防范

3.1漏洞原理

Freemarker模版注入漏洞属于SSTI类漏洞,对于模板注入漏洞成因是在模板引擎渲染模板

文件时,由于模板文件中存在内建危险函数且可执行,模版引擎进行解析后造成的攻击

3.2漏洞触发场景

触发Freemarker的漏洞的场景大致为:
– 文件上传
:用户的使用上传包含危险内建函数的FreeMarker模版,并且可访问渲染后的文件

  • 文件编辑
    :用户可以修改为包含内建函数的模版文件,访问该模版后造成的攻击

3.3漏洞触发条件

3.3.1上传or修改.ftl模版文件

添加模版、更新模版内容等功能可进行修改,其中FreeMarker已经内置的方法StringTemplateLoader下的putTemplate()方法

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

以下图片来源为FreeMarker官方文档(http://freemarker.foofun.cn/ref_builtins_expert.html#ref_builtin_new)

api函数

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

new 函数可以创建一个继承自 freemarker.template.TemplateModel 类的变量

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

freemarker.template.utility包中存在三个符合条件的类,分别为Execute类、ObjectConstructor类、JythonRuntime类最终实现了TemplateModel类。

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

3.3.2Freemarker模版漏洞定位关键词

freemarker、<#assign>、<#include>、<#if>、<#list>、<#macro>

OfCms实战审计案例

此篇OfCms为分析FreeMarker漏洞进行白盒与黑盒结合方式审计,通常模版文件上传、编辑等功能可能会存在模版注入漏洞。部署后从系统功能视角到源代码定位及抓包调试进行讲解。

抓包使用内建函数测试即

白盒审计流程

– 项目组件分析
:Pom.xml引入模版引擎依赖

  • 框架分析
    :Spring、Spring Boot、其他框架渲染模版引擎配置对应关键词定位

  • 渲染模版
    :定位渲染文件是否可控

  • Poc测试
    :抓包使用内建函数测试即可

黑盒审计流程

– 上传/编辑功能
:是否可编辑前端模版文件

  • 接口定位源代码
    :查看模版文件是否存在过滤或转义等处理

  • Poc测试
    :定位渲染文件是否可控

4.1OfCms漏洞项目部署

Gitee:https://gitee.com/oufu/ofcms/repository/archive/V1.1.2.zip

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

直接打开Pom.xml引入依赖即可,查看Web框架使用的jfinal而非Spring或SpringBoot

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

FreeMarker显示2.3.21版本

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

导入数据库文件,并修改数据库账号密码,成功启动项目

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

4.2白盒源代码漏洞分析

jfinal白盒定位关键词

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

  • TempleteUtile.java中用来初始化模版引擎,查看源代码后发现该process方法会进行模版引擎渲染

process(String templatefile, Map param) 方法使用模板文件名和参数 map 生成字符串输出。处理模板后,去除 HTML/XML 中标签之间的空白字符。

process(String templatefile, Map param, File file) 方法

将模板处理结果写入指定的文件中,使用 UTF-8 编码保存

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

templatefile注释来看为传入的模版文件并直接渲染,查看是否模版文件可控

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

向上查找参数均发现不可控,转换思路进行黑盒挖掘尝试

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

4.3黑盒项目功能触发漏洞分析

往往很多漏洞黑盒要比白盒方便很多,因为功能非常明显找到模版文件保存功能

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

抓包定位接口

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

功能定位分析:发现只有一个特殊符号转义但对保存为恶意模版文件并没起到作用

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

确定模版文件参数:file_content_

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

Payload插入,修改为恶意模版文件

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

保存模版文件中,毫无过滤

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

访问404页面,执行成功

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

分析如何404模版文件解析流程

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

向上追踪定位到FreeMarkerRender类:

`FreeMarkerRender是一个基于 JFinal 框架的 FreeMarker 模板渲染器,主要功能如下:

封装 FreeMarker 配置:通过静态变量 config初始化 FreeMarker 的配置;

提供配置方法:setProperty()、setSharedVariable()、setProperties()用于设置模板参数和共享变量;

模板路径设置:setTemplateLoadingPath()` 设置模板加载路径;

初始化配置:init()方法完成模板引擎的各项基础设置(编码、异常处理、日期格式等);

渲染视图:render() 方法将数据模型与模板合并输出 HTML 到响应;

内容类型控制:getContentType()返回默认文本类型为 HTML + 编码。

实战讲解 Java代码审计之 FreeMarker模版注入漏洞

END