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
|
@@ -4,6 +4,7 @@ SIEM Configuration Management.
|
|
|
4
4
|
Stores SIEM connection settings with encrypted credentials.
|
|
5
5
|
Supports multiple SIEM platforms: Wazuh, Splunk, Elastic, Sentinel.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import json
|
|
8
9
|
from typing import Optional, Dict, Any, List
|
|
9
10
|
from pathlib import Path
|
|
@@ -11,7 +12,7 @@ from souleyez.storage.database import get_db
|
|
|
11
12
|
from souleyez.storage.crypto import get_crypto_manager
|
|
12
13
|
|
|
13
14
|
# Supported SIEM types (Open Source first, then Commercial)
|
|
14
|
-
SIEM_TYPES = [
|
|
15
|
+
SIEM_TYPES = ["wazuh", "elastic", "splunk", "sentinel", "google_secops"]
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class WazuhConfig:
|
|
@@ -22,7 +23,9 @@ class WazuhConfig:
|
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
25
|
@staticmethod
|
|
25
|
-
def get_config(
|
|
26
|
+
def get_config(
|
|
27
|
+
engagement_id: int, siem_type: str = None
|
|
28
|
+
) -> Optional[Dict[str, Any]]:
|
|
26
29
|
"""
|
|
27
30
|
Get SIEM config for an engagement.
|
|
28
31
|
|
|
@@ -40,35 +43,44 @@ class WazuhConfig:
|
|
|
40
43
|
# Check if new columns exist (migration 025+)
|
|
41
44
|
cursor.execute("PRAGMA table_info(wazuh_config)")
|
|
42
45
|
columns = [col[1] for col in cursor.fetchall()]
|
|
43
|
-
has_new_columns =
|
|
46
|
+
has_new_columns = "siem_type" in columns
|
|
44
47
|
|
|
45
48
|
# Query with or without new columns
|
|
46
49
|
if has_new_columns:
|
|
47
50
|
if siem_type:
|
|
48
|
-
cursor.execute(
|
|
51
|
+
cursor.execute(
|
|
52
|
+
"""
|
|
49
53
|
SELECT api_url, api_user, api_password, indexer_url, indexer_user,
|
|
50
54
|
indexer_password, verify_ssl, enabled, siem_type, config_json
|
|
51
55
|
FROM wazuh_config
|
|
52
56
|
WHERE engagement_id = ? AND siem_type = ?
|
|
53
|
-
""",
|
|
57
|
+
""",
|
|
58
|
+
(engagement_id, siem_type),
|
|
59
|
+
)
|
|
54
60
|
else:
|
|
55
61
|
# Get most recently updated config (the "current" selected SIEM)
|
|
56
62
|
# Not filtering by enabled - user may have selected but not configured yet
|
|
57
|
-
cursor.execute(
|
|
63
|
+
cursor.execute(
|
|
64
|
+
"""
|
|
58
65
|
SELECT api_url, api_user, api_password, indexer_url, indexer_user,
|
|
59
66
|
indexer_password, verify_ssl, enabled, siem_type, config_json
|
|
60
67
|
FROM wazuh_config
|
|
61
68
|
WHERE engagement_id = ?
|
|
62
69
|
ORDER BY updated_at DESC
|
|
63
70
|
LIMIT 1
|
|
64
|
-
""",
|
|
71
|
+
""",
|
|
72
|
+
(engagement_id,),
|
|
73
|
+
)
|
|
65
74
|
else:
|
|
66
|
-
cursor.execute(
|
|
75
|
+
cursor.execute(
|
|
76
|
+
"""
|
|
67
77
|
SELECT api_url, api_user, api_password, indexer_url, indexer_user,
|
|
68
78
|
indexer_password, verify_ssl, enabled
|
|
69
79
|
FROM wazuh_config
|
|
70
80
|
WHERE engagement_id = ?
|
|
71
|
-
""",
|
|
81
|
+
""",
|
|
82
|
+
(engagement_id,),
|
|
83
|
+
)
|
|
72
84
|
|
|
73
85
|
row = cursor.fetchone()
|
|
74
86
|
if not row:
|
|
@@ -107,7 +119,7 @@ class WazuhConfig:
|
|
|
107
119
|
# Decrypt any encrypted fields in extra config
|
|
108
120
|
crypto = get_crypto_manager()
|
|
109
121
|
if crypto and extra_config:
|
|
110
|
-
for key in [
|
|
122
|
+
for key in ["password", "client_secret", "api_key", "token"]:
|
|
111
123
|
if key in extra_config and extra_config[key]:
|
|
112
124
|
try:
|
|
113
125
|
extra_config[key] = crypto.decrypt(extra_config[key])
|
|
@@ -118,9 +130,9 @@ class WazuhConfig:
|
|
|
118
130
|
pass
|
|
119
131
|
|
|
120
132
|
# Map Wazuh fields to generic names for SIEMFactory compatibility
|
|
121
|
-
if config[
|
|
122
|
-
config[
|
|
123
|
-
config[
|
|
133
|
+
if config["siem_type"] == "wazuh":
|
|
134
|
+
config["username"] = config.get("api_user")
|
|
135
|
+
config["password"] = config.get("api_password")
|
|
124
136
|
|
|
125
137
|
return config
|
|
126
138
|
|
|
@@ -130,14 +142,12 @@ class WazuhConfig:
|
|
|
130
142
|
cursor.execute("PRAGMA table_info(wazuh_config)")
|
|
131
143
|
columns = [col[1] for col in cursor.fetchall()]
|
|
132
144
|
|
|
133
|
-
if
|
|
145
|
+
if "siem_type" not in columns:
|
|
134
146
|
cursor.execute(
|
|
135
147
|
"ALTER TABLE wazuh_config ADD COLUMN siem_type TEXT DEFAULT 'wazuh'"
|
|
136
148
|
)
|
|
137
|
-
if
|
|
138
|
-
cursor.execute(
|
|
139
|
-
"ALTER TABLE wazuh_config ADD COLUMN config_json TEXT"
|
|
140
|
-
)
|
|
149
|
+
if "config_json" not in columns:
|
|
150
|
+
cursor.execute("ALTER TABLE wazuh_config ADD COLUMN config_json TEXT")
|
|
141
151
|
conn.commit()
|
|
142
152
|
|
|
143
153
|
@staticmethod
|
|
@@ -152,7 +162,7 @@ class WazuhConfig:
|
|
|
152
162
|
verify_ssl: bool = False,
|
|
153
163
|
enabled: bool = True,
|
|
154
164
|
siem_type: str = "wazuh",
|
|
155
|
-
config_json: Optional[Dict[str, Any]] = None
|
|
165
|
+
config_json: Optional[Dict[str, Any]] = None,
|
|
156
166
|
) -> bool:
|
|
157
167
|
"""
|
|
158
168
|
Save SIEM config for an engagement.
|
|
@@ -199,15 +209,18 @@ class WazuhConfig:
|
|
|
199
209
|
try:
|
|
200
210
|
crypto = get_crypto_manager()
|
|
201
211
|
if crypto:
|
|
202
|
-
for key in [
|
|
212
|
+
for key in ["password", "client_secret", "api_key", "token"]:
|
|
203
213
|
if key in encrypted_config and encrypted_config[key]:
|
|
204
|
-
encrypted_config[key] = crypto.encrypt(
|
|
214
|
+
encrypted_config[key] = crypto.encrypt(
|
|
215
|
+
encrypted_config[key]
|
|
216
|
+
)
|
|
205
217
|
except Exception:
|
|
206
218
|
pass
|
|
207
219
|
config_json_str = json.dumps(encrypted_config)
|
|
208
220
|
|
|
209
221
|
# Upsert config - keyed by (engagement_id, siem_type) for multi-SIEM support
|
|
210
|
-
cursor.execute(
|
|
222
|
+
cursor.execute(
|
|
223
|
+
"""
|
|
211
224
|
INSERT INTO wazuh_config (
|
|
212
225
|
engagement_id, api_url, api_user, api_password, indexer_url,
|
|
213
226
|
indexer_user, indexer_password, verify_ssl, enabled,
|
|
@@ -225,21 +238,28 @@ class WazuhConfig:
|
|
|
225
238
|
enabled = excluded.enabled,
|
|
226
239
|
config_json = excluded.config_json,
|
|
227
240
|
updated_at = CURRENT_TIMESTAMP
|
|
228
|
-
""",
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
""",
|
|
242
|
+
(
|
|
243
|
+
engagement_id,
|
|
244
|
+
api_url,
|
|
245
|
+
api_user,
|
|
246
|
+
encrypted_api_password,
|
|
247
|
+
indexer_url,
|
|
248
|
+
indexer_user or "admin",
|
|
249
|
+
encrypted_indexer_password,
|
|
250
|
+
verify_ssl,
|
|
251
|
+
enabled,
|
|
252
|
+
siem_type,
|
|
253
|
+
config_json_str,
|
|
254
|
+
),
|
|
255
|
+
)
|
|
233
256
|
|
|
234
257
|
conn.commit()
|
|
235
258
|
return True
|
|
236
259
|
|
|
237
260
|
@staticmethod
|
|
238
261
|
def save_siem_config(
|
|
239
|
-
engagement_id: int,
|
|
240
|
-
siem_type: str,
|
|
241
|
-
config: Dict[str, Any],
|
|
242
|
-
enabled: bool = True
|
|
262
|
+
engagement_id: int, siem_type: str, config: Dict[str, Any], enabled: bool = True
|
|
243
263
|
) -> bool:
|
|
244
264
|
"""
|
|
245
265
|
Save configuration for any SIEM type.
|
|
@@ -252,29 +272,29 @@ class WazuhConfig:
|
|
|
252
272
|
config: SIEM-specific configuration dict
|
|
253
273
|
enabled: Whether integration is enabled
|
|
254
274
|
"""
|
|
255
|
-
if siem_type ==
|
|
275
|
+
if siem_type == "wazuh":
|
|
256
276
|
# Use existing Wazuh fields for backwards compatibility
|
|
257
277
|
return WazuhConfig.save_config(
|
|
258
278
|
engagement_id=engagement_id,
|
|
259
|
-
api_url=config.get(
|
|
260
|
-
api_user=config.get(
|
|
261
|
-
api_password=config.get(
|
|
262
|
-
indexer_url=config.get(
|
|
263
|
-
indexer_user=config.get(
|
|
264
|
-
indexer_password=config.get(
|
|
265
|
-
verify_ssl=config.get(
|
|
279
|
+
api_url=config.get("api_url", ""),
|
|
280
|
+
api_user=config.get("username", config.get("api_user", "")),
|
|
281
|
+
api_password=config.get("password", config.get("api_password", "")),
|
|
282
|
+
indexer_url=config.get("indexer_url"),
|
|
283
|
+
indexer_user=config.get("indexer_user"),
|
|
284
|
+
indexer_password=config.get("indexer_password"),
|
|
285
|
+
verify_ssl=config.get("verify_ssl", False),
|
|
266
286
|
enabled=enabled,
|
|
267
|
-
siem_type=
|
|
287
|
+
siem_type="wazuh",
|
|
268
288
|
)
|
|
269
289
|
else:
|
|
270
290
|
# For other SIEMs, store config in config_json
|
|
271
291
|
return WazuhConfig.save_config(
|
|
272
292
|
engagement_id=engagement_id,
|
|
273
|
-
api_url=config.get(
|
|
274
|
-
verify_ssl=config.get(
|
|
293
|
+
api_url=config.get("api_url", config.get("elasticsearch_url", "")),
|
|
294
|
+
verify_ssl=config.get("verify_ssl", False),
|
|
275
295
|
enabled=enabled,
|
|
276
296
|
siem_type=siem_type,
|
|
277
|
-
config_json=config
|
|
297
|
+
config_json=config,
|
|
278
298
|
)
|
|
279
299
|
|
|
280
300
|
@staticmethod
|
|
@@ -292,10 +312,12 @@ class WazuhConfig:
|
|
|
292
312
|
if siem_type:
|
|
293
313
|
cursor.execute(
|
|
294
314
|
"DELETE FROM wazuh_config WHERE engagement_id = ? AND siem_type = ?",
|
|
295
|
-
(engagement_id, siem_type)
|
|
315
|
+
(engagement_id, siem_type),
|
|
296
316
|
)
|
|
297
317
|
else:
|
|
298
|
-
cursor.execute(
|
|
318
|
+
cursor.execute(
|
|
319
|
+
"DELETE FROM wazuh_config WHERE engagement_id = ?", (engagement_id,)
|
|
320
|
+
)
|
|
299
321
|
conn.commit()
|
|
300
322
|
return cursor.rowcount > 0
|
|
301
323
|
|
|
@@ -320,28 +342,34 @@ class WazuhConfig:
|
|
|
320
342
|
cursor.execute("PRAGMA table_info(wazuh_config)")
|
|
321
343
|
columns = [col[1] for col in cursor.fetchall()]
|
|
322
344
|
|
|
323
|
-
if
|
|
345
|
+
if "siem_type" not in columns:
|
|
324
346
|
# Old schema - only one config possible
|
|
325
|
-
cursor.execute(
|
|
347
|
+
cursor.execute(
|
|
348
|
+
"""
|
|
326
349
|
SELECT 'wazuh' as siem_type, enabled, api_url
|
|
327
350
|
FROM wazuh_config
|
|
328
351
|
WHERE engagement_id = ?
|
|
329
|
-
""",
|
|
352
|
+
""",
|
|
353
|
+
(engagement_id,),
|
|
354
|
+
)
|
|
330
355
|
else:
|
|
331
|
-
cursor.execute(
|
|
356
|
+
cursor.execute(
|
|
357
|
+
"""
|
|
332
358
|
SELECT siem_type, enabled, api_url, updated_at
|
|
333
359
|
FROM wazuh_config
|
|
334
360
|
WHERE engagement_id = ?
|
|
335
361
|
ORDER BY siem_type
|
|
336
|
-
""",
|
|
362
|
+
""",
|
|
363
|
+
(engagement_id,),
|
|
364
|
+
)
|
|
337
365
|
|
|
338
366
|
rows = cursor.fetchall()
|
|
339
367
|
return [
|
|
340
368
|
{
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
369
|
+
"siem_type": row[0],
|
|
370
|
+
"enabled": bool(row[1]),
|
|
371
|
+
"api_url": row[2],
|
|
372
|
+
"updated_at": row[3] if len(row) > 3 else None,
|
|
345
373
|
}
|
|
346
374
|
for row in rows
|
|
347
375
|
]
|
|
@@ -373,8 +401,8 @@ class WazuhConfig:
|
|
|
373
401
|
"""
|
|
374
402
|
config = WazuhConfig.get_config(engagement_id)
|
|
375
403
|
if config:
|
|
376
|
-
return config.get(
|
|
377
|
-
return
|
|
404
|
+
return config.get("siem_type", "wazuh")
|
|
405
|
+
return "wazuh"
|
|
378
406
|
|
|
379
407
|
@staticmethod
|
|
380
408
|
def set_current_siem(engagement_id: int, siem_type: str) -> bool:
|
|
@@ -395,7 +423,7 @@ class WazuhConfig:
|
|
|
395
423
|
cursor = conn.cursor()
|
|
396
424
|
cursor.execute(
|
|
397
425
|
"UPDATE wazuh_config SET updated_at = CURRENT_TIMESTAMP WHERE engagement_id = ? AND siem_type = ?",
|
|
398
|
-
(engagement_id, siem_type)
|
|
426
|
+
(engagement_id, siem_type),
|
|
399
427
|
)
|
|
400
428
|
conn.commit()
|
|
401
429
|
return cursor.rowcount > 0
|
|
@@ -17,11 +17,7 @@ class WazuhHostMapper:
|
|
|
17
17
|
def __init__(self):
|
|
18
18
|
self.db = get_db()
|
|
19
19
|
|
|
20
|
-
def map_agent_to_host(
|
|
21
|
-
self,
|
|
22
|
-
engagement_id: int,
|
|
23
|
-
agent_ip: str
|
|
24
|
-
) -> Optional[int]:
|
|
20
|
+
def map_agent_to_host(self, engagement_id: int, agent_ip: str) -> Optional[int]:
|
|
25
21
|
"""
|
|
26
22
|
Find SoulEyez host_id matching an agent IP.
|
|
27
23
|
|
|
@@ -42,7 +38,7 @@ class WazuhHostMapper:
|
|
|
42
38
|
result = self.db.execute_one(query, (engagement_id, agent_ip))
|
|
43
39
|
|
|
44
40
|
if result:
|
|
45
|
-
return result[
|
|
41
|
+
return result["id"]
|
|
46
42
|
|
|
47
43
|
return None
|
|
48
44
|
|
|
@@ -66,7 +62,7 @@ class WazuhHostMapper:
|
|
|
66
62
|
|
|
67
63
|
mapping = {}
|
|
68
64
|
for agent in agents:
|
|
69
|
-
agent_ip = agent.get(
|
|
65
|
+
agent_ip = agent.get("agent_ip")
|
|
70
66
|
if agent_ip:
|
|
71
67
|
host_id = self.map_agent_to_host(engagement_id, agent_ip)
|
|
72
68
|
mapping[agent_ip] = host_id
|
|
@@ -78,10 +74,7 @@ class WazuhHostMapper:
|
|
|
78
74
|
return mapping
|
|
79
75
|
|
|
80
76
|
def _update_vuln_host_mapping(
|
|
81
|
-
self,
|
|
82
|
-
engagement_id: int,
|
|
83
|
-
agent_ip: str,
|
|
84
|
-
host_id: int
|
|
77
|
+
self, engagement_id: int, agent_ip: str, host_id: int
|
|
85
78
|
) -> int:
|
|
86
79
|
"""
|
|
87
80
|
Update all vulnerabilities from an agent IP with the host_id.
|
|
@@ -103,7 +96,7 @@ class WazuhHostMapper:
|
|
|
103
96
|
WHERE engagement_id = ? AND agent_ip = ? AND host_id = ?
|
|
104
97
|
"""
|
|
105
98
|
result = self.db.execute_one(count_query, (engagement_id, agent_ip, host_id))
|
|
106
|
-
return result.get(
|
|
99
|
+
return result.get("count", 0) if result else 0
|
|
107
100
|
|
|
108
101
|
def get_unmapped_agents(self, engagement_id: int) -> List[Dict[str, any]]:
|
|
109
102
|
"""
|
|
@@ -167,18 +160,15 @@ class WazuhHostMapper:
|
|
|
167
160
|
|
|
168
161
|
if result:
|
|
169
162
|
return {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
163
|
+
"mapped": result.get("mapped", 0) or 0,
|
|
164
|
+
"unmapped": result.get("unmapped", 0) or 0,
|
|
165
|
+
"total": result.get("total", 0) or 0,
|
|
173
166
|
}
|
|
174
167
|
|
|
175
|
-
return {
|
|
168
|
+
return {"mapped": 0, "unmapped": 0, "total": 0}
|
|
176
169
|
|
|
177
170
|
def manual_map(
|
|
178
|
-
self,
|
|
179
|
-
engagement_id: int,
|
|
180
|
-
agent_ip: str,
|
|
181
|
-
host_id: int
|
|
171
|
+
self, engagement_id: int, agent_ip: str, host_id: int
|
|
182
172
|
) -> Tuple[bool, int]:
|
|
183
173
|
"""
|
|
184
174
|
Manually map an agent IP to a host.
|
|
@@ -225,7 +215,7 @@ class WazuhHostMapper:
|
|
|
225
215
|
WHERE engagement_id = ? AND agent_ip = ? AND host_id IS NULL
|
|
226
216
|
"""
|
|
227
217
|
result = self.db.execute_one(count_query, (engagement_id, agent_ip))
|
|
228
|
-
return result.get(
|
|
218
|
+
return result.get("count", 0) if result else 0
|
|
229
219
|
|
|
230
220
|
def suggest_mappings(self, engagement_id: int) -> List[Dict[str, any]]:
|
|
231
221
|
"""
|
|
@@ -250,38 +240,40 @@ class WazuhHostMapper:
|
|
|
250
240
|
suggestions = []
|
|
251
241
|
|
|
252
242
|
for agent in unmapped:
|
|
253
|
-
agent_ip = agent.get(
|
|
243
|
+
agent_ip = agent.get("agent_ip")
|
|
254
244
|
if not agent_ip:
|
|
255
245
|
continue
|
|
256
246
|
|
|
257
247
|
# Try to find hosts in same subnet
|
|
258
|
-
agent_parts = agent_ip.split(
|
|
248
|
+
agent_parts = agent_ip.split(".")
|
|
259
249
|
if len(agent_parts) != 4:
|
|
260
250
|
continue
|
|
261
251
|
|
|
262
|
-
agent_subnet =
|
|
252
|
+
agent_subnet = ".".join(agent_parts[:3])
|
|
263
253
|
|
|
264
254
|
for host in hosts:
|
|
265
|
-
host_ip = host.get(
|
|
255
|
+
host_ip = host.get("ip_address")
|
|
266
256
|
if not host_ip:
|
|
267
257
|
continue
|
|
268
258
|
|
|
269
|
-
host_parts = host_ip.split(
|
|
259
|
+
host_parts = host_ip.split(".")
|
|
270
260
|
if len(host_parts) != 4:
|
|
271
261
|
continue
|
|
272
262
|
|
|
273
|
-
host_subnet =
|
|
263
|
+
host_subnet = ".".join(host_parts[:3])
|
|
274
264
|
|
|
275
265
|
# Same subnet = possible match
|
|
276
266
|
if agent_subnet == host_subnet:
|
|
277
|
-
suggestions.append(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
267
|
+
suggestions.append(
|
|
268
|
+
{
|
|
269
|
+
"agent_ip": agent_ip,
|
|
270
|
+
"agent_name": agent.get("agent_name"),
|
|
271
|
+
"suggested_host_id": host["id"],
|
|
272
|
+
"suggested_host_ip": host_ip,
|
|
273
|
+
"suggested_host_name": host.get("hostname"),
|
|
274
|
+
"confidence": "medium",
|
|
275
|
+
"reason": "Same subnet",
|
|
276
|
+
}
|
|
277
|
+
)
|
|
286
278
|
|
|
287
279
|
return suggestions
|