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/wpscan.py
CHANGED
|
@@ -4,6 +4,7 @@ souleyez.plugins.wpscan
|
|
|
4
4
|
|
|
5
5
|
WPScan WordPress vulnerability scanner plugin.
|
|
6
6
|
"""
|
|
7
|
+
import os
|
|
7
8
|
import subprocess
|
|
8
9
|
import time
|
|
9
10
|
from typing import List
|
|
@@ -29,12 +30,15 @@ HELP = {
|
|
|
29
30
|
"usage": "souleyez jobs enqueue wpscan <url>",
|
|
30
31
|
"examples": [
|
|
31
32
|
"souleyez jobs enqueue wpscan http://example.com",
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
'souleyez jobs enqueue wpscan http://example.com --args "--enumerate vp"',
|
|
34
|
+
'souleyez jobs enqueue wpscan http://example.com --args "--enumerate u,ap,at"',
|
|
35
|
+
'souleyez jobs enqueue wpscan http://example.com --args "--passwords data/wordlists/top100.txt"',
|
|
35
36
|
],
|
|
36
37
|
"flags": [
|
|
37
|
-
[
|
|
38
|
+
[
|
|
39
|
+
"--enumerate <opts>",
|
|
40
|
+
"Enumerate: u (users), p (plugins), t (themes), vp (vulnerable plugins), vt (vulnerable themes)",
|
|
41
|
+
],
|
|
38
42
|
["--plugins-detection <mode>", "Detection mode: mixed, passive, aggressive"],
|
|
39
43
|
["--passwords <file>", "Password list for brute-force attacks"],
|
|
40
44
|
["--usernames <list>", "Usernames to use for brute-force (comma-separated)"],
|
|
@@ -43,58 +47,100 @@ HELP = {
|
|
|
43
47
|
["--api-token <token>", "WPVulnDB API token for vulnerability data"],
|
|
44
48
|
],
|
|
45
49
|
"presets": [
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
{
|
|
51
|
+
"name": "Quick Scan",
|
|
52
|
+
"args": ["--random-user-agent"],
|
|
53
|
+
"desc": "Basic WordPress detection and version check",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "Full Enumeration",
|
|
57
|
+
"args": ["--enumerate", "ap,at,u", "--random-user-agent"],
|
|
58
|
+
"desc": "Enumerate all plugins, themes, and users",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "Vulnerable Plugins",
|
|
62
|
+
"args": [
|
|
63
|
+
"--enumerate",
|
|
64
|
+
"vp",
|
|
65
|
+
"--plugins-detection",
|
|
66
|
+
"aggressive",
|
|
67
|
+
"--random-user-agent",
|
|
68
|
+
],
|
|
69
|
+
"desc": "Find vulnerable plugins only",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "User Enumeration",
|
|
73
|
+
"args": ["--enumerate", "u", "--random-user-agent"],
|
|
74
|
+
"desc": "Enumerate WordPress users",
|
|
75
|
+
},
|
|
50
76
|
],
|
|
51
77
|
"help_sections": [
|
|
52
78
|
{
|
|
53
79
|
"title": "What is WPScan?",
|
|
54
80
|
"color": "cyan",
|
|
55
81
|
"content": [
|
|
56
|
-
{
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
{
|
|
83
|
+
"title": "Overview",
|
|
84
|
+
"desc": "WPScan is the de-facto WordPress vulnerability scanner, identifying WordPress version, plugins, themes, misconfigurations, and known vulnerabilities.",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"title": "Use Cases",
|
|
88
|
+
"desc": "Essential for WordPress security assessments",
|
|
89
|
+
"tips": [
|
|
90
|
+
"Detect WordPress version and vulnerabilities",
|
|
91
|
+
"Enumerate installed plugins and themes",
|
|
92
|
+
"Find security misconfigurations",
|
|
93
|
+
"Test for weak passwords via brute-force",
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
64
97
|
},
|
|
65
98
|
{
|
|
66
99
|
"title": "How to Use",
|
|
67
100
|
"color": "green",
|
|
68
101
|
"content": [
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
{
|
|
103
|
+
"title": "Basic Workflow",
|
|
104
|
+
"desc": "1. Run quick scan to detect WordPress version\n 2. Enumerate vulnerable plugins/themes (vp,vt)\n 3. Check for users and misconfigurations\n 4. Test weak passwords if authorized",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"title": "Enumeration Options",
|
|
108
|
+
"desc": "Key flags for different scans",
|
|
109
|
+
"tips": [
|
|
110
|
+
"vp: Vulnerable plugins only",
|
|
111
|
+
"ap: All plugins (slow but thorough)",
|
|
112
|
+
"u: User enumeration",
|
|
113
|
+
"--passwords: Brute-force password file",
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
77
117
|
},
|
|
78
118
|
{
|
|
79
119
|
"title": "Tips & Best Practices",
|
|
80
120
|
"color": "yellow",
|
|
81
121
|
"content": [
|
|
82
|
-
(
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
(
|
|
123
|
+
"Best Practices:",
|
|
124
|
+
[
|
|
125
|
+
"Always use --random-user-agent to avoid detection",
|
|
126
|
+
"Start with vulnerable plugins/themes only (vp,vt)",
|
|
127
|
+
"Use WPVulnDB API token for full vulnerability data",
|
|
128
|
+
"Document outdated plugins as security findings",
|
|
129
|
+
"Test password lists only with explicit authorization",
|
|
130
|
+
],
|
|
131
|
+
),
|
|
132
|
+
(
|
|
133
|
+
"Common Issues:",
|
|
134
|
+
[
|
|
135
|
+
"Not WordPress site: Verify URL is a WordPress installation",
|
|
136
|
+
"Rate limiting: Add delays or reduce enumeration scope",
|
|
137
|
+
"No vulnerabilities found: Update WPScan or use API token",
|
|
138
|
+
"Enumeration blocked: Some hosts block automated scanners",
|
|
139
|
+
],
|
|
140
|
+
),
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
98
144
|
}
|
|
99
145
|
|
|
100
146
|
|
|
@@ -104,37 +150,64 @@ class WpscanPlugin(PluginBase):
|
|
|
104
150
|
category = "vulnerability_analysis"
|
|
105
151
|
HELP = HELP
|
|
106
152
|
|
|
107
|
-
|
|
108
153
|
def _get_base_url(self, url: str) -> str:
|
|
109
154
|
"""
|
|
110
|
-
Extract
|
|
155
|
+
Extract WordPress root URL from a full URL.
|
|
111
156
|
|
|
112
157
|
WPScan needs the WordPress root URL, not subpaths like /wp-content.
|
|
113
|
-
|
|
158
|
+
For WordPress in subdirectories, we preserve the parent path.
|
|
159
|
+
|
|
160
|
+
Examples:
|
|
161
|
+
http://10.0.0.48/wp-content → http://10.0.0.48/
|
|
162
|
+
http://10.0.0.48/blogblog/wp-admin/ → http://10.0.0.48/blogblog/
|
|
163
|
+
http://10.0.0.48/site/wordpress/wp-includes/ → http://10.0.0.48/site/wordpress/
|
|
114
164
|
"""
|
|
115
165
|
parsed = urlparse(url)
|
|
116
|
-
|
|
117
|
-
|
|
166
|
+
path = parsed.path
|
|
167
|
+
|
|
168
|
+
# WordPress subdirectory patterns to strip
|
|
169
|
+
# These indicate we're inside the WordPress installation
|
|
170
|
+
wp_subpaths = ["/wp-admin", "/wp-content", "/wp-includes", "/wp-login.php"]
|
|
171
|
+
|
|
172
|
+
# Find and strip WordPress-specific subpaths
|
|
173
|
+
for wp_sub in wp_subpaths:
|
|
174
|
+
idx = path.lower().find(wp_sub.lower())
|
|
175
|
+
if idx != -1:
|
|
176
|
+
# Keep everything before the WordPress subpath
|
|
177
|
+
path = path[:idx]
|
|
178
|
+
break
|
|
179
|
+
|
|
180
|
+
# Ensure path ends with /
|
|
181
|
+
if not path.endswith("/"):
|
|
182
|
+
path = path + "/"
|
|
183
|
+
|
|
184
|
+
# If path is empty, use root
|
|
185
|
+
if not path:
|
|
186
|
+
path = "/"
|
|
187
|
+
|
|
188
|
+
base = urlunparse((parsed.scheme, parsed.netloc, path, "", "", ""))
|
|
118
189
|
return base
|
|
119
190
|
|
|
120
|
-
def build_command(
|
|
191
|
+
def build_command(
|
|
192
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
193
|
+
):
|
|
121
194
|
"""Build command for background execution with PID tracking."""
|
|
122
195
|
if not target:
|
|
123
196
|
if log_path:
|
|
124
|
-
with open(log_path,
|
|
197
|
+
with open(log_path, "w") as f:
|
|
125
198
|
f.write("ERROR: Target URL is required\n")
|
|
126
199
|
return None
|
|
127
200
|
|
|
128
201
|
# Ensure URL format
|
|
129
|
-
if not target.startswith(
|
|
130
|
-
target = f
|
|
202
|
+
if not target.startswith("http://") and not target.startswith("https://"):
|
|
203
|
+
target = f"http://{target}"
|
|
131
204
|
|
|
132
205
|
# Validate URL
|
|
133
206
|
try:
|
|
134
207
|
target = validate_url(target)
|
|
135
208
|
except ValidationError as e:
|
|
136
209
|
if log_path:
|
|
137
|
-
with open(log_path,
|
|
210
|
+
with open(log_path, "w") as f:
|
|
138
211
|
f.write(f"ERROR: Invalid URL: {e}\n")
|
|
139
212
|
return None
|
|
140
213
|
|
|
@@ -144,20 +217,31 @@ class WpscanPlugin(PluginBase):
|
|
|
144
217
|
|
|
145
218
|
args = args or []
|
|
146
219
|
|
|
220
|
+
# Add --disable-tls-checks for HTTPS targets (handles self-signed certs)
|
|
221
|
+
if target.startswith("https://") and "--disable-tls-checks" not in args:
|
|
222
|
+
args = ["--disable-tls-checks"] + args
|
|
223
|
+
|
|
224
|
+
# Auto-add API token from environment if not already specified
|
|
225
|
+
if "--api-token" not in " ".join(args):
|
|
226
|
+
api_token = os.environ.get("WPSCAN_API_TOKEN")
|
|
227
|
+
if api_token:
|
|
228
|
+
args = ["--api-token", api_token] + args
|
|
229
|
+
|
|
147
230
|
# wpscan uses --url flag
|
|
148
231
|
cmd = ["wpscan", "--url", target] + args
|
|
149
232
|
|
|
150
233
|
# Log if we modified the URL
|
|
151
234
|
if log_path and original_target != target:
|
|
152
|
-
with open(log_path,
|
|
153
|
-
f.write(
|
|
235
|
+
with open(log_path, "w") as f:
|
|
236
|
+
f.write(
|
|
237
|
+
f"INFO: Using base URL {target} (original: {original_target})\n\n"
|
|
238
|
+
)
|
|
154
239
|
|
|
155
|
-
return {
|
|
156
|
-
'cmd': cmd,
|
|
157
|
-
'timeout': 1800
|
|
158
|
-
}
|
|
240
|
+
return {"cmd": cmd, "timeout": 1800}
|
|
159
241
|
|
|
160
|
-
def run(
|
|
242
|
+
def run(
|
|
243
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
244
|
+
) -> int:
|
|
161
245
|
"""
|
|
162
246
|
Execute WPScan and write output to log_path.
|
|
163
247
|
"""
|
|
@@ -165,15 +249,15 @@ class WpscanPlugin(PluginBase):
|
|
|
165
249
|
raise ValueError("Target URL is required")
|
|
166
250
|
|
|
167
251
|
# Ensure URL format
|
|
168
|
-
if not target.startswith(
|
|
169
|
-
target = f
|
|
252
|
+
if not target.startswith("http://") and not target.startswith("https://"):
|
|
253
|
+
target = f"http://{target}"
|
|
170
254
|
|
|
171
255
|
# Validate URL
|
|
172
256
|
try:
|
|
173
257
|
target = validate_url(target)
|
|
174
258
|
except ValidationError as e:
|
|
175
259
|
if log_path:
|
|
176
|
-
with open(log_path,
|
|
260
|
+
with open(log_path, "w") as f:
|
|
177
261
|
f.write(f"ERROR: Invalid URL: {e}\n")
|
|
178
262
|
return 1
|
|
179
263
|
raise ValueError(f"Invalid URL: {e}")
|
|
@@ -184,24 +268,44 @@ class WpscanPlugin(PluginBase):
|
|
|
184
268
|
if args is None:
|
|
185
269
|
args = []
|
|
186
270
|
|
|
271
|
+
# Add --disable-tls-checks for HTTPS targets (handles self-signed certs)
|
|
272
|
+
if target.startswith("https://") and "--disable-tls-checks" not in args:
|
|
273
|
+
args = ["--disable-tls-checks"] + args
|
|
274
|
+
|
|
275
|
+
# Auto-add API token from environment if not already specified
|
|
276
|
+
if "--api-token" not in " ".join(args):
|
|
277
|
+
api_token = os.environ.get("WPSCAN_API_TOKEN")
|
|
278
|
+
if api_token:
|
|
279
|
+
args = ["--api-token", api_token] + args
|
|
280
|
+
|
|
187
281
|
cmd = ["wpscan", "--url", target] + args
|
|
188
282
|
|
|
189
283
|
if log_path:
|
|
190
|
-
|
|
284
|
+
# Redact API token from logged command
|
|
285
|
+
logged_cmd = []
|
|
286
|
+
skip_next = False
|
|
287
|
+
for arg in cmd:
|
|
288
|
+
if skip_next:
|
|
289
|
+
logged_cmd.append("[REDACTED]")
|
|
290
|
+
skip_next = False
|
|
291
|
+
elif arg == "--api-token":
|
|
292
|
+
logged_cmd.append(arg)
|
|
293
|
+
skip_next = True
|
|
294
|
+
else:
|
|
295
|
+
logged_cmd.append(arg)
|
|
296
|
+
|
|
297
|
+
with open(log_path, "w") as f:
|
|
191
298
|
f.write(f"# WPScan for {target}\n")
|
|
192
|
-
f.write(f"# Command: {' '.join(
|
|
299
|
+
f.write(f"# Command: {' '.join(logged_cmd)}\n")
|
|
193
300
|
f.write(f"# Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
|
194
301
|
|
|
195
302
|
try:
|
|
196
303
|
result = subprocess.run(
|
|
197
|
-
cmd,
|
|
198
|
-
capture_output=True,
|
|
199
|
-
text=True,
|
|
200
|
-
timeout=600 # 10 minutes
|
|
304
|
+
cmd, capture_output=True, text=True, timeout=600 # 10 minutes
|
|
201
305
|
)
|
|
202
306
|
|
|
203
307
|
if log_path:
|
|
204
|
-
with open(log_path,
|
|
308
|
+
with open(log_path, "a") as f:
|
|
205
309
|
f.write(result.stdout)
|
|
206
310
|
if result.stderr:
|
|
207
311
|
f.write(f"\n\n# Errors:\n{result.stderr}\n")
|
|
@@ -210,12 +314,12 @@ class WpscanPlugin(PluginBase):
|
|
|
210
314
|
|
|
211
315
|
except subprocess.TimeoutExpired:
|
|
212
316
|
if log_path:
|
|
213
|
-
with open(log_path,
|
|
317
|
+
with open(log_path, "a") as f:
|
|
214
318
|
f.write("\n\n# ERROR: Command timed out after 10 minutes\n")
|
|
215
319
|
return 124
|
|
216
320
|
except Exception as e:
|
|
217
321
|
if log_path:
|
|
218
|
-
with open(log_path,
|
|
322
|
+
with open(log_path, "a") as f:
|
|
219
323
|
f.write(f"\n\n# ERROR: {str(e)}\n")
|
|
220
324
|
return 1
|
|
221
325
|
|
souleyez/reporting/__init__.py
CHANGED