souleyez 2.43.29__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.
- 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 +22827 -10678
- 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.29.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
- souleyez-2.43.34.dist-info/RECORD +443 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
- souleyez-2.43.29.dist-info/RECORD +0 -379
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
|
@@ -10,41 +10,41 @@ from typing import Dict, List, Tuple, Optional
|
|
|
10
10
|
# Do NOT skip application databases even if they seem like "test" or "lab" databases
|
|
11
11
|
# Real engagements may have legitimately named databases like these
|
|
12
12
|
SYSTEM_DATABASES = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
"information_schema", # MySQL metadata - no user data
|
|
14
|
+
"mysql", # MySQL system tables - no user data
|
|
15
|
+
"performance_schema", # MySQL performance metrics - no user data
|
|
16
|
+
"sys", # MySQL system views - no user data
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
# System table patterns to skip (even in application databases)
|
|
20
20
|
SYSTEM_TABLE_PATTERNS = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
"USER_PRIVILEGES",
|
|
22
|
+
"SCHEMA_PRIVILEGES",
|
|
23
|
+
"TABLE_PRIVILEGES",
|
|
24
|
+
"COLUMN_PRIVILEGES",
|
|
25
|
+
"REFERENTIAL_CONSTRAINTS",
|
|
26
|
+
"KEY_COLUMN_USAGE",
|
|
27
|
+
"TABLE_CONSTRAINTS",
|
|
28
|
+
"STATISTICS",
|
|
29
|
+
"VIEWS",
|
|
30
|
+
"TRIGGERS",
|
|
31
|
+
"ROUTINES",
|
|
32
|
+
"EVENTS",
|
|
33
|
+
"PARAMETERS",
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
# Skip tables with these suffixes (logs, history, metadata)
|
|
37
37
|
SKIP_TABLE_SUFFIXES = [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
"_log",
|
|
39
|
+
"_logs",
|
|
40
|
+
"_history",
|
|
41
|
+
"_audit",
|
|
42
|
+
"_backup",
|
|
43
|
+
"_temp",
|
|
44
|
+
"_tmp",
|
|
45
|
+
"_cache",
|
|
46
|
+
"_meta",
|
|
47
|
+
"_metadata",
|
|
48
48
|
]
|
|
49
49
|
|
|
50
50
|
|
|
@@ -59,69 +59,143 @@ def is_system_table(table_name: str) -> bool:
|
|
|
59
59
|
"""Check if table is a system table (should skip)."""
|
|
60
60
|
if not table_name:
|
|
61
61
|
return False
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
table_lower = table_name.lower().strip()
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
# Check against system table patterns
|
|
66
66
|
for pattern in SYSTEM_TABLE_PATTERNS:
|
|
67
67
|
if pattern.lower() in table_lower:
|
|
68
68
|
return True
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
# Check suffixes
|
|
71
71
|
for suffix in SKIP_TABLE_SUFFIXES:
|
|
72
72
|
if table_lower.endswith(suffix):
|
|
73
73
|
return True
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
return False
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
# Sensitive table name patterns by category
|
|
79
79
|
SENSITIVE_TABLE_PATTERNS = {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
"credentials": [
|
|
81
|
+
"users",
|
|
82
|
+
"user",
|
|
83
|
+
"accounts",
|
|
84
|
+
"account",
|
|
85
|
+
"members",
|
|
86
|
+
"member",
|
|
87
|
+
"logins",
|
|
88
|
+
"login",
|
|
89
|
+
"auth",
|
|
90
|
+
"authentication",
|
|
91
|
+
"customers",
|
|
92
|
+
"customer",
|
|
93
|
+
"clients",
|
|
94
|
+
"client",
|
|
95
|
+
"administrators",
|
|
96
|
+
"admin",
|
|
97
|
+
"admins",
|
|
98
|
+
"staff",
|
|
99
|
+
"employees",
|
|
100
|
+
"employee",
|
|
85
101
|
],
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
102
|
+
"payment": [
|
|
103
|
+
"credit_cards",
|
|
104
|
+
"creditcards",
|
|
105
|
+
"cards",
|
|
106
|
+
"card",
|
|
107
|
+
"payments",
|
|
108
|
+
"payment",
|
|
109
|
+
"transactions",
|
|
110
|
+
"transaction",
|
|
111
|
+
"billing",
|
|
112
|
+
"invoices",
|
|
113
|
+
"invoice",
|
|
114
|
+
"orders",
|
|
115
|
+
"order",
|
|
90
116
|
],
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
117
|
+
"sensitive_pii": [
|
|
118
|
+
"profiles",
|
|
119
|
+
"profile",
|
|
120
|
+
"persons",
|
|
121
|
+
"person",
|
|
122
|
+
"contacts",
|
|
123
|
+
"contact",
|
|
124
|
+
"addresses",
|
|
125
|
+
"address",
|
|
126
|
+
"personal_info",
|
|
127
|
+
"pii",
|
|
128
|
+
"identities",
|
|
129
|
+
"identity",
|
|
130
|
+
"social_security",
|
|
131
|
+
"ssn",
|
|
132
|
+
"drivers_license",
|
|
133
|
+
"passport",
|
|
134
|
+
],
|
|
135
|
+
"secrets": [
|
|
136
|
+
"api_keys",
|
|
137
|
+
"tokens",
|
|
138
|
+
"secrets",
|
|
139
|
+
"keys",
|
|
140
|
+
"passwords",
|
|
141
|
+
"password",
|
|
142
|
+
"credentials",
|
|
143
|
+
"creds",
|
|
144
|
+
"sessions",
|
|
145
|
+
"session",
|
|
146
|
+
"oauth",
|
|
147
|
+
"jwt",
|
|
96
148
|
],
|
|
97
|
-
'secrets': [
|
|
98
|
-
'api_keys', 'tokens', 'secrets', 'keys',
|
|
99
|
-
'passwords', 'password', 'credentials', 'creds',
|
|
100
|
-
'sessions', 'session', 'oauth', 'jwt'
|
|
101
|
-
]
|
|
102
149
|
}
|
|
103
150
|
|
|
104
151
|
# Column name patterns for validation
|
|
105
152
|
SENSITIVE_COLUMN_PATTERNS = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
153
|
+
"credentials": [
|
|
154
|
+
"password",
|
|
155
|
+
"passwd",
|
|
156
|
+
"pass",
|
|
157
|
+
"pwd",
|
|
158
|
+
"hash",
|
|
159
|
+
"username",
|
|
160
|
+
"user",
|
|
161
|
+
"email",
|
|
162
|
+
"login",
|
|
163
|
+
"salt",
|
|
164
|
+
"token",
|
|
165
|
+
"secret",
|
|
166
|
+
"api_key",
|
|
167
|
+
],
|
|
168
|
+
"payment": [
|
|
169
|
+
"card_number",
|
|
170
|
+
"cvv",
|
|
171
|
+
"expiry",
|
|
172
|
+
"card_type",
|
|
173
|
+
"account_number",
|
|
174
|
+
"routing_number",
|
|
175
|
+
"iban",
|
|
176
|
+
"swift",
|
|
177
|
+
"cardholder",
|
|
178
|
+
"billing",
|
|
110
179
|
],
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
180
|
+
"pii": [
|
|
181
|
+
"ssn",
|
|
182
|
+
"social_security",
|
|
183
|
+
"tax_id",
|
|
184
|
+
"national_id",
|
|
185
|
+
"address",
|
|
186
|
+
"phone",
|
|
187
|
+
"dob",
|
|
188
|
+
"birth_date",
|
|
189
|
+
"drivers_license",
|
|
190
|
+
"passport",
|
|
191
|
+
"maiden_name",
|
|
115
192
|
],
|
|
116
|
-
'pii': [
|
|
117
|
-
'ssn', 'social_security', 'tax_id', 'national_id',
|
|
118
|
-
'address', 'phone', 'dob', 'birth_date',
|
|
119
|
-
'drivers_license', 'passport', 'maiden_name'
|
|
120
|
-
]
|
|
121
193
|
}
|
|
122
194
|
|
|
123
195
|
|
|
124
|
-
def is_sensitive_table(
|
|
196
|
+
def is_sensitive_table(
|
|
197
|
+
table_name: str, category: Optional[str] = None
|
|
198
|
+
) -> Tuple[bool, Optional[str], int]:
|
|
125
199
|
"""
|
|
126
200
|
Determine if a table name is sensitive.
|
|
127
201
|
|
|
@@ -152,17 +226,17 @@ def is_sensitive_table(table_name: str, category: Optional[str] = None) -> Tuple
|
|
|
152
226
|
table_lower = table_name.lower().strip()
|
|
153
227
|
|
|
154
228
|
# Remove common prefixes (including tiki_, drupal_, etc.)
|
|
155
|
-
for prefix in [
|
|
229
|
+
for prefix in ["tbl_", "app_", "wp_", "db_", "sys_", "tiki_", "drupal_", "joomla_"]:
|
|
156
230
|
if table_lower.startswith(prefix):
|
|
157
|
-
table_lower = table_lower[len(prefix):]
|
|
231
|
+
table_lower = table_lower[len(prefix) :]
|
|
158
232
|
break
|
|
159
233
|
|
|
160
234
|
# Priority by category (credentials most important)
|
|
161
235
|
category_priorities = {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
236
|
+
"credentials": 10,
|
|
237
|
+
"payment": 9,
|
|
238
|
+
"secrets": 8,
|
|
239
|
+
"sensitive_pii": 7,
|
|
166
240
|
}
|
|
167
241
|
|
|
168
242
|
# Check against patterns
|
|
@@ -186,15 +260,19 @@ def is_sensitive_table(table_name: str, category: Optional[str] = None) -> Tuple
|
|
|
186
260
|
return (True, cat, priority)
|
|
187
261
|
|
|
188
262
|
# 2. Table ENDS with the pattern (e.g., "users_users" ends with "users")
|
|
189
|
-
if table_lower.endswith(
|
|
263
|
+
if table_lower.endswith("_" + pattern_lower) or table_lower.endswith(
|
|
264
|
+
pattern_lower
|
|
265
|
+
):
|
|
190
266
|
# Make sure it's a word boundary, not partial (e.g., "xusers" shouldn't match)
|
|
191
|
-
if table_lower == pattern_lower or table_lower.endswith(
|
|
267
|
+
if table_lower == pattern_lower or table_lower.endswith(
|
|
268
|
+
"_" + pattern_lower
|
|
269
|
+
):
|
|
192
270
|
priority = category_priorities.get(cat, 5)
|
|
193
271
|
return (True, cat, priority)
|
|
194
272
|
|
|
195
273
|
# 3. Singular/plural variants at end only
|
|
196
|
-
pattern_singular = pattern_lower.rstrip(
|
|
197
|
-
table_singular = table_lower.rstrip(
|
|
274
|
+
pattern_singular = pattern_lower.rstrip("s")
|
|
275
|
+
table_singular = table_lower.rstrip("s")
|
|
198
276
|
if table_singular == pattern_singular:
|
|
199
277
|
priority = category_priorities.get(cat, 5)
|
|
200
278
|
return (True, cat, priority)
|
|
@@ -224,22 +302,24 @@ def validate_sensitive_columns(columns: List[str], expected_category: str) -> bo
|
|
|
224
302
|
"""
|
|
225
303
|
if not columns:
|
|
226
304
|
return False
|
|
227
|
-
|
|
305
|
+
|
|
228
306
|
# Map category to column patterns
|
|
229
307
|
category_map = {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
308
|
+
"credentials": SENSITIVE_COLUMN_PATTERNS["credentials"],
|
|
309
|
+
"payment": SENSITIVE_COLUMN_PATTERNS["payment"],
|
|
310
|
+
"sensitive_pii": SENSITIVE_COLUMN_PATTERNS["pii"],
|
|
311
|
+
"secrets": SENSITIVE_COLUMN_PATTERNS[
|
|
312
|
+
"credentials"
|
|
313
|
+
], # Secrets use same patterns as credentials
|
|
234
314
|
}
|
|
235
|
-
|
|
315
|
+
|
|
236
316
|
expected_patterns = category_map.get(expected_category, [])
|
|
237
317
|
if not expected_patterns:
|
|
238
318
|
return True # If no patterns defined, assume valid
|
|
239
|
-
|
|
319
|
+
|
|
240
320
|
# Normalize column names
|
|
241
321
|
columns_lower = [col.lower() for col in columns]
|
|
242
|
-
|
|
322
|
+
|
|
243
323
|
# Check if any expected patterns match
|
|
244
324
|
matches = 0
|
|
245
325
|
for pattern in expected_patterns:
|
|
@@ -248,14 +328,15 @@ def validate_sensitive_columns(columns: List[str], expected_category: str) -> bo
|
|
|
248
328
|
if pattern_lower in col or col in pattern_lower:
|
|
249
329
|
matches += 1
|
|
250
330
|
break
|
|
251
|
-
|
|
331
|
+
|
|
252
332
|
# Require at least 2 matching columns for high confidence
|
|
253
333
|
# (e.g., username + password, card_number + cvv)
|
|
254
334
|
return matches >= 2
|
|
255
335
|
|
|
256
336
|
|
|
257
|
-
def prioritize_tables(
|
|
258
|
-
|
|
337
|
+
def prioritize_tables(
|
|
338
|
+
tables: Dict[str, List[str]], columns: Optional[Dict[str, List[str]]] = None
|
|
339
|
+
) -> List[Dict]:
|
|
259
340
|
"""
|
|
260
341
|
Prioritize sensitive tables for dumping.
|
|
261
342
|
|
|
@@ -281,69 +362,95 @@ def prioritize_tables(tables: Dict[str, List[str]],
|
|
|
281
362
|
- Priority 8-10 only (avoid dumping low-confidence matches)
|
|
282
363
|
"""
|
|
283
364
|
sensitive_tables = []
|
|
284
|
-
|
|
365
|
+
|
|
285
366
|
for database, table_list in tables.items():
|
|
286
367
|
for table in table_list:
|
|
287
368
|
# Check if table is sensitive
|
|
288
369
|
is_sensitive, category, priority = is_sensitive_table(table)
|
|
289
|
-
|
|
370
|
+
|
|
290
371
|
if not is_sensitive or priority < 5:
|
|
291
372
|
continue # Skip non-sensitive tables (lowered threshold for thoroughness)
|
|
292
|
-
|
|
373
|
+
|
|
293
374
|
# Get columns for validation if available
|
|
294
375
|
table_key = f"{database}.{table}"
|
|
295
376
|
table_columns = columns.get(table_key, []) if columns else []
|
|
296
|
-
|
|
377
|
+
|
|
297
378
|
# Validate columns if available (but don't skip - just note it)
|
|
298
379
|
if table_columns:
|
|
299
380
|
if not validate_sensitive_columns(table_columns, category):
|
|
300
381
|
# Columns don't match expected pattern - reduce priority slightly
|
|
301
382
|
# but still include for thoroughness
|
|
302
383
|
priority -= 1
|
|
303
|
-
|
|
304
|
-
sensitive_tables.append(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
384
|
+
|
|
385
|
+
sensitive_tables.append(
|
|
386
|
+
{
|
|
387
|
+
"database": database,
|
|
388
|
+
"table": table,
|
|
389
|
+
"category": category,
|
|
390
|
+
"priority": priority,
|
|
391
|
+
"columns": table_columns,
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
|
|
312
395
|
# Sort by priority (highest first), then by category importance
|
|
313
|
-
category_order = {
|
|
396
|
+
category_order = {"credentials": 0, "payment": 1, "secrets": 2, "sensitive_pii": 3}
|
|
314
397
|
sensitive_tables.sort(
|
|
315
|
-
key=lambda t: (-t[
|
|
398
|
+
key=lambda t: (-t["priority"], category_order.get(t["category"], 9))
|
|
316
399
|
)
|
|
317
|
-
|
|
400
|
+
|
|
318
401
|
# Limit to top 25 tables (increased for thoroughness in real engagements)
|
|
319
402
|
return sensitive_tables[:25]
|
|
320
403
|
|
|
321
404
|
|
|
322
405
|
# Sensitive table names (for quick lookup without column validation)
|
|
323
406
|
SENSITIVE_TABLE_NAMES = {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
407
|
+
"users",
|
|
408
|
+
"user",
|
|
409
|
+
"accounts",
|
|
410
|
+
"account",
|
|
411
|
+
"members",
|
|
412
|
+
"member",
|
|
413
|
+
"customers",
|
|
414
|
+
"customer",
|
|
415
|
+
"clients",
|
|
416
|
+
"client",
|
|
417
|
+
"admins",
|
|
418
|
+
"admin",
|
|
419
|
+
"administrators",
|
|
420
|
+
"credentials",
|
|
421
|
+
"creds",
|
|
422
|
+
"passwords",
|
|
423
|
+
"passwd",
|
|
424
|
+
"logins",
|
|
425
|
+
"login",
|
|
426
|
+
"auth",
|
|
427
|
+
"authentication",
|
|
428
|
+
"sessions",
|
|
429
|
+
"tokens",
|
|
430
|
+
"api_keys",
|
|
431
|
+
"apikeys",
|
|
432
|
+
"credit_cards",
|
|
433
|
+
"creditcards",
|
|
434
|
+
"cards",
|
|
435
|
+
"payments",
|
|
436
|
+
"orders",
|
|
437
|
+
"transactions",
|
|
438
|
+
"billing",
|
|
332
439
|
}
|
|
333
440
|
|
|
334
441
|
|
|
335
442
|
def is_sensitive_table_name(table_name: str) -> bool:
|
|
336
443
|
"""
|
|
337
444
|
Check if table name suggests sensitive data (name-based only).
|
|
338
|
-
|
|
445
|
+
|
|
339
446
|
Used for quick decisions without column information.
|
|
340
|
-
|
|
447
|
+
|
|
341
448
|
Args:
|
|
342
449
|
table_name: Name of the table to check
|
|
343
|
-
|
|
450
|
+
|
|
344
451
|
Returns:
|
|
345
452
|
bool: True if table name suggests sensitive data
|
|
346
|
-
|
|
453
|
+
|
|
347
454
|
Examples:
|
|
348
455
|
>>> is_sensitive_table_name('users')
|
|
349
456
|
True
|
|
@@ -357,27 +464,57 @@ def is_sensitive_table_name(table_name: str) -> bool:
|
|
|
357
464
|
|
|
358
465
|
# Sensitive column patterns (expanded for detection)
|
|
359
466
|
SENSITIVE_COLUMN_KEYWORDS = {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
467
|
+
"password",
|
|
468
|
+
"passwd",
|
|
469
|
+
"pass",
|
|
470
|
+
"pwd",
|
|
471
|
+
"secret",
|
|
472
|
+
"email",
|
|
473
|
+
"mail",
|
|
474
|
+
"phone",
|
|
475
|
+
"mobile",
|
|
476
|
+
"cell",
|
|
477
|
+
"ssn",
|
|
478
|
+
"social_security",
|
|
479
|
+
"national_id",
|
|
480
|
+
"tax_id",
|
|
481
|
+
"credit_card",
|
|
482
|
+
"cc_number",
|
|
483
|
+
"card_number",
|
|
484
|
+
"cvv",
|
|
485
|
+
"ccv",
|
|
486
|
+
"token",
|
|
487
|
+
"api_key",
|
|
488
|
+
"apikey",
|
|
489
|
+
"auth_token",
|
|
490
|
+
"session",
|
|
491
|
+
"address",
|
|
492
|
+
"street",
|
|
493
|
+
"city",
|
|
494
|
+
"zip",
|
|
495
|
+
"postal",
|
|
496
|
+
"dob",
|
|
497
|
+
"date_of_birth",
|
|
498
|
+
"birthday",
|
|
499
|
+
"birthdate",
|
|
500
|
+
"salary",
|
|
501
|
+
"income",
|
|
502
|
+
"bank",
|
|
503
|
+
"account_number",
|
|
504
|
+
"routing",
|
|
368
505
|
}
|
|
369
506
|
|
|
370
507
|
|
|
371
508
|
def has_sensitive_columns(columns: List[str]) -> bool:
|
|
372
509
|
"""
|
|
373
510
|
Check if any column name suggests sensitive data.
|
|
374
|
-
|
|
511
|
+
|
|
375
512
|
Args:
|
|
376
513
|
columns: List of column names or column dictionaries
|
|
377
|
-
|
|
514
|
+
|
|
378
515
|
Returns:
|
|
379
516
|
bool: True if sensitive columns detected
|
|
380
|
-
|
|
517
|
+
|
|
381
518
|
Examples:
|
|
382
519
|
>>> has_sensitive_columns(['id', 'username', 'password'])
|
|
383
520
|
True
|
|
@@ -386,19 +523,19 @@ def has_sensitive_columns(columns: List[str]) -> bool:
|
|
|
386
523
|
"""
|
|
387
524
|
if not columns:
|
|
388
525
|
return False
|
|
389
|
-
|
|
526
|
+
|
|
390
527
|
for col in columns:
|
|
391
528
|
# Handle both string column names and dict with 'name' key
|
|
392
529
|
if isinstance(col, dict):
|
|
393
|
-
col_name = col.get(
|
|
530
|
+
col_name = col.get("name", col.get("column", ""))
|
|
394
531
|
else:
|
|
395
532
|
col_name = str(col)
|
|
396
|
-
|
|
533
|
+
|
|
397
534
|
col_lower = col_name.lower()
|
|
398
|
-
|
|
535
|
+
|
|
399
536
|
# Check if any sensitive keyword appears in column name
|
|
400
537
|
for pattern in SENSITIVE_COLUMN_KEYWORDS:
|
|
401
538
|
if pattern in col_lower:
|
|
402
539
|
return True
|
|
403
|
-
|
|
540
|
+
|
|
404
541
|
return False
|