0X00 前言
太菜了,比赛时没做出来这道题。现在复现一下,顺便整理一下模版注入相关的知识,和各位师傅一块探讨一下!
文中概念多来自互联网,如有侵权,联系删除!
0X01 什么是SSTI(模版注入)
1、 模版引擎
模板引擎(这里特指用于Web开发的模板引擎):是为了使用户界面
与业务数据
(内容)分离而产生的,它可以生成特定格式的文档,利用模板引擎来生成前端的html代码,模板引擎会提供一套生成html代码的程序,然后只需要获取用户的数据,然后放到渲染函数里,然后生成模板+用户数据的前端html页面,然后反馈给浏览器,呈现在用户面前。
模板引擎也会提供沙箱机制来进行漏洞防范,但是可以用沙箱逃逸技术来进行绕过。
2、ssti(模版注入)
SSTI 就是服务器端模板注入(Server-Side Template Injection)。
当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。
漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。
凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是,沙盒绕过只是由于模板引擎发现了很大的安全漏洞,然后模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎。
更详细的内容可以看看这位师傅的文章:https://www.cnblogs.com/bmjoker/p/13508538.html
0X02 JSP是模版引擎吗?
JSP是web开发最早期的模板引擎产品。
如果你在网上搜Spring Boot的教程,会发现模板引擎清一色用的Thymeleaf,为什么很少人用JSP?因为Spring Boot官方已经不推荐使用JSP了。但Spring Boot提供了多种模板引擎的支持(嵌入式容器JSP有限制,2010年后Velocity停止更新,所以JSP与Velocity两个不建议使用
)
springBoot支持的模板引擎有: Thymeleaf、FreeMarker、Velocity、Mustache、JSP、Groovy、Handlebars、Jade4j、Pebble、Thymol等等
因为这个文章主要来写hellospring
这个题目,所以我们先学习Pebble
模版!
0X03 Pebble模版
1、简介
Pebble是一款Java 模板引擎,开发他的灵感来自于Twig。它具有很强的模板延续性和易于阅读的语法;
2、数据绑定示例
在模板中,开发人员可以动态值定义静态内容和占位符。在运行时,模板将由其引擎处理以映射模板中的动态值引用。
1 | 你好{{Name}}! |
在确定Name的值,经过引擎处理后的输出就是
3、漏洞原因
在 Java 中各种表达式语言中利用模板注入的常用方法是使用类似于以下内容的代码:
1 | variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') |
基本上,Java中的每个对象都有一个称为 getClass()的方法,它可以通过检索特殊的 java.lang.class,轻而易举的获取任意 Java类的实例。因为它允许执行 OS 命令,下一步通常是获取 java.lang.Runtime 的实例。
1 | {{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }} |
0X04 hellospring复现
1、环境搭建
比赛时给的附件公众号发送hellospring
获取!
比赛给的是个jar包,直接解压在idea打开!
从META-INF\MANIFEST.MF
路径下我们可以看到使用的jdk版本!
我们配置到对应的环境,直接在虚拟机把项目跑起来!
说明:给的附件和远程环境中的不一样!我们需要根据配置文件和源码return ‘home’写一个home.pebble放在/tmp目录下,作为模板文件
1 |
|
成功访问到就说明环境搭建成功!
2、题目环境分析
给出了两个路由!
(1)根据参数x返回指定模板
(2)看名字应该是上传文件的
写了个过滤器,但是没有内容!
上传文件后,给文件重命名了
使用的是FileNameGenerator
这个工具类的general_time
方法。大概就是获取当前日期,然后改改变格式。拼接生成新的文件名!
写个demo瞅瞅,最后就是file_20231230_044928.pebble
这样的,很好构造!
3、目录穿越
pebble当中有两个loader一个是classpathloader,另一个是fileloader,优先会在classpath下尝试加载模板文件,如果寻找不到则使用fileloader尝试加载模板文件
但是题目中给出了后缀名的限制,导致了不能任意文件读取。
但是可以读取到.pebble的文件!我们写入一个类似文件测试一下!
4、思路
大胆的猜测一下出题人的思路!
- 存在目录穿越(只能读取.pebble后缀文件)
- 有一个上传文件的路由
大概思路就是通过上传点传一个.pebble的恶意文件,然后访问–>触发pebble模版注入漏洞,然后rce或者反弹shell拿flag!
5、本地复现
(1)找到一个比较新的利用方式:
https://github.com/Y4tacker/Web-Security/issues/3
大概思路:
1 | 1、老版本的exploit,通过Class.forName加载任意类,新版本中修复了 |
poc.xml
1 | <?xml version="1.0" encoding="UTF-8" ?> |
(2)python开个web服务,放poc.xml
(3)vps开启端口监听
(4)接下里就是上传啦!!
poc
1 | {% set y= beans.get("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory").resourceLoader.classLoader.loadClass("java.beans.Beans") %} |
访问/uploadFile
,yakit抓包,改成post请求,添加请求体
结合之前分析的重命名规则,我们就可以构造出文件名,但是注意是服务端的时间,我们的本地时间不一样
(5)结合之前分析的目录穿越访问!反弹shell。。
0X05 总结
其他的模版注入无非也就是:
服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的恶意的语句。
0X06 参考文章
https://www.cnblogs.com/bmjoker/p/13508538.html
https://kumamon.fun/server-side-template-injection-on-the-example-of-pebble/
https://tttang.com/archive/1692/#toc
https://blog.51cto.com/u_15585381/5277421
https://blog.tawnx.com/2022/07/25/SSTI/index.html
0X07 原文地址
转载自公众号:安服仔Yu9
原文地址:https://mp.weixin.qq.com/s/PNOpAnkyhWoXHXFFfE4_Sw