offensive-ssti
The offensive-ssti skill provides a systematic methodology for identifying and exploiting server-side template injection vulnerabilities across multiple template engines including Jinja2, Twig, Freemarker, Pebble, and Velocity. It includes detection techniques using polyglot payloads, engine identification methods, blind SSTI testing approaches, and filter bypass strategies. Use this skill when assessing web applications for template injection risks or conducting penetration tests on systems utilizing dynamic template rendering.
git clone --depth 1 https://github.com/SnailSploit/Claude-Red /tmp/offensive-ssti && cp -r /tmp/offensive-ssti/Skills/web/offensive-ssti ~/.claude/skills/offensive-sstiSKILL.md
# SKILL: Server-Side Template Injection (SSTI)
## Metadata
- **Skill Name**: ssti
- **Folder**: offensive-ssti
- **Source**: https://github.com/SnailSploit/offensive-checklist/blob/main/ssti.md
## Description
Server-Side Template Injection testing checklist: template engine identification (Jinja2, Twig, Freemarker, Pebble, Velocity), polyglot detection payloads, engine-specific RCE payloads, blind SSTI, and filter bypass. Use when testing web apps for template injection vulnerabilities.
## Trigger Phrases
Use this skill when the conversation involves any of:
`SSTI, server-side template injection, Jinja2, Twig, Freemarker, Pebble, Velocity, template injection, template RCE, polyglot payload, template engine, blind SSTI`
## Instructions for Claude
When this skill is active:
1. Load and apply the full methodology below as your operational checklist
2. Follow steps in order unless the user specifies otherwise
3. For each technique, consider applicability to the current target/context
4. Track which checklist items have been completed
5. Suggest next steps based on findings
---
## Full Methodology
# Server-Side Template Injection (SSTI)
Template engines are software used to generate dynamic web pages. When user input is unsafely embedded into templates, server-side template injection (SSTI) can occur, potentially leading to Remote Code Execution (RCE).
## Shortcut
- Look for all locations where user input is reflected or used in the response (URL parameters, POST data, HTTP headers, JSON data, etc.).
- Inject template syntax characters/polyglots like `${{<%[%'"}}%\`, `{{7*'7'}}`, `{{7*7}}` into inputs. Check for errors, mathematical evaluation (e.g., `49` instead of `7*7`), or missing/changed reflections.
- Verify server-side evaluation (e.g., math works) vs. client-side XSS.
- Use engine-specific syntax (e.g., `${7/0}`, `{{7/0}}`, `<%= 7/0 %>`), known variable names (`{{config}}`, `{$smarty}`), or error messages to identify the template engine (use a decision tree like PortSwigger's or HackTricks').
- Look up payloads specific to the identified engine and backend language.
- Use engine-specific payloads (see Methodologies) to read files, execute commands, access internal data, or escape sandboxes.
- Create a non-destructive proof of concept (e.g., `touch ssti_poc_by_YOUR_NAME.txt` via RCE).
## Mechanisms
Server-Side Template Injection (SSTI) occurs when attacker-controlled input is embedded unsafely into a server-side template. Instead of treating the input as data, the template engine executes it as part of the template's code. This allows injecting template directives to execute arbitrary code, access server data, or perform actions as the application.
**Root Cause:** Concatenating or directly rendering user input within a template string without proper sanitization or using insecure template functions.
- Misusing “helper” APIs that compile raw strings at runtime, such as `render_template_string`, `Template::render_inline`, or `Template.compile`, which appear safe but execute attacker‑supplied data.
### Vulnerable Example 1 (Simple Jinja2)
The following program takes user input and concatenates it directly into a template string:
```python
# Assume user_input comes from an HTTP request parameter
from jinja2 import Template
tmpl = Template("<html><h1>The user's name is: " + user_input + "</h1></html>")
print(tmpl.render())
```
If `user_input` is `{{1+1}}`, the engine executes the expression:
```html
<html>
<h1>The user's name is: 2</h1>
</html>
```
### Vulnerable Example 2 (Flask/Jinja2)
```python
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/')
def home():
# Vulnerable: Directly renders user input from 'user' query parameter
if request.args.get('user'):
return render_template_string('Welcome ' + request.args.get('user'))
else:
return render_template_string('Hello World!')
# Attacker URL: http://<server>/?user={{7*7}}
# Response: Welcome 49
```
### Secure Example (Flask/Jinja2)
```python
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/')
def home():
# Secure: Passes user input as a variable to the template
if request.args.get('user'):
# The template engine treats 'username' as data, not code
return render_template_string('Welcome {{ username }}', username=request.args.get('user'))
else:
# ...
```
## Hunt
### Preparation
- Identify all user-controlled input points: URL parameters, POST data, HTTP headers (Referer, User-Agent, custom headers), JSON keys/values, etc.
- Use tools like `waybackurls` and `qsreplace` to generate fuzzing lists for parameters:
```bash
waybackurls http://target.com | qsreplace "ssti{{9*9}}" > fuzz.txt
ffuf -u FUZZ -w fuzz.txt -replay-proxy http://127.0.0.1:8080/ -mr "ssti81"
# Check Burp Repeater/Logger++ for responses containing the evaluated result (e.g., 81)
```
### Detection
- Initial Fuzzing: Inject basic polyglots: `${{<%[%'"}}%\`, `{{7*'7'}}`, `{{7*7}}`, `${7*7}`, **quote‑less payloads** such as `{{[].__class__.__mro__[1]}}`.
- Observe Behavior:
- Errors: Stack traces or specific error messages can reveal the template engine (e.g., Jinja2, Smarty, FreeMarker).
- Evaluation: Input like `{{7*7}}` becomes `49`.
- Blank Output: The payload might be processed and removed if invalid or if it performs an action without output.
- No Change: Input reflected exactly as provided; likely not vulnerable (or requires different syntax).
- Differentiate from XSS: Ensure the evaluation happens server-side, not client-side. `${7*7}` evaluating to `49` strongly suggests SSTI.
### Identification
#### Engine-Specific Payloads
Use a systematic approach based on the initial observations or a decision tree ([PortSwigger, updated July 2024](https://portswigger.net/research/server-side-template-injection), [Medium](https://miro.medium.com/v2/resize:fit:1100/format:webp/1%2A35XwCActive Directory attack methodology for internal network red team engagements. Covers reconnaissance (BloodHound, PowerView, ADExplorer), credential abuse (Kerberoasting, ASREProasting, NTLM relay, LLMNR/NBT-NS poisoning), privilege escalation (ACL abuse, GPO abuse, unconstrained/constrained delegation), lateral movement (Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, WMI/WinRM/PsExec), persistence (Golden/Silver/Diamond Tickets, DCSync, DCShadow, AdminSDHolder, Skeleton Key), forest trust attacks, ADCS abuse (ESC1-ESC15), and modern MDI/Defender for Identity evasion. Use when assessing on-prem AD, hybrid AD/Entra ID environments, or ADCS deployments.
JWT attack methodology for penetration testers. Covers algorithm confusion (alg:none, RS256→HS256), weak HMAC secret brute force, kid parameter injection (SQLi, path traversal), jku/x5u/jwk header injection, JWKS cache poisoning, JWS/JWE confusion, timing attacks, and mobile JWT storage extraction. Use when testing JWT-based authentication, hunting auth bypass via token manipulation, or evaluating JWT implementation security in web or mobile apps.
Cloud security attack methodology covering AWS, Azure, and GCP. Includes credential harvesting (IMDS, ~/.aws, env vars, leaked CI secrets, instance roles), enumeration with cloud-specific tools (pacu, ScoutSuite, Prowler, ROADtools, gcp_enum), privilege escalation paths (IAM PassRole, AssumeRole chains, Lambda/Functions privilege flips, Azure Owner-on-self, GCP serviceAccountTokenCreator), persistence techniques (IAM user/key creation, AAD app registration, GCP svc account key creation, EventBridge/Logic Apps backdoors), data exfiltration (S3/Blob/GCS, snapshot share, RDS/CosmosDB/Cloud SQL exfil), cloud-native lateral movement (cross-account assume, Azure AD multi-tenant, GCP project hierarchy), serverless attacks (Lambda env vars, layer hijack, Step Functions), Kubernetes-on-cloud (EKS/AKS/GKE-specific paths to node and AWS metadata), and CSPM evasion (CloudTrail blind spots, GuardDuty mute, Sentinel rule shaping). Use when the engagement scope is cloud accounts, when you've stolen cloud credentials, or when assessing cloud posture.