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
souleyez/plugins/dalfox.py
CHANGED
|
@@ -25,11 +25,11 @@ HELP = {
|
|
|
25
25
|
"Dalfox works best when given URLs with parameters to test. Chain it after "
|
|
26
26
|
"directory discovery (Gobuster/ffuf) to test discovered endpoints.\n"
|
|
27
27
|
),
|
|
28
|
-
"usage":
|
|
28
|
+
"usage": 'souleyez jobs enqueue dalfox <url> --args "url <target>"',
|
|
29
29
|
"examples": [
|
|
30
30
|
"souleyez jobs enqueue dalfox 'http://example.com/search?q=test' --args \"url 'http://example.com/search?q=test'\"",
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
'souleyez jobs enqueue dalfox http://example.com --args "url http://example.com/page?id=1 --deep-domxss"',
|
|
32
|
+
'souleyez jobs enqueue dalfox http://example.com --args "url http://example.com/form?name=test --waf-evasion"',
|
|
33
33
|
],
|
|
34
34
|
"flags": [
|
|
35
35
|
["url <url>", "Target URL with parameters (required)"],
|
|
@@ -47,76 +47,128 @@ HELP = {
|
|
|
47
47
|
{
|
|
48
48
|
"name": "Quick XSS Scan",
|
|
49
49
|
"args": ["url", "<target>", "--format", "json", "--skip-bav"],
|
|
50
|
-
"desc": "Fast XSS scan on target URL"
|
|
50
|
+
"desc": "Fast XSS scan on target URL",
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"name": "Parameter Discovery",
|
|
54
54
|
"args": ["url", "<target>", "--only-discovery", "--format", "json"],
|
|
55
|
-
"desc": "Find parameters without attacking"
|
|
56
|
-
}
|
|
55
|
+
"desc": "Find parameters without attacking",
|
|
56
|
+
},
|
|
57
57
|
],
|
|
58
58
|
"comprehensive": [
|
|
59
59
|
{
|
|
60
60
|
"name": "Deep Scan",
|
|
61
61
|
"args": ["url", "<target>", "--deep-domxss", "--format", "json"],
|
|
62
|
-
"desc": "Include DOM XSS analysis"
|
|
62
|
+
"desc": "Include DOM XSS analysis",
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
"name": "WAF Bypass",
|
|
66
66
|
"args": ["url", "<target>", "--waf-evasion", "--format", "json"],
|
|
67
|
-
"desc": "Use WAF evasion techniques"
|
|
67
|
+
"desc": "Use WAF evasion techniques",
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"name": "Full Scan",
|
|
71
|
-
"args": [
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
"args": [
|
|
72
|
+
"url",
|
|
73
|
+
"<target>",
|
|
74
|
+
"--deep-domxss",
|
|
75
|
+
"--waf-evasion",
|
|
76
|
+
"--format",
|
|
77
|
+
"json",
|
|
78
|
+
],
|
|
79
|
+
"desc": "All techniques enabled",
|
|
80
|
+
},
|
|
74
81
|
],
|
|
75
82
|
"stealth": [
|
|
76
83
|
{
|
|
77
84
|
"name": "Slow Scan",
|
|
78
85
|
"args": ["url", "<target>", "--delay", "1000", "--format", "json"],
|
|
79
|
-
"desc": "1 second delay between requests"
|
|
86
|
+
"desc": "1 second delay between requests",
|
|
80
87
|
}
|
|
81
|
-
]
|
|
88
|
+
],
|
|
82
89
|
},
|
|
83
90
|
"presets": [
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{
|
|
91
|
+
{
|
|
92
|
+
"name": "Quick XSS Scan",
|
|
93
|
+
"args": ["url", "<target>", "--format", "json", "--skip-bav"],
|
|
94
|
+
"desc": "Fast XSS scan on target URL",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "Parameter Discovery",
|
|
98
|
+
"args": ["url", "<target>", "--only-discovery", "--format", "json"],
|
|
99
|
+
"desc": "Find parameters without attacking",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "Deep Scan",
|
|
103
|
+
"args": ["url", "<target>", "--deep-domxss", "--format", "json"],
|
|
104
|
+
"desc": "Include DOM XSS analysis",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "WAF Bypass",
|
|
108
|
+
"args": ["url", "<target>", "--waf-evasion", "--format", "json"],
|
|
109
|
+
"desc": "Use WAF evasion techniques",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "Full Scan",
|
|
113
|
+
"args": [
|
|
114
|
+
"url",
|
|
115
|
+
"<target>",
|
|
116
|
+
"--deep-domxss",
|
|
117
|
+
"--waf-evasion",
|
|
118
|
+
"--format",
|
|
119
|
+
"json",
|
|
120
|
+
],
|
|
121
|
+
"desc": "All techniques enabled",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "Slow Scan",
|
|
125
|
+
"args": ["url", "<target>", "--delay", "1000", "--format", "json"],
|
|
126
|
+
"desc": "1 second delay between requests",
|
|
127
|
+
},
|
|
90
128
|
],
|
|
91
129
|
"help_sections": [
|
|
92
130
|
{
|
|
93
131
|
"title": "What is Dalfox?",
|
|
94
132
|
"color": "cyan",
|
|
95
133
|
"content": [
|
|
96
|
-
{
|
|
97
|
-
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
|
|
104
|
-
|
|
134
|
+
{
|
|
135
|
+
"title": "Overview",
|
|
136
|
+
"desc": "Dalfox (XSS Finder) is a fast, powerful parameter analysis and XSS scanner written in Go. It's designed specifically for finding XSS vulnerabilities.",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"title": "Use Cases",
|
|
140
|
+
"desc": "Perfect for testing web applications",
|
|
141
|
+
"tips": [
|
|
142
|
+
"Test form inputs for XSS",
|
|
143
|
+
"Analyze URL parameters",
|
|
144
|
+
"Find DOM-based XSS",
|
|
145
|
+
"Bypass WAF protections",
|
|
146
|
+
"Detect blind XSS opportunities",
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
],
|
|
105
150
|
},
|
|
106
151
|
{
|
|
107
152
|
"title": "Best Practices",
|
|
108
153
|
"color": "green",
|
|
109
154
|
"content": [
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
"
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
155
|
+
{
|
|
156
|
+
"title": "Workflow",
|
|
157
|
+
"desc": "1. Run Gobuster/ffuf to find endpoints\n2. Identify URLs with parameters\n3. Run Dalfox on each parameterized URL\n4. Review findings for exploitability",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"title": "Tips",
|
|
161
|
+
"desc": "Maximize XSS detection",
|
|
162
|
+
"tips": [
|
|
163
|
+
"Use --deep-domxss for JavaScript-heavy apps",
|
|
164
|
+
"Enable --waf-evasion for protected sites",
|
|
165
|
+
"Check --blind for delayed XSS detection",
|
|
166
|
+
"Use --delay to avoid rate limiting",
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
],
|
|
120
172
|
}
|
|
121
173
|
|
|
122
174
|
|
|
@@ -128,11 +180,13 @@ class DalfoxPlugin(PluginBase):
|
|
|
128
180
|
|
|
129
181
|
def _ensure_url_scheme(self, target: str) -> str:
|
|
130
182
|
"""Ensure target has http:// or https:// scheme."""
|
|
131
|
-
if not target.startswith((
|
|
132
|
-
return f
|
|
183
|
+
if not target.startswith(("http://", "https://")):
|
|
184
|
+
return f"http://{target}"
|
|
133
185
|
return target
|
|
134
186
|
|
|
135
|
-
def build_command(
|
|
187
|
+
def build_command(
|
|
188
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
189
|
+
):
|
|
136
190
|
"""Build dalfox command for background execution."""
|
|
137
191
|
args = args or []
|
|
138
192
|
|
|
@@ -140,24 +194,23 @@ class DalfoxPlugin(PluginBase):
|
|
|
140
194
|
target = self._ensure_url_scheme(target)
|
|
141
195
|
|
|
142
196
|
# If no mode specified, add 'url' mode with target
|
|
143
|
-
if
|
|
144
|
-
args = [
|
|
197
|
+
if "url" not in args and "file" not in args and "pipe" not in args:
|
|
198
|
+
args = ["url", target] + args
|
|
145
199
|
|
|
146
200
|
# Replace <target> placeholder (also ensure scheme in placeholder)
|
|
147
201
|
processed_args = [arg.replace("<target>", target) for arg in args]
|
|
148
202
|
|
|
149
203
|
# Add JSON output format if not specified
|
|
150
|
-
if
|
|
151
|
-
processed_args.extend([
|
|
204
|
+
if "--format" not in processed_args and "-format" not in processed_args:
|
|
205
|
+
processed_args.extend(["--format", "json"])
|
|
152
206
|
|
|
153
207
|
cmd = ["dalfox"] + processed_args
|
|
154
208
|
|
|
155
|
-
return {
|
|
156
|
-
'cmd': cmd,
|
|
157
|
-
'timeout': 1800 # 30 minutes
|
|
158
|
-
}
|
|
209
|
+
return {"cmd": cmd, "timeout": 1800} # 30 minutes
|
|
159
210
|
|
|
160
|
-
def run(
|
|
211
|
+
def run(
|
|
212
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
213
|
+
) -> int:
|
|
161
214
|
"""Execute dalfox scan and write output to log_path."""
|
|
162
215
|
args = args or []
|
|
163
216
|
|
|
@@ -165,21 +218,23 @@ class DalfoxPlugin(PluginBase):
|
|
|
165
218
|
target = self._ensure_url_scheme(target)
|
|
166
219
|
|
|
167
220
|
# If no mode specified, add 'url' mode with target
|
|
168
|
-
if
|
|
169
|
-
args = [
|
|
221
|
+
if "url" not in args and "file" not in args and "pipe" not in args:
|
|
222
|
+
args = ["url", target] + args
|
|
170
223
|
|
|
171
224
|
# Replace <target> placeholder (also ensure scheme in placeholder)
|
|
172
225
|
processed_args = [arg.replace("<target>", target) for arg in args]
|
|
173
226
|
|
|
174
227
|
# Add JSON output format if not specified
|
|
175
|
-
if
|
|
176
|
-
processed_args.extend([
|
|
228
|
+
if "--format" not in processed_args and "-format" not in processed_args:
|
|
229
|
+
processed_args.extend(["--format", "json"])
|
|
177
230
|
|
|
178
231
|
cmd = ["dalfox"] + processed_args
|
|
179
232
|
|
|
180
233
|
if not log_path:
|
|
181
234
|
try:
|
|
182
|
-
proc = subprocess.run(
|
|
235
|
+
proc = subprocess.run(
|
|
236
|
+
cmd, capture_output=True, timeout=1800, check=False
|
|
237
|
+
)
|
|
183
238
|
return proc.returncode
|
|
184
239
|
except Exception:
|
|
185
240
|
return 1
|
|
@@ -191,7 +246,9 @@ class DalfoxPlugin(PluginBase):
|
|
|
191
246
|
fh.write(f"Args: {processed_args}\n")
|
|
192
247
|
if label:
|
|
193
248
|
fh.write(f"Label: {label}\n")
|
|
194
|
-
fh.write(
|
|
249
|
+
fh.write(
|
|
250
|
+
f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n"
|
|
251
|
+
)
|
|
195
252
|
fh.write(f"Command: {' '.join(cmd)}\n")
|
|
196
253
|
fh.write("=" * 60 + "\n\n")
|
|
197
254
|
fh.flush()
|
|
@@ -202,11 +259,13 @@ class DalfoxPlugin(PluginBase):
|
|
|
202
259
|
stderr=subprocess.STDOUT,
|
|
203
260
|
timeout=1800,
|
|
204
261
|
check=False,
|
|
205
|
-
text=True
|
|
262
|
+
text=True,
|
|
206
263
|
)
|
|
207
264
|
|
|
208
265
|
fh.write(proc.stdout)
|
|
209
|
-
fh.write(
|
|
266
|
+
fh.write(
|
|
267
|
+
f"\n=== Completed: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())} ===\n"
|
|
268
|
+
)
|
|
210
269
|
fh.write(f"Exit Code: {proc.returncode}\n")
|
|
211
270
|
|
|
212
271
|
return proc.returncode
|
|
@@ -219,7 +278,9 @@ class DalfoxPlugin(PluginBase):
|
|
|
219
278
|
except FileNotFoundError:
|
|
220
279
|
with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
|
|
221
280
|
fh.write("\nERROR: dalfox not found in PATH\n")
|
|
222
|
-
fh.write(
|
|
281
|
+
fh.write(
|
|
282
|
+
"Install with: go install github.com/hahwul/dalfox/v2@latest\n"
|
|
283
|
+
)
|
|
223
284
|
return 127
|
|
224
285
|
|
|
225
286
|
except Exception as e:
|
souleyez/plugins/dns_hijack.py
CHANGED
|
@@ -31,14 +31,97 @@ HELP = {
|
|
|
31
31
|
"usage": "souleyez jobs enqueue dns_hijack <router_ip>",
|
|
32
32
|
"examples": [
|
|
33
33
|
"souleyez jobs enqueue dns_hijack 192.168.1.1",
|
|
34
|
-
|
|
34
|
+
'souleyez jobs enqueue dns_hijack 192.168.1.1 --args "--domains google.com,microsoft.com"',
|
|
35
35
|
],
|
|
36
36
|
"flags": [
|
|
37
37
|
["--domains DOMAINS", "Comma-separated test domains"],
|
|
38
38
|
],
|
|
39
39
|
"presets": [
|
|
40
40
|
{"name": "Quick Check", "args": [], "desc": "Test with common domains"},
|
|
41
|
-
{
|
|
41
|
+
{
|
|
42
|
+
"name": "Extended",
|
|
43
|
+
"args": [
|
|
44
|
+
"--domains",
|
|
45
|
+
"google.com,microsoft.com,apple.com,facebook.com,amazon.com",
|
|
46
|
+
],
|
|
47
|
+
"desc": "Test multiple major sites",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
"help_sections": [
|
|
51
|
+
{
|
|
52
|
+
"title": "What is DNS Hijacking?",
|
|
53
|
+
"color": "cyan",
|
|
54
|
+
"content": [
|
|
55
|
+
(
|
|
56
|
+
"Overview",
|
|
57
|
+
[
|
|
58
|
+
"DNS hijacking redirects DNS queries to attacker-controlled servers",
|
|
59
|
+
"Compromised routers may modify DNS to redirect traffic",
|
|
60
|
+
"This tool compares router DNS responses to known-good DNS (8.8.8.8)",
|
|
61
|
+
],
|
|
62
|
+
),
|
|
63
|
+
(
|
|
64
|
+
"Common Attack Goals",
|
|
65
|
+
[
|
|
66
|
+
"Redirect users to phishing sites (fake banking, email)",
|
|
67
|
+
"Inject ads into web pages for profit",
|
|
68
|
+
"Monitor browsing activity and steal credentials",
|
|
69
|
+
"Block security updates to maintain access",
|
|
70
|
+
],
|
|
71
|
+
),
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"title": "Usage & Examples",
|
|
76
|
+
"color": "green",
|
|
77
|
+
"content": [
|
|
78
|
+
(
|
|
79
|
+
"Basic Usage",
|
|
80
|
+
[
|
|
81
|
+
"souleyez jobs enqueue dns_hijack 192.168.1.1",
|
|
82
|
+
" → Tests router DNS against Google DNS (8.8.8.8)",
|
|
83
|
+
],
|
|
84
|
+
),
|
|
85
|
+
(
|
|
86
|
+
"Custom Domains",
|
|
87
|
+
[
|
|
88
|
+
'souleyez jobs enqueue dns_hijack 192.168.1.1 --args "--domains google.com,bank.com"',
|
|
89
|
+
" → Tests specific domains you're concerned about",
|
|
90
|
+
],
|
|
91
|
+
),
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"title": "Understanding Results",
|
|
96
|
+
"color": "yellow",
|
|
97
|
+
"content": [
|
|
98
|
+
(
|
|
99
|
+
"Result Indicators",
|
|
100
|
+
[
|
|
101
|
+
"[OK] - DNS responses match the reference server",
|
|
102
|
+
"[WARN] - Partial match, some IPs differ (investigate)",
|
|
103
|
+
"[ALERT] - No matching IPs, likely hijacked!",
|
|
104
|
+
],
|
|
105
|
+
),
|
|
106
|
+
(
|
|
107
|
+
"NXDOMAIN Test",
|
|
108
|
+
[
|
|
109
|
+
"Tests if router returns IPs for fake domains",
|
|
110
|
+
"If yes: Router hijacks typos to show ads/search pages",
|
|
111
|
+
"Common ISP 'feature' but can mask real hijacking",
|
|
112
|
+
],
|
|
113
|
+
),
|
|
114
|
+
(
|
|
115
|
+
"Next Steps if Hijacked",
|
|
116
|
+
[
|
|
117
|
+
"Change router DNS to 8.8.8.8 or 1.1.1.1 manually",
|
|
118
|
+
"Check router for firmware compromise",
|
|
119
|
+
"Look for unauthorized admin accounts",
|
|
120
|
+
"Consider factory reset if malware suspected",
|
|
121
|
+
],
|
|
122
|
+
),
|
|
123
|
+
],
|
|
124
|
+
},
|
|
42
125
|
],
|
|
43
126
|
}
|
|
44
127
|
|
|
@@ -49,7 +132,9 @@ class DNSHijackPlugin(PluginBase):
|
|
|
49
132
|
category = "vulnerability_analysis"
|
|
50
133
|
HELP = HELP
|
|
51
134
|
|
|
52
|
-
def build_command(
|
|
135
|
+
def build_command(
|
|
136
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
137
|
+
):
|
|
53
138
|
"""Build dig commands for DNS hijack detection."""
|
|
54
139
|
args = args or []
|
|
55
140
|
|
|
@@ -57,39 +142,37 @@ class DNSHijackPlugin(PluginBase):
|
|
|
57
142
|
target = validate_target(target)
|
|
58
143
|
except ValidationError as e:
|
|
59
144
|
if log_path:
|
|
60
|
-
with open(log_path,
|
|
145
|
+
with open(log_path, "w") as f:
|
|
61
146
|
f.write(f"ERROR: Invalid target: {e}\n")
|
|
62
147
|
return None
|
|
63
148
|
|
|
64
149
|
# Parse domains to test
|
|
65
|
-
domains = [
|
|
150
|
+
domains = ["google.com", "microsoft.com", "example.com"]
|
|
66
151
|
i = 0
|
|
67
152
|
while i < len(args):
|
|
68
|
-
if args[i] ==
|
|
69
|
-
domains = [d.strip() for d in args[i + 1].split(
|
|
153
|
+
if args[i] == "--domains" and i + 1 < len(args):
|
|
154
|
+
domains = [d.strip() for d in args[i + 1].split(",")]
|
|
70
155
|
i += 2
|
|
71
156
|
else:
|
|
72
157
|
i += 1
|
|
73
158
|
|
|
74
159
|
# We'll build a shell script that compares responses
|
|
75
160
|
# This is stored and executed
|
|
76
|
-
return {
|
|
77
|
-
'domains': domains,
|
|
78
|
-
'target': target,
|
|
79
|
-
'timeout': 120
|
|
80
|
-
}
|
|
161
|
+
return {"domains": domains, "target": target, "timeout": 120}
|
|
81
162
|
|
|
82
|
-
def run(
|
|
163
|
+
def run(
|
|
164
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
165
|
+
) -> int:
|
|
83
166
|
"""Execute DNS hijack detection."""
|
|
84
167
|
cmd_spec = self.build_command(target, args, label, log_path)
|
|
85
168
|
if cmd_spec is None:
|
|
86
169
|
return 1
|
|
87
170
|
|
|
88
|
-
domains = cmd_spec[
|
|
89
|
-
reference_dns =
|
|
171
|
+
domains = cmd_spec["domains"]
|
|
172
|
+
reference_dns = "8.8.8.8" # Google DNS as reference
|
|
90
173
|
|
|
91
174
|
if log_path:
|
|
92
|
-
with open(log_path,
|
|
175
|
+
with open(log_path, "w") as f:
|
|
93
176
|
f.write(f"# DNS Hijack Detection on {target}\n")
|
|
94
177
|
f.write(f"# Reference DNS: {reference_dns}\n")
|
|
95
178
|
f.write(f"# Test domains: {', '.join(domains)}\n")
|
|
@@ -99,7 +182,7 @@ class DNSHijackPlugin(PluginBase):
|
|
|
99
182
|
|
|
100
183
|
try:
|
|
101
184
|
for domain in domains:
|
|
102
|
-
with open(log_path,
|
|
185
|
+
with open(log_path, "a") as f:
|
|
103
186
|
f.write(f"\n{'='*60}\n")
|
|
104
187
|
f.write(f"Testing: {domain}\n")
|
|
105
188
|
f.write(f"{'='*60}\n\n")
|
|
@@ -107,32 +190,40 @@ class DNSHijackPlugin(PluginBase):
|
|
|
107
190
|
# Query target router
|
|
108
191
|
try:
|
|
109
192
|
router_result = subprocess.run(
|
|
110
|
-
[
|
|
193
|
+
["dig", "+short", f"@{target}", domain, "A"],
|
|
111
194
|
capture_output=True,
|
|
112
195
|
text=True,
|
|
113
|
-
timeout=10
|
|
196
|
+
timeout=10,
|
|
197
|
+
)
|
|
198
|
+
router_ips = (
|
|
199
|
+
set(router_result.stdout.strip().split("\n"))
|
|
200
|
+
if router_result.stdout.strip()
|
|
201
|
+
else set()
|
|
114
202
|
)
|
|
115
|
-
router_ips = set(router_result.stdout.strip().split('\n')) if router_result.stdout.strip() else set()
|
|
116
203
|
except subprocess.TimeoutExpired:
|
|
117
204
|
router_ips = set()
|
|
118
|
-
with open(log_path,
|
|
205
|
+
with open(log_path, "a") as f:
|
|
119
206
|
f.write(f" Router DNS (@{target}): TIMEOUT\n")
|
|
120
207
|
|
|
121
208
|
# Query reference DNS
|
|
122
209
|
try:
|
|
123
210
|
ref_result = subprocess.run(
|
|
124
|
-
[
|
|
211
|
+
["dig", "+short", f"@{reference_dns}", domain, "A"],
|
|
125
212
|
capture_output=True,
|
|
126
213
|
text=True,
|
|
127
|
-
timeout=10
|
|
214
|
+
timeout=10,
|
|
215
|
+
)
|
|
216
|
+
ref_ips = (
|
|
217
|
+
set(ref_result.stdout.strip().split("\n"))
|
|
218
|
+
if ref_result.stdout.strip()
|
|
219
|
+
else set()
|
|
128
220
|
)
|
|
129
|
-
ref_ips = set(ref_result.stdout.strip().split('\n')) if ref_result.stdout.strip() else set()
|
|
130
221
|
except subprocess.TimeoutExpired:
|
|
131
222
|
ref_ips = set()
|
|
132
|
-
with open(log_path,
|
|
223
|
+
with open(log_path, "a") as f:
|
|
133
224
|
f.write(f" Reference DNS (@{reference_dns}): TIMEOUT\n")
|
|
134
225
|
|
|
135
|
-
with open(log_path,
|
|
226
|
+
with open(log_path, "a") as f:
|
|
136
227
|
f.write(f" Router DNS (@{target}):\n")
|
|
137
228
|
for ip in sorted(router_ips):
|
|
138
229
|
f.write(f" {ip}\n")
|
|
@@ -149,50 +240,64 @@ class DNSHijackPlugin(PluginBase):
|
|
|
149
240
|
f.write(f" Router only: {router_ips - ref_ips}\n")
|
|
150
241
|
f.write(f" Reference only: {ref_ips - router_ips}\n")
|
|
151
242
|
else:
|
|
152
|
-
f.write(
|
|
243
|
+
f.write(
|
|
244
|
+
f"\n [ALERT] No matching IPs - possible DNS hijack!\n"
|
|
245
|
+
)
|
|
153
246
|
hijack_detected = True
|
|
154
247
|
elif router_ips and not ref_ips:
|
|
155
|
-
f.write(
|
|
248
|
+
f.write(
|
|
249
|
+
f"\n [WARN] Router returned IPs but reference didn't\n"
|
|
250
|
+
)
|
|
156
251
|
elif ref_ips and not router_ips:
|
|
157
|
-
f.write(
|
|
252
|
+
f.write(
|
|
253
|
+
f"\n [WARN] Reference returned IPs but router didn't\n"
|
|
254
|
+
)
|
|
158
255
|
|
|
159
256
|
# Test NXDOMAIN hijacking
|
|
160
|
-
with open(log_path,
|
|
257
|
+
with open(log_path, "a") as f:
|
|
161
258
|
f.write(f"\n{'='*60}\n")
|
|
162
259
|
f.write("Testing NXDOMAIN hijacking (nonexistent domain):\n")
|
|
163
260
|
f.write(f"{'='*60}\n\n")
|
|
164
261
|
|
|
165
|
-
fake_domain =
|
|
262
|
+
fake_domain = "thisisafakedomainthatdoesnotexist12345.com"
|
|
166
263
|
|
|
167
264
|
try:
|
|
168
265
|
nxdomain_result = subprocess.run(
|
|
169
|
-
[
|
|
266
|
+
["dig", "+short", f"@{target}", fake_domain, "A"],
|
|
170
267
|
capture_output=True,
|
|
171
268
|
text=True,
|
|
172
|
-
timeout=10
|
|
269
|
+
timeout=10,
|
|
173
270
|
)
|
|
174
271
|
nxdomain_ips = nxdomain_result.stdout.strip()
|
|
175
272
|
|
|
176
|
-
with open(log_path,
|
|
273
|
+
with open(log_path, "a") as f:
|
|
177
274
|
if nxdomain_ips:
|
|
178
|
-
f.write(
|
|
179
|
-
|
|
275
|
+
f.write(
|
|
276
|
+
f" [ALERT] Router returns IPs for nonexistent domain!\n"
|
|
277
|
+
)
|
|
278
|
+
f.write(
|
|
279
|
+
f" This indicates NXDOMAIN hijacking (likely ads/search redirect)\n"
|
|
280
|
+
)
|
|
180
281
|
f.write(f" Returned IPs: {nxdomain_ips}\n")
|
|
181
282
|
hijack_detected = True
|
|
182
283
|
else:
|
|
183
|
-
f.write(
|
|
284
|
+
f.write(
|
|
285
|
+
f" [OK] Router correctly returns no IPs for nonexistent domain\n"
|
|
286
|
+
)
|
|
184
287
|
except subprocess.TimeoutExpired:
|
|
185
|
-
with open(log_path,
|
|
288
|
+
with open(log_path, "a") as f:
|
|
186
289
|
f.write(f" [WARN] NXDOMAIN test timed out\n")
|
|
187
290
|
|
|
188
291
|
# Summary
|
|
189
|
-
with open(log_path,
|
|
292
|
+
with open(log_path, "a") as f:
|
|
190
293
|
f.write(f"\n{'='*60}\n")
|
|
191
294
|
f.write("SUMMARY\n")
|
|
192
295
|
f.write(f"{'='*60}\n\n")
|
|
193
296
|
if hijack_detected:
|
|
194
297
|
f.write(" [!] POTENTIAL DNS HIJACKING DETECTED\n")
|
|
195
|
-
f.write(
|
|
298
|
+
f.write(
|
|
299
|
+
" Investigate the router for malware or misconfiguration.\n"
|
|
300
|
+
)
|
|
196
301
|
else:
|
|
197
302
|
f.write(" [OK] No obvious DNS hijacking detected\n")
|
|
198
303
|
|
|
@@ -200,7 +305,7 @@ class DNSHijackPlugin(PluginBase):
|
|
|
200
305
|
|
|
201
306
|
except Exception as e:
|
|
202
307
|
if log_path:
|
|
203
|
-
with open(log_path,
|
|
308
|
+
with open(log_path, "a") as f:
|
|
204
309
|
f.write(f"\n\n# ERROR: {e}\n")
|
|
205
310
|
return 1
|
|
206
311
|
|