souleyez 2.43.26__py3-none-any.whl → 2.43.34__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.

Potentially problematic release.


This version of souleyez might be problematic. Click here for more details.

Files changed (358) 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 +9526 -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 +1239 -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 +2200 -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 +292 -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/web_login_test_handler.py +327 -0
  126. souleyez/handlers/whois_handler.py +277 -0
  127. souleyez/handlers/wpscan_handler.py +554 -0
  128. souleyez/history.py +32 -16
  129. souleyez/importers/msf_importer.py +106 -75
  130. souleyez/importers/smart_importer.py +208 -147
  131. souleyez/integrations/siem/__init__.py +10 -10
  132. souleyez/integrations/siem/base.py +17 -18
  133. souleyez/integrations/siem/elastic.py +108 -122
  134. souleyez/integrations/siem/factory.py +207 -80
  135. souleyez/integrations/siem/googlesecops.py +146 -154
  136. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  137. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  138. souleyez/integrations/siem/sentinel.py +107 -109
  139. souleyez/integrations/siem/splunk.py +246 -212
  140. souleyez/integrations/siem/wazuh.py +65 -71
  141. souleyez/integrations/wazuh/__init__.py +5 -5
  142. souleyez/integrations/wazuh/client.py +70 -93
  143. souleyez/integrations/wazuh/config.py +85 -57
  144. souleyez/integrations/wazuh/host_mapper.py +28 -36
  145. souleyez/integrations/wazuh/sync.py +78 -68
  146. souleyez/intelligence/__init__.py +4 -5
  147. souleyez/intelligence/correlation_analyzer.py +309 -295
  148. souleyez/intelligence/exploit_knowledge.py +661 -623
  149. souleyez/intelligence/exploit_suggestions.py +159 -139
  150. souleyez/intelligence/gap_analyzer.py +132 -97
  151. souleyez/intelligence/gap_detector.py +251 -214
  152. souleyez/intelligence/sensitive_tables.py +266 -129
  153. souleyez/intelligence/service_parser.py +137 -123
  154. souleyez/intelligence/surface_analyzer.py +407 -268
  155. souleyez/intelligence/target_parser.py +159 -162
  156. souleyez/licensing/__init__.py +6 -6
  157. souleyez/licensing/validator.py +17 -19
  158. souleyez/log_config.py +79 -54
  159. souleyez/main.py +1505 -687
  160. souleyez/migrations/fix_job_counter.py +16 -14
  161. souleyez/parsers/bloodhound_parser.py +41 -39
  162. souleyez/parsers/crackmapexec_parser.py +178 -111
  163. souleyez/parsers/dalfox_parser.py +72 -77
  164. souleyez/parsers/dnsrecon_parser.py +103 -91
  165. souleyez/parsers/enum4linux_parser.py +183 -153
  166. souleyez/parsers/ffuf_parser.py +29 -25
  167. souleyez/parsers/gobuster_parser.py +301 -41
  168. souleyez/parsers/hashcat_parser.py +324 -79
  169. souleyez/parsers/http_fingerprint_parser.py +350 -103
  170. souleyez/parsers/hydra_parser.py +131 -111
  171. souleyez/parsers/impacket_parser.py +231 -178
  172. souleyez/parsers/john_parser.py +98 -86
  173. souleyez/parsers/katana_parser.py +316 -0
  174. souleyez/parsers/msf_parser.py +943 -498
  175. souleyez/parsers/nikto_parser.py +346 -65
  176. souleyez/parsers/nmap_parser.py +262 -174
  177. souleyez/parsers/nuclei_parser.py +40 -44
  178. souleyez/parsers/responder_parser.py +26 -26
  179. souleyez/parsers/searchsploit_parser.py +74 -74
  180. souleyez/parsers/service_explorer_parser.py +279 -0
  181. souleyez/parsers/smbmap_parser.py +180 -124
  182. souleyez/parsers/sqlmap_parser.py +434 -308
  183. souleyez/parsers/theharvester_parser.py +75 -57
  184. souleyez/parsers/whois_parser.py +135 -94
  185. souleyez/parsers/wpscan_parser.py +278 -190
  186. souleyez/plugins/afp.py +44 -36
  187. souleyez/plugins/afp_brute.py +114 -46
  188. souleyez/plugins/ard.py +48 -37
  189. souleyez/plugins/bloodhound.py +95 -61
  190. souleyez/plugins/certipy.py +303 -0
  191. souleyez/plugins/crackmapexec.py +186 -85
  192. souleyez/plugins/dalfox.py +120 -59
  193. souleyez/plugins/dns_hijack.py +146 -41
  194. souleyez/plugins/dnsrecon.py +97 -61
  195. souleyez/plugins/enum4linux.py +91 -66
  196. souleyez/plugins/evil_winrm.py +291 -0
  197. souleyez/plugins/ffuf.py +166 -90
  198. souleyez/plugins/firmware_extract.py +133 -29
  199. souleyez/plugins/gobuster.py +387 -190
  200. souleyez/plugins/gpp_extract.py +393 -0
  201. souleyez/plugins/hashcat.py +100 -73
  202. souleyez/plugins/http_fingerprint.py +854 -267
  203. souleyez/plugins/hydra.py +566 -200
  204. souleyez/plugins/impacket_getnpusers.py +117 -69
  205. souleyez/plugins/impacket_psexec.py +84 -64
  206. souleyez/plugins/impacket_secretsdump.py +103 -69
  207. souleyez/plugins/impacket_smbclient.py +89 -75
  208. souleyez/plugins/john.py +86 -69
  209. souleyez/plugins/katana.py +313 -0
  210. souleyez/plugins/kerbrute.py +237 -0
  211. souleyez/plugins/lfi_extract.py +541 -0
  212. souleyez/plugins/macos_ssh.py +117 -48
  213. souleyez/plugins/mdns.py +35 -30
  214. souleyez/plugins/msf_auxiliary.py +253 -130
  215. souleyez/plugins/msf_exploit.py +239 -161
  216. souleyez/plugins/nikto.py +134 -78
  217. souleyez/plugins/nmap.py +275 -91
  218. souleyez/plugins/nuclei.py +180 -89
  219. souleyez/plugins/nxc.py +285 -0
  220. souleyez/plugins/plugin_base.py +35 -36
  221. souleyez/plugins/plugin_template.py +13 -5
  222. souleyez/plugins/rdp_sec_check.py +130 -0
  223. souleyez/plugins/responder.py +112 -71
  224. souleyez/plugins/router_http_brute.py +76 -65
  225. souleyez/plugins/router_ssh_brute.py +118 -41
  226. souleyez/plugins/router_telnet_brute.py +124 -42
  227. souleyez/plugins/routersploit.py +91 -59
  228. souleyez/plugins/routersploit_exploit.py +77 -55
  229. souleyez/plugins/searchsploit.py +91 -77
  230. souleyez/plugins/service_explorer.py +1160 -0
  231. souleyez/plugins/smbmap.py +122 -72
  232. souleyez/plugins/smbpasswd.py +215 -0
  233. souleyez/plugins/sqlmap.py +301 -113
  234. souleyez/plugins/theharvester.py +127 -75
  235. souleyez/plugins/tr069.py +79 -57
  236. souleyez/plugins/upnp.py +65 -47
  237. souleyez/plugins/upnp_abuse.py +73 -55
  238. souleyez/plugins/vnc_access.py +129 -42
  239. souleyez/plugins/vnc_brute.py +109 -38
  240. souleyez/plugins/web_login_test.py +417 -0
  241. souleyez/plugins/whois.py +77 -58
  242. souleyez/plugins/wpscan.py +173 -69
  243. souleyez/reporting/__init__.py +2 -1
  244. souleyez/reporting/attack_chain.py +411 -346
  245. souleyez/reporting/charts.py +436 -501
  246. souleyez/reporting/compliance_mappings.py +334 -201
  247. souleyez/reporting/detection_report.py +126 -125
  248. souleyez/reporting/formatters.py +828 -591
  249. souleyez/reporting/generator.py +386 -302
  250. souleyez/reporting/metrics.py +72 -75
  251. souleyez/scanner.py +35 -29
  252. souleyez/security/__init__.py +37 -11
  253. souleyez/security/scope_validator.py +175 -106
  254. souleyez/security/validation.py +223 -149
  255. souleyez/security.py +22 -6
  256. souleyez/storage/credentials.py +247 -186
  257. souleyez/storage/crypto.py +296 -129
  258. souleyez/storage/database.py +73 -50
  259. souleyez/storage/db.py +58 -36
  260. souleyez/storage/deliverable_evidence.py +177 -128
  261. souleyez/storage/deliverable_exporter.py +282 -246
  262. souleyez/storage/deliverable_templates.py +134 -116
  263. souleyez/storage/deliverables.py +135 -130
  264. souleyez/storage/engagements.py +109 -56
  265. souleyez/storage/evidence.py +181 -152
  266. souleyez/storage/execution_log.py +31 -17
  267. souleyez/storage/exploit_attempts.py +93 -57
  268. souleyez/storage/exploits.py +67 -36
  269. souleyez/storage/findings.py +48 -61
  270. souleyez/storage/hosts.py +176 -144
  271. souleyez/storage/migrate_to_engagements.py +43 -19
  272. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  273. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  274. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  275. souleyez/storage/migrations/_005_screenshots.py +13 -5
  276. souleyez/storage/migrations/_006_deliverables.py +13 -5
  277. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  278. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  279. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  280. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  281. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  282. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  283. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  284. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  285. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  286. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  287. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  288. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  289. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  290. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  291. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  292. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  293. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  294. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  295. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  296. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  297. souleyez/storage/migrations/__init__.py +26 -26
  298. souleyez/storage/migrations/migration_manager.py +19 -19
  299. souleyez/storage/msf_sessions.py +100 -65
  300. souleyez/storage/osint.py +17 -24
  301. souleyez/storage/recommendation_engine.py +269 -235
  302. souleyez/storage/screenshots.py +33 -32
  303. souleyez/storage/smb_shares.py +136 -92
  304. souleyez/storage/sqlmap_data.py +183 -128
  305. souleyez/storage/team_collaboration.py +135 -141
  306. souleyez/storage/timeline_tracker.py +122 -94
  307. souleyez/storage/wazuh_vulns.py +64 -66
  308. souleyez/storage/web_paths.py +33 -37
  309. souleyez/testing/credential_tester.py +221 -205
  310. souleyez/ui/__init__.py +1 -1
  311. souleyez/ui/ai_quotes.py +12 -12
  312. souleyez/ui/attack_surface.py +2439 -1516
  313. souleyez/ui/chain_rules_view.py +914 -382
  314. souleyez/ui/correlation_view.py +312 -230
  315. souleyez/ui/dashboard.py +2382 -1130
  316. souleyez/ui/deliverables_view.py +148 -62
  317. souleyez/ui/design_system.py +13 -13
  318. souleyez/ui/errors.py +49 -49
  319. souleyez/ui/evidence_linking_view.py +284 -179
  320. souleyez/ui/evidence_vault.py +393 -285
  321. souleyez/ui/exploit_suggestions_view.py +555 -349
  322. souleyez/ui/export_view.py +100 -66
  323. souleyez/ui/gap_analysis_view.py +315 -171
  324. souleyez/ui/help_system.py +105 -97
  325. souleyez/ui/intelligence_view.py +436 -293
  326. souleyez/ui/interactive.py +23434 -10286
  327. souleyez/ui/interactive_selector.py +75 -68
  328. souleyez/ui/log_formatter.py +47 -39
  329. souleyez/ui/menu_components.py +22 -13
  330. souleyez/ui/msf_auxiliary_menu.py +184 -133
  331. souleyez/ui/pending_chains_view.py +336 -172
  332. souleyez/ui/progress_indicators.py +5 -3
  333. souleyez/ui/recommendations_view.py +195 -137
  334. souleyez/ui/rule_builder.py +343 -225
  335. souleyez/ui/setup_wizard.py +678 -284
  336. souleyez/ui/shortcuts.py +217 -165
  337. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  338. souleyez/ui/splunk_vulns_view.py +139 -86
  339. souleyez/ui/team_dashboard.py +498 -335
  340. souleyez/ui/template_selector.py +196 -105
  341. souleyez/ui/terminal.py +6 -6
  342. souleyez/ui/timeline_view.py +198 -127
  343. souleyez/ui/tool_setup.py +264 -164
  344. souleyez/ui/tutorial.py +202 -72
  345. souleyez/ui/tutorial_state.py +40 -40
  346. souleyez/ui/wazuh_vulns_view.py +235 -141
  347. souleyez/ui/wordlist_browser.py +260 -107
  348. souleyez/ui.py +464 -312
  349. souleyez/utils/tool_checker.py +427 -367
  350. souleyez/utils.py +33 -29
  351. souleyez/wordlists.py +134 -167
  352. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
  353. souleyez-2.43.34.dist-info/RECORD +443 -0
  354. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.26.dist-info/RECORD +0 -379
  356. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,9 @@ class ContextBuilder:
18
18
  self.creds_mgr = CredentialsManager()
19
19
  self.findings_mgr = FindingsManager()
20
20
 
21
- def build_context(self, engagement_id: int, target_host_ids: Optional[list] = None) -> str:
21
+ def build_context(
22
+ self, engagement_id: int, target_host_ids: Optional[list] = None
23
+ ) -> str:
22
24
  """
23
25
  Build formatted context string from engagement data.
24
26
 
@@ -40,7 +42,7 @@ class ContextBuilder:
40
42
  # Engagement info
41
43
  sections.append("=" * 60)
42
44
  sections.append(f"ENGAGEMENT: {engagement['name']}")
43
- if engagement.get('description'):
45
+ if engagement.get("description"):
44
46
  sections.append(f"Description: {engagement['description']}")
45
47
  sections.append("=" * 60)
46
48
  sections.append("")
@@ -48,25 +50,27 @@ class ContextBuilder:
48
50
  # Get hosts (filtered if target_host_ids provided)
49
51
  all_hosts = self.host_mgr.list_hosts(engagement_id)
50
52
  if target_host_ids:
51
- hosts = [h for h in all_hosts if h['id'] in target_host_ids]
52
- sections.append(f"SELECTED TARGET HOSTS ({len(hosts)} of {len(all_hosts)}):")
53
+ hosts = [h for h in all_hosts if h["id"] in target_host_ids]
54
+ sections.append(
55
+ f"SELECTED TARGET HOSTS ({len(hosts)} of {len(all_hosts)}):"
56
+ )
53
57
  else:
54
58
  hosts = all_hosts
55
59
  sections.append(f"DISCOVERED HOSTS ({len(hosts)}):")
56
-
60
+
57
61
  if hosts:
58
62
  for host in hosts:
59
- ip = host.get('ip_address', 'unknown')
60
- hostname = host.get('hostname', '')
61
- os_name = host.get('os_name', '')
62
- status = host.get('status', 'unknown')
63
- access_level = host.get('access_level', 'none')
64
- notes = host.get('notes', '')
63
+ ip = host.get("ip_address", "unknown")
64
+ hostname = host.get("hostname", "")
65
+ os_name = host.get("os_name", "")
66
+ status = host.get("status", "unknown")
67
+ access_level = host.get("access_level", "none")
68
+ notes = host.get("notes", "")
65
69
 
66
70
  # Status icon
67
- if status == 'compromised' or access_level != 'none':
71
+ if status == "compromised" or access_level != "none":
68
72
  icon = "🔓"
69
- elif status in ['up', 'active']:
73
+ elif status in ["up", "active"]:
70
74
  icon = "🔒"
71
75
  else:
72
76
  icon = "❓"
@@ -74,16 +78,16 @@ class ContextBuilder:
74
78
  host_line = f" {icon} {ip}"
75
79
  if hostname:
76
80
  host_line += f" ({hostname})"
77
-
81
+
78
82
  # Show access level if compromised
79
- if access_level != 'none':
83
+ if access_level != "none":
80
84
  host_line += f" - COMPROMISED [access={access_level.upper()}]"
81
85
  elif status:
82
86
  host_line += f" [{status.upper()}]"
83
-
87
+
84
88
  if os_name:
85
89
  host_line += f" - {os_name}"
86
-
90
+
87
91
  if notes:
88
92
  host_line += f"\n Note: {notes}"
89
93
 
@@ -96,15 +100,15 @@ class ContextBuilder:
96
100
  total_services = 0
97
101
  service_lines = []
98
102
  for host in hosts:
99
- host_id = host['id']
100
- ip = host.get('ip_address', 'unknown')
103
+ host_id = host["id"]
104
+ ip = host.get("ip_address", "unknown")
101
105
  services = self.host_mgr.get_host_services(host_id)
102
106
 
103
107
  for service in services:
104
- port = service.get('port', '?')
105
- protocol = service.get('protocol', 'tcp')
106
- service_name = service.get('service_name', 'unknown')
107
- version = service.get('service_version', '')
108
+ port = service.get("port", "?")
109
+ protocol = service.get("protocol", "tcp")
110
+ service_name = service.get("service_name", "unknown")
111
+ version = service.get("service_version", "")
108
112
 
109
113
  service_line = f" - {ip}:{port}/{protocol} - {service_name}"
110
114
  if version:
@@ -126,17 +130,17 @@ class ContextBuilder:
126
130
  sections.append(f"AVAILABLE CREDENTIALS ({len(creds)}):")
127
131
  if creds:
128
132
  for cred in creds:
129
- username = cred.get('username', 'unknown')
130
- password = cred.get('password', 'unknown')
131
- service = cred.get('service', '')
132
- status = cred.get('status', 'untested')
133
- last_tested = cred.get('last_tested', '')
134
- notes = cred.get('notes', '')
133
+ username = cred.get("username", "unknown")
134
+ password = cred.get("password", "unknown")
135
+ service = cred.get("service", "")
136
+ status = cred.get("status", "untested")
137
+ last_tested = cred.get("last_tested", "")
138
+ notes = cred.get("notes", "")
135
139
 
136
140
  # Status icon
137
- if status == 'valid':
141
+ if status == "valid":
138
142
  icon = "✓"
139
- elif status == 'invalid':
143
+ elif status == "invalid":
140
144
  icon = "✗"
141
145
  else:
142
146
  icon = "?"
@@ -144,14 +148,18 @@ class ContextBuilder:
144
148
  cred_line = f" {icon} {username}:{password}"
145
149
  if service:
146
150
  cred_line += f" ({service})"
147
-
151
+
148
152
  cred_line += f" - {status.upper()}"
149
-
153
+
150
154
  if last_tested:
151
155
  # Extract date from timestamp
152
- test_date = last_tested.split('T')[0] if 'T' in last_tested else last_tested
156
+ test_date = (
157
+ last_tested.split("T")[0]
158
+ if "T" in last_tested
159
+ else last_tested
160
+ )
153
161
  cred_line += f", tested {test_date}"
154
-
162
+
155
163
  if notes:
156
164
  cred_line += f"\n Note: {notes}"
157
165
 
@@ -167,26 +175,26 @@ class ContextBuilder:
167
175
  sections.append(f"FINDINGS ({len(findings)}):")
168
176
  if findings:
169
177
  # Group by severity
170
- critical = [f for f in findings if f.get('severity') == 'critical']
171
- high = [f for f in findings if f.get('severity') == 'high']
172
- medium = [f for f in findings if f.get('severity') == 'medium']
173
- low = [f for f in findings if f.get('severity') == 'low']
174
- info = [f for f in findings if f.get('severity') == 'info']
178
+ critical = [f for f in findings if f.get("severity") == "critical"]
179
+ high = [f for f in findings if f.get("severity") == "high"]
180
+ medium = [f for f in findings if f.get("severity") == "medium"]
181
+ low = [f for f in findings if f.get("severity") == "low"]
182
+ info = [f for f in findings if f.get("severity") == "info"]
175
183
 
176
184
  if critical:
177
185
  sections.append(f" CRITICAL ({len(critical)}):")
178
186
  for f in critical:
179
187
  sections.append(f" - {f.get('title', 'Untitled')}")
180
- if f.get('cve_id'):
188
+ if f.get("cve_id"):
181
189
  sections.append(f" CVE: {f['cve_id']}")
182
- if f.get('cvss_score'):
190
+ if f.get("cvss_score"):
183
191
  sections.append(f" CVSS: {f['cvss_score']}")
184
192
 
185
193
  if high:
186
194
  sections.append(f" HIGH ({len(high)}):")
187
195
  for f in high:
188
196
  sections.append(f" - {f.get('title', 'Untitled')}")
189
- if f.get('cve_id'):
197
+ if f.get("cve_id"):
190
198
  sections.append(f" CVE: {f['cve_id']}")
191
199
 
192
200
  if medium:
@@ -213,14 +221,16 @@ class ContextBuilder:
213
221
 
214
222
  return "\n".join(sections)
215
223
 
216
- def get_state_summary(self, engagement_id: int, target_host_ids: Optional[list] = None) -> str:
224
+ def get_state_summary(
225
+ self, engagement_id: int, target_host_ids: Optional[list] = None
226
+ ) -> str:
217
227
  """
218
228
  Build a summary of current engagement state (what's already done).
219
-
229
+
220
230
  Args:
221
231
  engagement_id: Engagement ID
222
232
  target_host_ids: Optional list of specific host IDs to include
223
-
233
+
224
234
  Returns:
225
235
  String summary of completed actions and current access level
226
236
  """
@@ -229,38 +239,40 @@ class ContextBuilder:
229
239
  # Get data (filtered if target_host_ids provided)
230
240
  all_hosts = self.host_mgr.list_hosts(engagement_id)
231
241
  if target_host_ids:
232
- hosts = [h for h in all_hosts if h['id'] in target_host_ids]
242
+ hosts = [h for h in all_hosts if h["id"] in target_host_ids]
233
243
  else:
234
244
  hosts = all_hosts
235
-
245
+
236
246
  creds = self.creds_mgr.list_credentials(engagement_id)
237
247
 
238
248
  # Track state
239
249
  compromised_hosts = []
240
- highest_access = 'none'
250
+ highest_access = "none"
241
251
  validated_creds = []
242
252
  invalid_creds = []
243
253
 
244
254
  # Analyze hosts
245
255
  for host in hosts:
246
- access = host.get('access_level', 'none')
247
- if access != 'none':
248
- ip = host.get('ip_address', 'unknown')
256
+ access = host.get("access_level", "none")
257
+ if access != "none":
258
+ ip = host.get("ip_address", "unknown")
249
259
  compromised_hosts.append(f"{ip} ({access})")
250
260
 
251
261
  # Track highest access
252
- access_levels = ['none', 'user', 'admin', 'root']
262
+ access_levels = ["none", "user", "admin", "root"]
253
263
  if access_levels.index(access) > access_levels.index(highest_access):
254
264
  highest_access = access
255
265
 
256
266
  # Analyze credentials
257
267
  for cred in creds:
258
- status = cred.get('status', 'untested')
259
- if status == 'valid':
260
- username = cred.get('username', 'unknown')
261
- service = cred.get('service', '')
262
- validated_creds.append(f"{username} ({service})" if service else username)
263
- elif status == 'invalid':
268
+ status = cred.get("status", "untested")
269
+ if status == "valid":
270
+ username = cred.get("username", "unknown")
271
+ service = cred.get("service", "")
272
+ validated_creds.append(
273
+ f"{username} ({service})" if service else username
274
+ )
275
+ elif status == "invalid":
264
276
  invalid_creds.append(f"{cred.get('username', 'unknown')}")
265
277
 
266
278
  # Build summary
@@ -273,14 +285,20 @@ class ContextBuilder:
273
285
 
274
286
  if compromised_hosts:
275
287
  sections.append(f"- Compromised hosts: {', '.join(compromised_hosts)}")
276
- sections.append(f"- Highest access level achieved: {highest_access.upper()}")
288
+ sections.append(
289
+ f"- Highest access level achieved: {highest_access.upper()}"
290
+ )
277
291
  else:
278
292
  sections.append("- No systems compromised yet")
279
293
 
280
294
  if validated_creds:
281
- sections.append(f"- Validated credentials: {', '.join(validated_creds)}")
295
+ sections.append(
296
+ f"- Validated credentials: {', '.join(validated_creds)}"
297
+ )
282
298
 
283
299
  if invalid_creds:
284
- sections.append(f"- Failed credentials tested: {', '.join(invalid_creds[:3])}")
300
+ sections.append(
301
+ f"- Failed credentials tested: {', '.join(invalid_creds[:3])}"
302
+ )
285
303
 
286
304
  return "\n".join(sections)