> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-17/vulnerability-exploitation/trick-0188/web-vulnerability-exploitation-ssti.md).

# Ssti

## Flask SSTI Via PGP Name

When a web application processes PGP keys, the `Real name` field within the user ID can be a potential Server-Side Template Injection (SSTI) vector if it's rendered by a template engine.

To test for SSTI via this field, create a PGP key with a template payload in the name. For Flask/Jinja2, a common test is `{{7*7}}`.

Generate the key with the injection payload as the real name:

```bash
gpg --full-generate-key
```

This command initiates the process of generating a new key pair. You will be asked to specify the kind of key you want, the key size, and the validity period. Following these choices, you will be prompted for user ID information: Real name, Email address, and Comment. Enter the SSTI payload, such as `{{7*7}}`, in the Real name field.

Export the public key:

```bash
gpg --armor --export <fingerprint_of_the_test_key>
```

This command outputs the public key in ASCII armored format, which is a text representation suitable for sharing or submitting to web applications.

Sign a dummy message using this key:

```bash
echo "test message" | gpg --sign --local-user <fingerprint_of_the_test_key> --armor
```

This creates a signed message using the key containing the payload, also in ASCII armored format.

Submit the exported public key and the signed message to the vulnerable web application's PGP verification function. Observe the output page where the user's name would normally be displayed. If the application is vulnerable, you should see the result of the calculation (e.g., `49`) instead of the literal payload `{{7*7}}`. This confirms that the template engine processed the input from the key's real name field.

***

## Flask Server-Side Template Injection

Confirm Flask Server-Side Template Injection via specific debug endpoints often found in development or misconfigured production setups.

First, send a template expression (like arithmetic) to the debug variable endpoint, typically requiring an authenticated session cookie:

```bash
curl 'http://10.10.85.113:7777/debug?debug={{7*7}}&password=[REDACTED]' -I -b 'session=.eJyrVkpJTSpNV7JS...[REDACTED]'
```

Next, retrieve the result from a separate debug result endpoint, potentially requiring headers like `X-Forwarded-For: 127.0.0.1` and the same session cookie:

```bash
curl 'http://10.10.85.113:7777/debugresult' -H 'X-Forwarded-For: 127.0.0.1' -b 'session=.eJyrVkpJTSpNV7JS...[REDACTED]'
```

Look for the evaluated output (`49` in this example) in the response body. This pattern often indicates the application uses `render_template_string` or similar with user-controlled input from a session variable, confirming SSTI on this path. Be mindful of potential filters like the `illegal_chars_check` noted in the application logic.

Template engines evaluate expressions contained within delimiters. For example, in Jinja2, expressions like `{{ 7 * 7 }}` are evaluated. The `render_template_string` function in Flask renders a template from a string rather than a file. This is useful for small snippets or for extending templates. The template is parsed and rendered with the given context variables.

```python
flask.render_template_string(source, **context)
```

The `source` parameter is the template string to render, and `context` provides variables accessible within the template. When user-supplied input is directly used as the `source` or within the `context` of a template rendering function like `render_template_string`, it creates the potential for Server-Side Template Injection, allowing attackers to execute arbitrary code or access sensitive data depending on the template engine's capabilities and available objects.

Beyond simple arithmetic, other common payloads can be used to confirm Jinja2 template evaluation and gather information about the application environment:

* `{{ config }}`: Attempts to print the Flask application's configuration object, which may contain sensitive information like secret keys or database credentials.
* `{{ session }}`: Attempts to print the user's session object, confirming session variables are accessible within the template context.
* `{{ request }}`: Attempts to print the request object, useful for understanding the current request details.
* `{{ self }}`: In some contexts, refers to the current template object itself.

A more advanced technique to explore the capabilities of the template engine and potentially achieve RCE involves accessing Python's object system. A common payload for Jinja2 is:

```jinja
{{ ''.__class__.__mro__[1].__subclasses__() }}
```

This payload attempts to:

1. Get the class of an empty string (`''.__class__`).
2. Access the Method Resolution Order (`__mro__`) of the string class. The `__mro__` is a tuple containing the classes that are considered when looking for base classes.
3. Access the second element (`[1]`), which is typically the base `object` class in Python 3.
4. Call the `__subclasses__()` method on the `object` class, which returns a list of all classes that inherit from `object` currently loaded in the Python interpreter's memory.

By enumerating subclasses, an attacker might find classes that allow arbitrary code execution (e.g., `os.system`, `subprocess.Popen`) and chain further payloads to execute commands. However, successfully exploiting this for RCE depends heavily on filters, available classes, and accessible methods within the template environment. Confirming the execution of payloads like `{{ config }}` or the subclass enumeration payload is a strong indicator of a exploitable SSTI vulnerability.
