问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Java中SSTI漏洞分析
漏洞分析
SSTI:Server Side Template Injection,即服务端模板注入
0x00 前言 ======= SSTI:Server Side Template Injection,即服务端模板注入。 在web开发中,为了使用户界面与业务数据分离,提升开发效率,因此会使用模板引擎来生成一个标准的HTML文档用来数据的展示。 本文主要针对java中Velocity、FreeMarker以及Thymeleaf三个模板的注入漏洞进行分析 0x01 velocity ============= 1.1 Velocity简介 -------------- Apache Velocity是一个基于Java的模板引擎,它提供了一个模板语言去引用由Java代码定义的对象。Velocity旨在确保Web应用程序在表示层和业务逻辑层之间的隔离(即MVC设计模式)。 **语法概要** 在 Velocity 中所有的关键字都是以#开头的,而所有的变量则是以$开头 "#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等; "$"用来标识一个对象(或理解为变量);如$i、$msg、$TagUtil.options(...)等; "{}"用来明确标识Velocity变量; "!"用来强制把不存在的变量显示为空白; 1.2 漏洞利用 -------- 环境:java-sec-code(<https://github.com/JoyChou93/java-sec-code/>) 服务端代码:  访问/ssti/velocity?template=并提交payload  断点进行拦截提交的payload,并跟进Velocity.*evaluate方法进行分析*  继续跟进evaluate方法  RuntimeInstance类中封装了evaluate方法  继续跟进分析,可以看到parse方法对reader进行解析  跟进分析,可以看出进行一次判断,如果nodeTree不为空则进入render方法  继续跟进分析,多次循环后会进行execute方法下进行for循环,进行payload的遍历  遍历完成后命令成功执行  0x02 FreeMarker =============== 2.1 FreeMarker简介 ---------------- FreeMarker 是一款模板引擎:即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。  当需要一个类似Output的页面时,就可以利用FreeMarker模板代码来进行生成。 FreeMarker模板代码: ```java <html> <head> <title>Welcome</title> </head> <body> <h1>Welcome ${user}!</h1> </body> </html> ``` 模板文件存放在Web服务器上,就像通常存放静态HTML页面那样。当有人来访问这个页面, FreeMarker将会介入执行,然后动态转换模板,用最新的数据内容替换模板中 ${...} 的部分, 之后将结果发送到访问者的Web浏览器中。 FreeMarker模板注入主要利用freemarker.template.utility里面的Excute类来执行命令,利用FreeMarker中的内建函数new,new是用来创建一个确定的 TemplateModel 实现变量的内建函数,新建一个Excute类,并将需要执行的命令传入其中。 具体的payload的构造按照该内建函数的用法进行构造,可以参考[http://freemarker.foofun.cn/ref\_builtins\_expert.html#ref\_builtin\_new](http://freemarker.foofun.cn/ref_builtins_expert.html#ref_builtin_new),具体用法如下: ```python <#-- Creates an user-defined directive be calling the parameterless constructor of the class --> <#assign word_wrapp = "com.acmee.freemarker.WordWrapperDirective"?new()> <#-- Creates an user-defined directive be calling the constructor with one numerical argument --> <#assign word_wrapp_narrow = "com.acmee.freemarker.WordWrapperDirective"?new(40)> ``` 2.2 漏洞利用 -------- 服务端代码:  模板代码:  ```python payload:<#assign ex="freemarker.template.utility.Execute"?new()>${ ex("calc") } ``` 请求/hello获取模板,可以看出成功实现,对应数据提交到了模板中展示  构造payload,请求/template  post提交payload,注入恶意模板代码,并在for循环中进行断点调试  可以看出stringLoader,也就是StringTemplateLoader函数下的putTemplate通过key:value的形式获取到传入的payload,达到注入hello.ftl的效果  再访问/hello获取模板,达到恶意代码执行的效果。  0x03 Thymeleaf ============== 3.1 Thymeleaf简介 --------------- Thymeleaf是springboot官方推荐使用的java模板引擎,提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现[表单](https://so.csdn.net/so/search?q=%E8%A1%A8%E5%8D%95&spm=1001.2101.3001.7020)绑定、属性编辑器、国际化等功能。 **Thymeleaf简单表达式:** - 变量表达式: ${...} - 选择变量表达式: \*{...} - 消息表达式: #{...} - 链接网址表达式: @{...} - 片段表达式: ~{...} 简单的Thymeleaf模板代码 ```python <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Good Thymes Virtual Grocery</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" /> </head> <body> <p th:text="#{home.welcome}">Welcome to our grocery store!</p> </body> </html> ``` 3.2 漏洞利用 -------- 环境:spring-view-manipulation(<https://github.com/veracode-research/spring-view-manipulation/>) 服务端代码:  模板代码:  **漏洞利用方法一:** ```python payload:__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22calc%22).getInputStream()).next()%7d__::.x uri:/path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22calc%22).getInputStream()).next()%7d__::.x ```  进行数据提交,成功获取到提交的payload  进行跟进,在 org.thymeleaf.spring5.view 中的 ThymeleafView类中thymeleaf 在解析包含 :: 的模板名时,会将其作为表达式去进行执行  继续跟进,在StandarExpressionPreprocessor类中利用正则对\_\_(.\*?)\_\_进行匹配,也就是payload\_\_中间的内容  匹配处理完成后为${new.java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("calc").getInputStream()).next()}  继续跟进execute  可以看到是使用的SPEL 引擎,满足**(${SPEL})**::格式达到注入的效果  进入后成功执行代码  **漏洞利用方法二:** ```python payload:__$%7BT(java.lang.Runtime).getRuntime().exec(%22calc%22)%7D__::.x uri:/doc/__$%7BT(java.lang.Runtime).getRuntime().exec(%22calc%22)%7D__::.x ```  因为该请求无返回值,因此返回值无法作为模板名,这个时候传入的参数也就是payload便作为了视图名  进行跟进,在 org.thymeleaf.spring5.view 中的 ThymeleafView类中thymeleaf 在解析包含 :: 的模板名时,会将其作为表达式去进行执行  继续跟进,在StandarExpressionPreprocessor类中利用正则对\_\_(.\*?)\_\_进行匹配,也就是payload\_\_中间的内容,匹配处理完成后为${T(java.lang.Runtime).getRuntime().exec(%22calc%22)}  可以看到是使用的SPEL 引擎,满足**(${SPEL})**::格式达到注入的效果 
发表于 2022-06-15 09:45:35
阅读 ( 8676 )
分类:
漏洞分析
1 推荐
收藏
0 条评论
请先
登录
后评论
阿蓝
7 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!