SSTI模板注入
前言
模板引擎
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
模板引擎会提供一套生成HTML
代码的程序,只需要获取用户的数据放到渲染函数里,然后生成模板+用户数据的前端HTML
页面,就能反馈给浏览器,呈现在用户面前。
这是一个模板的例子:
1 | <html> |
对应的后端代码逻辑是:
1 | $templateEngine = new TemplateEngine(); |
SSTI(服务器端模板注入)
SSTI
(Server-Side Template Injection)就是服务器端模板注入。
SSTI
的本质也是注入,
SQL注入
在本应该插入正常数据的地方插入了SQL
语句,破坏了原本的SQL
语句的格式,从而执行攻击者想要的SQL
语句。
注入就是格式化字符串漏洞的一种体现。
利用漏洞可以对服务端进行输入,服务端在接收用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了信息泄露
、代码执行
、GetShell
等问题。
各模板引擎的相关信息
SSTI模板注入基本原理
用户的输入作为模板变量
中的值
1 |
|
对这段代码输入<script>alert(welcome)</script>
,不会执行脚本中的代码,会进行HTML
编码转义,以原样输出,不会造成XSS
攻击。
用户的输入作为模板内容
的一部分
1 |
|
对这段代码模板输入<script>alert(welcome)</script>
,这段JavaScript
代码会作为模板内容的一部分并执行,会造成XSS
漏洞。
不同的模板有不同的语法,见本文各模板引擎相关信息
。
例题
题目基本信息
看题目名,可以知道是考察SSTI
相关知识。
解题步骤
查看网页的源代码
需要我们传入一个flag
参数。
同时可以看到这样一段注释:
1 | <!-- You know, in the flask, We often set a secret_key variable.--> |
可知,该网页使用的是Flask
框架,模板引擎使用的是Jingja2
。
在Flask
模板中,config
是Flask
模版中的一个全局对象,它包含了所有应用程序的配置值。会有一个SECRET_KEY
变量,根据这个提示,我们需要获取这个SECRET_KEY
。
接下来我们尝试用get
方式传入一段HTML
代码:
可以看到源码发生了改变,所以可以使用SSTI
进行攻击。
下面是Jinja2
的基础语法:
1 | {% … %} |
要查看SECRET_KEY
,设置我们的payload为:
1 | ?flag = {{config.SECRET_KEY}} |
使用get
方式传参得到flag。