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.
- souleyez/__init__.py +1 -2
- souleyez/ai/__init__.py +21 -15
- souleyez/ai/action_mapper.py +249 -150
- souleyez/ai/chain_advisor.py +116 -100
- souleyez/ai/claude_provider.py +29 -28
- souleyez/ai/context_builder.py +80 -62
- souleyez/ai/executor.py +158 -117
- souleyez/ai/feedback_handler.py +136 -121
- souleyez/ai/llm_factory.py +27 -20
- souleyez/ai/llm_provider.py +4 -2
- souleyez/ai/ollama_provider.py +6 -9
- souleyez/ai/ollama_service.py +44 -37
- souleyez/ai/path_scorer.py +91 -76
- souleyez/ai/recommender.py +176 -144
- souleyez/ai/report_context.py +74 -73
- souleyez/ai/report_service.py +84 -66
- souleyez/ai/result_parser.py +222 -229
- souleyez/ai/safety.py +67 -44
- souleyez/auth/__init__.py +23 -22
- souleyez/auth/audit.py +36 -26
- souleyez/auth/engagement_access.py +65 -48
- souleyez/auth/permissions.py +14 -3
- souleyez/auth/session_manager.py +54 -37
- souleyez/auth/user_manager.py +109 -64
- souleyez/commands/audit.py +40 -43
- souleyez/commands/auth.py +35 -15
- souleyez/commands/deliverables.py +55 -50
- souleyez/commands/engagement.py +47 -28
- souleyez/commands/license.py +32 -23
- souleyez/commands/screenshots.py +36 -32
- souleyez/commands/user.py +82 -36
- souleyez/config.py +52 -44
- souleyez/core/credential_tester.py +87 -81
- souleyez/core/cve_mappings.py +179 -192
- souleyez/core/cve_matcher.py +162 -148
- souleyez/core/msf_auto_mapper.py +100 -83
- souleyez/core/msf_chain_engine.py +294 -256
- souleyez/core/msf_database.py +153 -70
- souleyez/core/msf_integration.py +679 -673
- souleyez/core/msf_rpc_client.py +40 -42
- souleyez/core/msf_rpc_manager.py +77 -79
- souleyez/core/msf_sync_manager.py +241 -181
- souleyez/core/network_utils.py +22 -15
- souleyez/core/parser_handler.py +34 -25
- souleyez/core/pending_chains.py +114 -63
- souleyez/core/templates.py +158 -107
- souleyez/core/tool_chaining.py +9526 -2879
- souleyez/core/version_utils.py +79 -94
- souleyez/core/vuln_correlation.py +136 -89
- souleyez/core/web_utils.py +33 -32
- souleyez/data/wordlists/ad_users.txt +378 -0
- souleyez/data/wordlists/api_endpoints_large.txt +769 -0
- souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
- souleyez/data/wordlists/lfi_payloads.txt +82 -0
- souleyez/data/wordlists/passwords_brute.txt +1548 -0
- souleyez/data/wordlists/passwords_crack.txt +2479 -0
- souleyez/data/wordlists/passwords_spray.txt +386 -0
- souleyez/data/wordlists/subdomains_large.txt +5057 -0
- souleyez/data/wordlists/usernames_common.txt +694 -0
- souleyez/data/wordlists/web_dirs_large.txt +4769 -0
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +12 -17
- souleyez/detection/mitre_mappings.py +61 -55
- souleyez/detection/validator.py +97 -86
- souleyez/devtools.py +23 -10
- souleyez/docs/README.md +4 -4
- souleyez/docs/api-reference/cli-commands.md +2 -2
- souleyez/docs/developer-guide/adding-new-tools.md +562 -0
- souleyez/docs/user-guide/auto-chaining.md +30 -8
- souleyez/docs/user-guide/getting-started.md +1 -1
- souleyez/docs/user-guide/installation.md +26 -3
- souleyez/docs/user-guide/metasploit-integration.md +2 -2
- souleyez/docs/user-guide/rbac.md +1 -1
- souleyez/docs/user-guide/scope-management.md +1 -1
- souleyez/docs/user-guide/siem-integration.md +1 -1
- souleyez/docs/user-guide/tools-reference.md +1 -8
- souleyez/docs/user-guide/worker-management.md +1 -1
- souleyez/engine/background.py +1239 -535
- souleyez/engine/base.py +4 -1
- souleyez/engine/job_status.py +17 -49
- souleyez/engine/log_sanitizer.py +103 -77
- souleyez/engine/manager.py +38 -7
- souleyez/engine/result_handler.py +2200 -1550
- souleyez/engine/worker_manager.py +50 -41
- souleyez/export/evidence_bundle.py +72 -62
- souleyez/feature_flags/features.py +16 -20
- souleyez/feature_flags.py +5 -9
- souleyez/handlers/__init__.py +11 -0
- souleyez/handlers/base.py +188 -0
- souleyez/handlers/bash_handler.py +277 -0
- souleyez/handlers/bloodhound_handler.py +243 -0
- souleyez/handlers/certipy_handler.py +311 -0
- souleyez/handlers/crackmapexec_handler.py +486 -0
- souleyez/handlers/dnsrecon_handler.py +344 -0
- souleyez/handlers/enum4linux_handler.py +400 -0
- souleyez/handlers/evil_winrm_handler.py +493 -0
- souleyez/handlers/ffuf_handler.py +815 -0
- souleyez/handlers/gobuster_handler.py +1114 -0
- souleyez/handlers/gpp_extract_handler.py +334 -0
- souleyez/handlers/hashcat_handler.py +444 -0
- souleyez/handlers/hydra_handler.py +563 -0
- souleyez/handlers/impacket_getuserspns_handler.py +343 -0
- souleyez/handlers/impacket_psexec_handler.py +222 -0
- souleyez/handlers/impacket_secretsdump_handler.py +426 -0
- souleyez/handlers/john_handler.py +286 -0
- souleyez/handlers/katana_handler.py +425 -0
- souleyez/handlers/kerbrute_handler.py +298 -0
- souleyez/handlers/ldapsearch_handler.py +636 -0
- souleyez/handlers/lfi_extract_handler.py +464 -0
- souleyez/handlers/msf_auxiliary_handler.py +408 -0
- souleyez/handlers/msf_exploit_handler.py +380 -0
- souleyez/handlers/nikto_handler.py +413 -0
- souleyez/handlers/nmap_handler.py +821 -0
- souleyez/handlers/nuclei_handler.py +359 -0
- souleyez/handlers/nxc_handler.py +371 -0
- souleyez/handlers/rdp_sec_check_handler.py +353 -0
- souleyez/handlers/registry.py +292 -0
- souleyez/handlers/responder_handler.py +232 -0
- souleyez/handlers/service_explorer_handler.py +434 -0
- souleyez/handlers/smbclient_handler.py +344 -0
- souleyez/handlers/smbmap_handler.py +510 -0
- souleyez/handlers/smbpasswd_handler.py +296 -0
- souleyez/handlers/sqlmap_handler.py +1116 -0
- souleyez/handlers/theharvester_handler.py +601 -0
- souleyez/handlers/web_login_test_handler.py +327 -0
- souleyez/handlers/whois_handler.py +277 -0
- souleyez/handlers/wpscan_handler.py +554 -0
- souleyez/history.py +32 -16
- souleyez/importers/msf_importer.py +106 -75
- souleyez/importers/smart_importer.py +208 -147
- souleyez/integrations/siem/__init__.py +10 -10
- souleyez/integrations/siem/base.py +17 -18
- souleyez/integrations/siem/elastic.py +108 -122
- souleyez/integrations/siem/factory.py +207 -80
- souleyez/integrations/siem/googlesecops.py +146 -154
- souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
- souleyez/integrations/siem/sentinel.py +107 -109
- souleyez/integrations/siem/splunk.py +246 -212
- souleyez/integrations/siem/wazuh.py +65 -71
- souleyez/integrations/wazuh/__init__.py +5 -5
- souleyez/integrations/wazuh/client.py +70 -93
- souleyez/integrations/wazuh/config.py +85 -57
- souleyez/integrations/wazuh/host_mapper.py +28 -36
- souleyez/integrations/wazuh/sync.py +78 -68
- souleyez/intelligence/__init__.py +4 -5
- souleyez/intelligence/correlation_analyzer.py +309 -295
- souleyez/intelligence/exploit_knowledge.py +661 -623
- souleyez/intelligence/exploit_suggestions.py +159 -139
- souleyez/intelligence/gap_analyzer.py +132 -97
- souleyez/intelligence/gap_detector.py +251 -214
- souleyez/intelligence/sensitive_tables.py +266 -129
- souleyez/intelligence/service_parser.py +137 -123
- souleyez/intelligence/surface_analyzer.py +407 -268
- souleyez/intelligence/target_parser.py +159 -162
- souleyez/licensing/__init__.py +6 -6
- souleyez/licensing/validator.py +17 -19
- souleyez/log_config.py +79 -54
- souleyez/main.py +1505 -687
- souleyez/migrations/fix_job_counter.py +16 -14
- souleyez/parsers/bloodhound_parser.py +41 -39
- souleyez/parsers/crackmapexec_parser.py +178 -111
- souleyez/parsers/dalfox_parser.py +72 -77
- souleyez/parsers/dnsrecon_parser.py +103 -91
- souleyez/parsers/enum4linux_parser.py +183 -153
- souleyez/parsers/ffuf_parser.py +29 -25
- souleyez/parsers/gobuster_parser.py +301 -41
- souleyez/parsers/hashcat_parser.py +324 -79
- souleyez/parsers/http_fingerprint_parser.py +350 -103
- souleyez/parsers/hydra_parser.py +131 -111
- souleyez/parsers/impacket_parser.py +231 -178
- souleyez/parsers/john_parser.py +98 -86
- souleyez/parsers/katana_parser.py +316 -0
- souleyez/parsers/msf_parser.py +943 -498
- souleyez/parsers/nikto_parser.py +346 -65
- souleyez/parsers/nmap_parser.py +262 -174
- souleyez/parsers/nuclei_parser.py +40 -44
- souleyez/parsers/responder_parser.py +26 -26
- souleyez/parsers/searchsploit_parser.py +74 -74
- souleyez/parsers/service_explorer_parser.py +279 -0
- souleyez/parsers/smbmap_parser.py +180 -124
- souleyez/parsers/sqlmap_parser.py +434 -308
- souleyez/parsers/theharvester_parser.py +75 -57
- souleyez/parsers/whois_parser.py +135 -94
- souleyez/parsers/wpscan_parser.py +278 -190
- souleyez/plugins/afp.py +44 -36
- souleyez/plugins/afp_brute.py +114 -46
- souleyez/plugins/ard.py +48 -37
- souleyez/plugins/bloodhound.py +95 -61
- souleyez/plugins/certipy.py +303 -0
- souleyez/plugins/crackmapexec.py +186 -85
- souleyez/plugins/dalfox.py +120 -59
- souleyez/plugins/dns_hijack.py +146 -41
- souleyez/plugins/dnsrecon.py +97 -61
- souleyez/plugins/enum4linux.py +91 -66
- souleyez/plugins/evil_winrm.py +291 -0
- souleyez/plugins/ffuf.py +166 -90
- souleyez/plugins/firmware_extract.py +133 -29
- souleyez/plugins/gobuster.py +387 -190
- souleyez/plugins/gpp_extract.py +393 -0
- souleyez/plugins/hashcat.py +100 -73
- souleyez/plugins/http_fingerprint.py +854 -267
- souleyez/plugins/hydra.py +566 -200
- souleyez/plugins/impacket_getnpusers.py +117 -69
- souleyez/plugins/impacket_psexec.py +84 -64
- souleyez/plugins/impacket_secretsdump.py +103 -69
- souleyez/plugins/impacket_smbclient.py +89 -75
- souleyez/plugins/john.py +86 -69
- souleyez/plugins/katana.py +313 -0
- souleyez/plugins/kerbrute.py +237 -0
- souleyez/plugins/lfi_extract.py +541 -0
- souleyez/plugins/macos_ssh.py +117 -48
- souleyez/plugins/mdns.py +35 -30
- souleyez/plugins/msf_auxiliary.py +253 -130
- souleyez/plugins/msf_exploit.py +239 -161
- souleyez/plugins/nikto.py +134 -78
- souleyez/plugins/nmap.py +275 -91
- souleyez/plugins/nuclei.py +180 -89
- souleyez/plugins/nxc.py +285 -0
- souleyez/plugins/plugin_base.py +35 -36
- souleyez/plugins/plugin_template.py +13 -5
- souleyez/plugins/rdp_sec_check.py +130 -0
- souleyez/plugins/responder.py +112 -71
- souleyez/plugins/router_http_brute.py +76 -65
- souleyez/plugins/router_ssh_brute.py +118 -41
- souleyez/plugins/router_telnet_brute.py +124 -42
- souleyez/plugins/routersploit.py +91 -59
- souleyez/plugins/routersploit_exploit.py +77 -55
- souleyez/plugins/searchsploit.py +91 -77
- souleyez/plugins/service_explorer.py +1160 -0
- souleyez/plugins/smbmap.py +122 -72
- souleyez/plugins/smbpasswd.py +215 -0
- souleyez/plugins/sqlmap.py +301 -113
- souleyez/plugins/theharvester.py +127 -75
- souleyez/plugins/tr069.py +79 -57
- souleyez/plugins/upnp.py +65 -47
- souleyez/plugins/upnp_abuse.py +73 -55
- souleyez/plugins/vnc_access.py +129 -42
- souleyez/plugins/vnc_brute.py +109 -38
- souleyez/plugins/web_login_test.py +417 -0
- souleyez/plugins/whois.py +77 -58
- souleyez/plugins/wpscan.py +173 -69
- souleyez/reporting/__init__.py +2 -1
- souleyez/reporting/attack_chain.py +411 -346
- souleyez/reporting/charts.py +436 -501
- souleyez/reporting/compliance_mappings.py +334 -201
- souleyez/reporting/detection_report.py +126 -125
- souleyez/reporting/formatters.py +828 -591
- souleyez/reporting/generator.py +386 -302
- souleyez/reporting/metrics.py +72 -75
- souleyez/scanner.py +35 -29
- souleyez/security/__init__.py +37 -11
- souleyez/security/scope_validator.py +175 -106
- souleyez/security/validation.py +223 -149
- souleyez/security.py +22 -6
- souleyez/storage/credentials.py +247 -186
- souleyez/storage/crypto.py +296 -129
- souleyez/storage/database.py +73 -50
- souleyez/storage/db.py +58 -36
- souleyez/storage/deliverable_evidence.py +177 -128
- souleyez/storage/deliverable_exporter.py +282 -246
- souleyez/storage/deliverable_templates.py +134 -116
- souleyez/storage/deliverables.py +135 -130
- souleyez/storage/engagements.py +109 -56
- souleyez/storage/evidence.py +181 -152
- souleyez/storage/execution_log.py +31 -17
- souleyez/storage/exploit_attempts.py +93 -57
- souleyez/storage/exploits.py +67 -36
- souleyez/storage/findings.py +48 -61
- souleyez/storage/hosts.py +176 -144
- souleyez/storage/migrate_to_engagements.py +43 -19
- souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
- souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
- souleyez/storage/migrations/_003_add_execution_log.py +14 -8
- souleyez/storage/migrations/_005_screenshots.py +13 -5
- souleyez/storage/migrations/_006_deliverables.py +13 -5
- souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
- souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
- souleyez/storage/migrations/_010_evidence_linking.py +17 -10
- souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
- souleyez/storage/migrations/_012_team_collaboration.py +34 -21
- souleyez/storage/migrations/_013_add_host_tags.py +12 -6
- souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
- souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
- souleyez/storage/migrations/_016_add_domain_field.py +10 -4
- souleyez/storage/migrations/_017_msf_sessions.py +16 -8
- souleyez/storage/migrations/_018_add_osint_target.py +10 -6
- souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
- souleyez/storage/migrations/_020_add_rbac.py +36 -15
- souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
- souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
- souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
- souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
- souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
- souleyez/storage/migrations/__init__.py +26 -26
- souleyez/storage/migrations/migration_manager.py +19 -19
- souleyez/storage/msf_sessions.py +100 -65
- souleyez/storage/osint.py +17 -24
- souleyez/storage/recommendation_engine.py +269 -235
- souleyez/storage/screenshots.py +33 -32
- souleyez/storage/smb_shares.py +136 -92
- souleyez/storage/sqlmap_data.py +183 -128
- souleyez/storage/team_collaboration.py +135 -141
- souleyez/storage/timeline_tracker.py +122 -94
- souleyez/storage/wazuh_vulns.py +64 -66
- souleyez/storage/web_paths.py +33 -37
- souleyez/testing/credential_tester.py +221 -205
- souleyez/ui/__init__.py +1 -1
- souleyez/ui/ai_quotes.py +12 -12
- souleyez/ui/attack_surface.py +2439 -1516
- souleyez/ui/chain_rules_view.py +914 -382
- souleyez/ui/correlation_view.py +312 -230
- souleyez/ui/dashboard.py +2382 -1130
- souleyez/ui/deliverables_view.py +148 -62
- souleyez/ui/design_system.py +13 -13
- souleyez/ui/errors.py +49 -49
- souleyez/ui/evidence_linking_view.py +284 -179
- souleyez/ui/evidence_vault.py +393 -285
- souleyez/ui/exploit_suggestions_view.py +555 -349
- souleyez/ui/export_view.py +100 -66
- souleyez/ui/gap_analysis_view.py +315 -171
- souleyez/ui/help_system.py +105 -97
- souleyez/ui/intelligence_view.py +436 -293
- souleyez/ui/interactive.py +23434 -10286
- souleyez/ui/interactive_selector.py +75 -68
- souleyez/ui/log_formatter.py +47 -39
- souleyez/ui/menu_components.py +22 -13
- souleyez/ui/msf_auxiliary_menu.py +184 -133
- souleyez/ui/pending_chains_view.py +336 -172
- souleyez/ui/progress_indicators.py +5 -3
- souleyez/ui/recommendations_view.py +195 -137
- souleyez/ui/rule_builder.py +343 -225
- souleyez/ui/setup_wizard.py +678 -284
- souleyez/ui/shortcuts.py +217 -165
- souleyez/ui/splunk_gap_analysis_view.py +452 -270
- souleyez/ui/splunk_vulns_view.py +139 -86
- souleyez/ui/team_dashboard.py +498 -335
- souleyez/ui/template_selector.py +196 -105
- souleyez/ui/terminal.py +6 -6
- souleyez/ui/timeline_view.py +198 -127
- souleyez/ui/tool_setup.py +264 -164
- souleyez/ui/tutorial.py +202 -72
- souleyez/ui/tutorial_state.py +40 -40
- souleyez/ui/wazuh_vulns_view.py +235 -141
- souleyez/ui/wordlist_browser.py +260 -107
- souleyez/ui.py +464 -312
- souleyez/utils/tool_checker.py +427 -367
- souleyez/utils.py +33 -29
- souleyez/wordlists.py +134 -167
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
- souleyez-2.43.34.dist-info/RECORD +443 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
- souleyez-2.43.26.dist-info/RECORD +0 -379
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.26.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Metasploit auxiliary handler.
|
|
4
|
+
|
|
5
|
+
Consolidates parsing and display logic for msf_auxiliary jobs.
|
|
6
|
+
"""
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
from souleyez.engine.job_status import STATUS_DONE, STATUS_NO_RESULTS, STATUS_WARNING
|
|
15
|
+
from souleyez.handlers.base import BaseToolHandler
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MsfAuxiliaryHandler(BaseToolHandler):
|
|
21
|
+
"""Handler for Metasploit auxiliary module jobs."""
|
|
22
|
+
|
|
23
|
+
tool_name = "msf_auxiliary"
|
|
24
|
+
display_name = "Metasploit Auxiliary"
|
|
25
|
+
|
|
26
|
+
# All handlers enabled
|
|
27
|
+
has_error_handler = True
|
|
28
|
+
has_warning_handler = True
|
|
29
|
+
has_no_results_handler = True
|
|
30
|
+
has_done_handler = True
|
|
31
|
+
|
|
32
|
+
# Connection failure patterns
|
|
33
|
+
CONNECTION_FAILURE_PATTERNS = [
|
|
34
|
+
(r"Could not connect.*timed?\s*out", "Connection timed out"),
|
|
35
|
+
(r"Connection refused", "Connection refused"),
|
|
36
|
+
(r"Rex::ConnectionTimeout", "Connection timed out"),
|
|
37
|
+
(r"Rex::ConnectionRefused", "Connection refused"),
|
|
38
|
+
(r"No route to host", "No route to host"),
|
|
39
|
+
(r"Network is unreachable", "Network unreachable"),
|
|
40
|
+
(r"Login Failed.*Session Request failed", "SMB session request failed"),
|
|
41
|
+
(r"SMB Login Error", "SMB login error"),
|
|
42
|
+
(r"Connection reset by peer", "Connection reset"),
|
|
43
|
+
(r"Called name not present", "NetBIOS name not found"),
|
|
44
|
+
(r"DCERPC FAULT.*nca_s_fault_access_denied", "RPC access denied"),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def parse_job(
|
|
48
|
+
self,
|
|
49
|
+
engagement_id: int,
|
|
50
|
+
log_path: str,
|
|
51
|
+
job: Dict[str, Any],
|
|
52
|
+
host_manager: Optional[Any] = None,
|
|
53
|
+
findings_manager: Optional[Any] = None,
|
|
54
|
+
credentials_manager: Optional[Any] = None,
|
|
55
|
+
) -> Dict[str, Any]:
|
|
56
|
+
"""
|
|
57
|
+
Parse MSF auxiliary job results.
|
|
58
|
+
|
|
59
|
+
Extracts findings, credentials, and services from the output.
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
from souleyez.parsers.msf_parser import parse_msf_log
|
|
63
|
+
|
|
64
|
+
# Import managers if not provided
|
|
65
|
+
if host_manager is None:
|
|
66
|
+
from souleyez.storage.hosts import HostManager
|
|
67
|
+
|
|
68
|
+
host_manager = HostManager()
|
|
69
|
+
if findings_manager is None:
|
|
70
|
+
from souleyez.storage.findings import FindingsManager
|
|
71
|
+
|
|
72
|
+
findings_manager = FindingsManager()
|
|
73
|
+
if credentials_manager is None:
|
|
74
|
+
from souleyez.storage.credentials import CredentialsManager
|
|
75
|
+
|
|
76
|
+
credentials_manager = CredentialsManager()
|
|
77
|
+
|
|
78
|
+
# Read raw log for connection failure detection
|
|
79
|
+
with open(log_path, "r", encoding="utf-8", errors="replace") as f:
|
|
80
|
+
raw_content = f.read()
|
|
81
|
+
|
|
82
|
+
# Check for connection failures BEFORE parsing
|
|
83
|
+
connection_failure = False
|
|
84
|
+
failure_reason = None
|
|
85
|
+
for pattern, reason in self.CONNECTION_FAILURE_PATTERNS:
|
|
86
|
+
if re.search(pattern, raw_content, re.IGNORECASE):
|
|
87
|
+
connection_failure = True
|
|
88
|
+
failure_reason = reason
|
|
89
|
+
break
|
|
90
|
+
|
|
91
|
+
# Parse the log
|
|
92
|
+
parsed = parse_msf_log(log_path)
|
|
93
|
+
|
|
94
|
+
if "error" in parsed:
|
|
95
|
+
return {"error": parsed["error"]}
|
|
96
|
+
|
|
97
|
+
target = job.get("target", "")
|
|
98
|
+
|
|
99
|
+
services_added = 0
|
|
100
|
+
findings_added = 0
|
|
101
|
+
credentials_added = 0
|
|
102
|
+
finding_summaries = []
|
|
103
|
+
credential_summaries = []
|
|
104
|
+
|
|
105
|
+
# Get or create host
|
|
106
|
+
host = host_manager.get_host_by_ip(engagement_id, target)
|
|
107
|
+
if not host:
|
|
108
|
+
host_id = host_manager.add_host(engagement_id, target)
|
|
109
|
+
else:
|
|
110
|
+
host_id = host["id"]
|
|
111
|
+
|
|
112
|
+
# Add services if any
|
|
113
|
+
for svc in parsed.get("services", []):
|
|
114
|
+
host_manager.add_service(
|
|
115
|
+
host_id,
|
|
116
|
+
{
|
|
117
|
+
"port": svc.get("port"),
|
|
118
|
+
"protocol": svc.get("protocol", "tcp"),
|
|
119
|
+
"state": svc.get("state", "open"),
|
|
120
|
+
"service": svc.get("service_name"),
|
|
121
|
+
"version": svc.get("service_version"),
|
|
122
|
+
},
|
|
123
|
+
)
|
|
124
|
+
services_added += 1
|
|
125
|
+
|
|
126
|
+
# Add findings
|
|
127
|
+
for finding in parsed.get("findings", []):
|
|
128
|
+
findings_manager.add_finding(
|
|
129
|
+
engagement_id=engagement_id,
|
|
130
|
+
host_id=host_id,
|
|
131
|
+
title=finding.get("title"),
|
|
132
|
+
finding_type=(
|
|
133
|
+
"credential"
|
|
134
|
+
if "credential" in finding.get("title", "").lower()
|
|
135
|
+
else "security_issue"
|
|
136
|
+
),
|
|
137
|
+
severity=finding.get("severity", "info"),
|
|
138
|
+
description=finding.get("description"),
|
|
139
|
+
tool="msf_auxiliary",
|
|
140
|
+
port=finding.get("port"),
|
|
141
|
+
)
|
|
142
|
+
findings_added += 1
|
|
143
|
+
finding_summaries.append(
|
|
144
|
+
{
|
|
145
|
+
"title": finding.get("title"),
|
|
146
|
+
"severity": finding.get("severity", "info"),
|
|
147
|
+
"description": finding.get("description", "")[:200],
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Add credentials if any
|
|
152
|
+
for cred in parsed.get("credentials", []):
|
|
153
|
+
credentials_manager.add_credential(
|
|
154
|
+
engagement_id=engagement_id,
|
|
155
|
+
host_id=host_id,
|
|
156
|
+
service=cred.get("service", "unknown"),
|
|
157
|
+
username=cred.get("username", ""),
|
|
158
|
+
password=cred.get("password", ""),
|
|
159
|
+
credential_type="password",
|
|
160
|
+
tool="msf_auxiliary",
|
|
161
|
+
port=cred.get("port"),
|
|
162
|
+
status=cred.get("status", "valid"),
|
|
163
|
+
)
|
|
164
|
+
credentials_added += 1
|
|
165
|
+
credential_summaries.append(
|
|
166
|
+
{
|
|
167
|
+
"username": cred.get("username", ""),
|
|
168
|
+
"service": cred.get("service", "unknown"),
|
|
169
|
+
"port": cred.get("port"),
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Determine status and summary
|
|
174
|
+
has_results = (
|
|
175
|
+
services_added > 0 or findings_added > 0 or credentials_added > 0
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
if has_results:
|
|
179
|
+
final_status = STATUS_DONE
|
|
180
|
+
summary = (
|
|
181
|
+
f"Found {findings_added} findings, {credentials_added} credentials"
|
|
182
|
+
)
|
|
183
|
+
elif connection_failure:
|
|
184
|
+
final_status = STATUS_WARNING
|
|
185
|
+
summary = f"Target unreachable: {failure_reason}"
|
|
186
|
+
else:
|
|
187
|
+
final_status = STATUS_NO_RESULTS
|
|
188
|
+
summary = "No results found (target responded but nothing discovered)"
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
"tool": "msf_auxiliary",
|
|
192
|
+
"status": final_status,
|
|
193
|
+
"summary": summary,
|
|
194
|
+
"host": target,
|
|
195
|
+
"services_added": services_added,
|
|
196
|
+
"findings_added": findings_added,
|
|
197
|
+
"credentials_added": credentials_added,
|
|
198
|
+
"findings": finding_summaries,
|
|
199
|
+
"credentials": credential_summaries,
|
|
200
|
+
}
|
|
201
|
+
except Exception as e:
|
|
202
|
+
logger.error(f"Error parsing msf_auxiliary job: {e}")
|
|
203
|
+
return {"error": str(e)}
|
|
204
|
+
|
|
205
|
+
def display_done(
|
|
206
|
+
self,
|
|
207
|
+
job: Dict[str, Any],
|
|
208
|
+
log_path: str,
|
|
209
|
+
show_all: bool = False,
|
|
210
|
+
show_passwords: bool = False,
|
|
211
|
+
) -> None:
|
|
212
|
+
"""Display successful auxiliary scan results."""
|
|
213
|
+
try:
|
|
214
|
+
from souleyez.parsers.msf_parser import parse_msf_log
|
|
215
|
+
|
|
216
|
+
if not log_path or not os.path.exists(log_path):
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
parsed = parse_msf_log(log_path)
|
|
220
|
+
findings = parsed.get("findings", [])
|
|
221
|
+
credentials = parsed.get("credentials", [])
|
|
222
|
+
services = parsed.get("services", [])
|
|
223
|
+
|
|
224
|
+
if not findings and not credentials and not services:
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
click.echo(click.style("=" * 70, fg="cyan"))
|
|
228
|
+
click.echo(click.style("PARSED RESULTS", bold=True, fg="cyan"))
|
|
229
|
+
click.echo(click.style("=" * 70, fg="cyan"))
|
|
230
|
+
click.echo()
|
|
231
|
+
|
|
232
|
+
# Show findings
|
|
233
|
+
if findings:
|
|
234
|
+
severity_colors = {
|
|
235
|
+
"critical": "red",
|
|
236
|
+
"high": "red",
|
|
237
|
+
"medium": "yellow",
|
|
238
|
+
"low": "blue",
|
|
239
|
+
"info": "cyan",
|
|
240
|
+
}
|
|
241
|
+
click.echo(click.style(f"Findings ({len(findings)}):", bold=True))
|
|
242
|
+
for f in findings[:10]:
|
|
243
|
+
sev = f.get("severity", "info")
|
|
244
|
+
color = severity_colors.get(sev, "white")
|
|
245
|
+
title = f.get("title", "Unknown")
|
|
246
|
+
click.echo(click.style(f" [{sev.upper()}] ", fg=color) + title)
|
|
247
|
+
# Show description if it has useful details
|
|
248
|
+
desc = f.get("description", "")
|
|
249
|
+
if desc and desc != title and len(desc) > len(title):
|
|
250
|
+
if len(desc) > 120:
|
|
251
|
+
desc = desc[:117] + "..."
|
|
252
|
+
click.echo(click.style(f" {desc}", fg="bright_black"))
|
|
253
|
+
if len(findings) > 10:
|
|
254
|
+
click.echo(f" ... and {len(findings) - 10} more findings")
|
|
255
|
+
click.echo()
|
|
256
|
+
|
|
257
|
+
# Show credentials
|
|
258
|
+
if credentials:
|
|
259
|
+
click.echo(click.style(f"Credentials ({len(credentials)}):", bold=True))
|
|
260
|
+
creds_to_show = credentials if show_all else credentials[:5]
|
|
261
|
+
for c in creds_to_show:
|
|
262
|
+
user = c.get("username", "")
|
|
263
|
+
pwd = c.get("password", "")
|
|
264
|
+
svc = c.get("service", "unknown")
|
|
265
|
+
if pwd and show_passwords:
|
|
266
|
+
click.echo(click.style(f" {svc}: {user}:{pwd}", fg="green"))
|
|
267
|
+
elif pwd:
|
|
268
|
+
click.echo(click.style(f" {svc}: {user}:******", fg="green"))
|
|
269
|
+
else:
|
|
270
|
+
click.echo(f" {svc}: {user} (username only)")
|
|
271
|
+
if not show_all and len(credentials) > 5:
|
|
272
|
+
click.echo(
|
|
273
|
+
click.style(
|
|
274
|
+
f" ... and {len(credentials) - 5} more (press [x] to expand)",
|
|
275
|
+
fg="bright_black",
|
|
276
|
+
)
|
|
277
|
+
)
|
|
278
|
+
click.echo()
|
|
279
|
+
|
|
280
|
+
# Show services
|
|
281
|
+
if services:
|
|
282
|
+
click.echo(click.style(f"Services ({len(services)}):", bold=True))
|
|
283
|
+
for s in services[:5]:
|
|
284
|
+
port = s.get("port", "?")
|
|
285
|
+
name = s.get("service_name", "unknown")
|
|
286
|
+
ver = s.get("service_version", "")
|
|
287
|
+
click.echo(f" {port}/{name}: {ver}" if ver else f" {port}/{name}")
|
|
288
|
+
if len(services) > 5:
|
|
289
|
+
click.echo(f" ... and {len(services) - 5} more services")
|
|
290
|
+
click.echo()
|
|
291
|
+
|
|
292
|
+
click.echo(click.style("=" * 70, fg="cyan"))
|
|
293
|
+
click.echo()
|
|
294
|
+
except Exception as e:
|
|
295
|
+
logger.debug(f"Error in display_done: {e}")
|
|
296
|
+
|
|
297
|
+
def display_warning(
|
|
298
|
+
self,
|
|
299
|
+
job: Dict[str, Any],
|
|
300
|
+
log_path: str,
|
|
301
|
+
log_content: Optional[str] = None,
|
|
302
|
+
) -> None:
|
|
303
|
+
"""Display warning status for auxiliary scan."""
|
|
304
|
+
parse_result = job.get("parse_result", {})
|
|
305
|
+
summary = "Auxiliary scan failed"
|
|
306
|
+
if isinstance(parse_result, dict):
|
|
307
|
+
summary = parse_result.get("summary", "Auxiliary scan failed")
|
|
308
|
+
|
|
309
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
310
|
+
click.echo(
|
|
311
|
+
click.style("[WARNING] METASPLOIT AUXILIARY", bold=True, fg="yellow")
|
|
312
|
+
)
|
|
313
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
314
|
+
click.echo()
|
|
315
|
+
click.echo(f" {summary}")
|
|
316
|
+
click.echo()
|
|
317
|
+
click.echo(click.style(" Common causes:", fg="bright_black"))
|
|
318
|
+
click.echo(
|
|
319
|
+
click.style(
|
|
320
|
+
" - Target unreachable (firewall, network issue)", fg="bright_black"
|
|
321
|
+
)
|
|
322
|
+
)
|
|
323
|
+
click.echo(
|
|
324
|
+
click.style(" - Service not running on expected port", fg="bright_black")
|
|
325
|
+
)
|
|
326
|
+
click.echo(click.style(" - Connection timed out", fg="bright_black"))
|
|
327
|
+
click.echo()
|
|
328
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
329
|
+
click.echo()
|
|
330
|
+
|
|
331
|
+
def display_error(
|
|
332
|
+
self,
|
|
333
|
+
job: Dict[str, Any],
|
|
334
|
+
log_path: str,
|
|
335
|
+
log_content: Optional[str] = None,
|
|
336
|
+
) -> None:
|
|
337
|
+
"""Display error status for auxiliary scan."""
|
|
338
|
+
# Read log if not provided
|
|
339
|
+
if log_content is None and log_path and os.path.exists(log_path):
|
|
340
|
+
try:
|
|
341
|
+
with open(log_path, "r", encoding="utf-8", errors="replace") as f:
|
|
342
|
+
log_content = f.read()
|
|
343
|
+
except Exception:
|
|
344
|
+
log_content = ""
|
|
345
|
+
|
|
346
|
+
click.echo(click.style("=" * 70, fg="red"))
|
|
347
|
+
click.echo(
|
|
348
|
+
click.style("[ERROR] METASPLOIT AUXILIARY FAILED", bold=True, fg="red")
|
|
349
|
+
)
|
|
350
|
+
click.echo(click.style("=" * 70, fg="red"))
|
|
351
|
+
click.echo()
|
|
352
|
+
|
|
353
|
+
# Check for common MSF errors
|
|
354
|
+
error_msg = None
|
|
355
|
+
if log_content:
|
|
356
|
+
if "Connection refused" in log_content:
|
|
357
|
+
error_msg = "Connection refused - target service may be down"
|
|
358
|
+
elif "timed out" in log_content.lower() or "timeout" in log_content.lower():
|
|
359
|
+
error_msg = "Connection timed out - target may be slow or filtering"
|
|
360
|
+
elif "Exploit failed" in log_content:
|
|
361
|
+
error_msg = "Exploit failed - target may not be vulnerable"
|
|
362
|
+
elif "Module not found" in log_content or "Unknown module" in log_content:
|
|
363
|
+
error_msg = "Module not found - check module name"
|
|
364
|
+
elif "Required option" in log_content:
|
|
365
|
+
match = re.search(
|
|
366
|
+
r'Required option\s*[\'"]?(\w+)[\'"]?\s*is missing', log_content
|
|
367
|
+
)
|
|
368
|
+
if match:
|
|
369
|
+
error_msg = f"Required option '{match.group(1)}' is missing"
|
|
370
|
+
elif "[-]" in log_content:
|
|
371
|
+
match = re.search(r"\[-\]\s*(.+?)(?:\n|$)", log_content)
|
|
372
|
+
if match:
|
|
373
|
+
error_msg = match.group(1).strip()[:100]
|
|
374
|
+
|
|
375
|
+
if error_msg:
|
|
376
|
+
click.echo(f" {error_msg}")
|
|
377
|
+
else:
|
|
378
|
+
click.echo(" Module failed - see raw logs for details (press 'r')")
|
|
379
|
+
|
|
380
|
+
click.echo()
|
|
381
|
+
click.echo(click.style("=" * 70, fg="red"))
|
|
382
|
+
click.echo()
|
|
383
|
+
|
|
384
|
+
def display_no_results(
|
|
385
|
+
self,
|
|
386
|
+
job: Dict[str, Any],
|
|
387
|
+
log_path: str,
|
|
388
|
+
) -> None:
|
|
389
|
+
"""Display no_results status for auxiliary scan."""
|
|
390
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
391
|
+
click.echo(click.style("METASPLOIT AUXILIARY RESULTS", bold=True, fg="yellow"))
|
|
392
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
393
|
+
click.echo()
|
|
394
|
+
click.echo(" No results found.")
|
|
395
|
+
click.echo()
|
|
396
|
+
click.echo(
|
|
397
|
+
click.style(
|
|
398
|
+
" The target responded but the module found nothing.",
|
|
399
|
+
fg="bright_black",
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
click.echo(click.style(" This could mean:", fg="bright_black"))
|
|
403
|
+
click.echo(click.style(" - Service is not vulnerable", fg="bright_black"))
|
|
404
|
+
click.echo(click.style(" - No valid credentials found", fg="bright_black"))
|
|
405
|
+
click.echo(click.style(" - No matching configuration", fg="bright_black"))
|
|
406
|
+
click.echo()
|
|
407
|
+
click.echo(click.style("=" * 70, fg="yellow"))
|
|
408
|
+
click.echo()
|