souleyez 2.43.29__py3-none-any.whl → 3.0.0__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 +9564 -2881
- 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 +564 -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 +409 -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 +417 -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 +913 -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 +219 -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 +237 -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 +23034 -10679
- 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-3.0.0.dist-info}/METADATA +2 -2
- souleyez-3.0.0.dist-info/RECORD +443 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
- souleyez-2.43.29.dist-info/RECORD +0 -379
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
souleyez.plugins.evil_winrm
|
|
4
|
+
|
|
5
|
+
Evil-WinRM - Windows Remote Management Shell plugin.
|
|
6
|
+
"""
|
|
7
|
+
import subprocess
|
|
8
|
+
import time
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
from .plugin_base import PluginBase
|
|
12
|
+
|
|
13
|
+
HELP = {
|
|
14
|
+
"name": "Evil-WinRM - Windows Remote Shell",
|
|
15
|
+
"description": (
|
|
16
|
+
"Got Windows creds and need a shell?\n\n"
|
|
17
|
+
"Evil-WinRM is the ultimate WinRM shell for hacking. It provides a fully "
|
|
18
|
+
"interactive PowerShell session on Windows targets over WinRM (port 5985/5986).\n\n"
|
|
19
|
+
"Perfect for post-exploitation after discovering valid credentials through "
|
|
20
|
+
"Hydra, secretsdump, or other credential attacks.\n\n"
|
|
21
|
+
"Quick tips:\n"
|
|
22
|
+
"- Supports password, NTLM hash (pass-the-hash), and Kerberos authentication\n"
|
|
23
|
+
"- Built-in file upload/download functionality\n"
|
|
24
|
+
"- Execute commands non-interactively with -c flag\n"
|
|
25
|
+
"- Works when SMB is blocked but WinRM is open\n"
|
|
26
|
+
"- Default ports: 5985 (HTTP) and 5986 (HTTPS/SSL)\n"
|
|
27
|
+
),
|
|
28
|
+
"usage": 'souleyez jobs enqueue evil_winrm <target> --args "-u <user> -p <pass>"',
|
|
29
|
+
"examples": [
|
|
30
|
+
'souleyez jobs enqueue evil_winrm 192.168.1.10 --args "-u administrator -p Password123!"',
|
|
31
|
+
'souleyez jobs enqueue evil_winrm 192.168.1.10 --args "-u admin -H aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0"',
|
|
32
|
+
"souleyez jobs enqueue evil_winrm 192.168.1.10 --args \"-u admin -p Password123! -c 'whoami /all'\"",
|
|
33
|
+
"souleyez jobs enqueue evil_winrm 192.168.1.10 --args \"-u admin@DOMAIN -p Password123! -c 'hostname'\"",
|
|
34
|
+
],
|
|
35
|
+
"flags": [
|
|
36
|
+
["-i, --ip <IP>", "Remote host IP or hostname"],
|
|
37
|
+
["-u, --user <USER>", "Username for authentication"],
|
|
38
|
+
["-p, --password <PASS>", "Password for authentication"],
|
|
39
|
+
["-H, --hash <HASH>", "NTLM hash for pass-the-hash (LM:NT or just NT)"],
|
|
40
|
+
["-P, --port <PORT>", "WinRM port (default: 5985)"],
|
|
41
|
+
["-s, --ssl", "Enable SSL (port 5986)"],
|
|
42
|
+
["-c, --command <CMD>", "Execute command and exit (non-interactive)"],
|
|
43
|
+
["-S, --scripts <PATH>", "PowerShell scripts local path"],
|
|
44
|
+
["-e, --executables <PATH>", "C# executables local path"],
|
|
45
|
+
["-r, --realm <DOMAIN>", "Kerberos realm (domain)"],
|
|
46
|
+
],
|
|
47
|
+
"preset_categories": {
|
|
48
|
+
"authentication": [
|
|
49
|
+
{
|
|
50
|
+
"name": "Password Auth",
|
|
51
|
+
"args": ["-u", "administrator", "-p", "PASSWORD"],
|
|
52
|
+
"desc": "Authenticate with username and password",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "Pass-the-Hash",
|
|
56
|
+
"args": ["-u", "administrator", "-H", "HASH"],
|
|
57
|
+
"desc": "Authenticate with NTLM hash",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "SSL Connection",
|
|
61
|
+
"args": ["-u", "administrator", "-p", "PASSWORD", "-s", "-P", "5986"],
|
|
62
|
+
"desc": "Connect over SSL (HTTPS)",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
"command_execution": [
|
|
66
|
+
{
|
|
67
|
+
"name": "Whoami",
|
|
68
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "whoami /all"],
|
|
69
|
+
"desc": "Check current user and privileges",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "System Info",
|
|
73
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "systeminfo"],
|
|
74
|
+
"desc": "Get system information",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "Network Info",
|
|
78
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "ipconfig /all"],
|
|
79
|
+
"desc": "Get network configuration",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "List Users",
|
|
83
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "net user"],
|
|
84
|
+
"desc": "List local users",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "List Domain Users",
|
|
88
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "net user /domain"],
|
|
89
|
+
"desc": "List domain users",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
"enumeration": [
|
|
93
|
+
{
|
|
94
|
+
"name": "Enum Shares",
|
|
95
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "net share"],
|
|
96
|
+
"desc": "List network shares",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "Enum Services",
|
|
100
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "sc query"],
|
|
101
|
+
"desc": "List running services",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "Enum Processes",
|
|
105
|
+
"args": ["-u", "USER", "-p", "PASSWORD", "-c", "tasklist"],
|
|
106
|
+
"desc": "List running processes",
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
"presets": [],
|
|
111
|
+
"common_options": {
|
|
112
|
+
"-i": "Target IP address (can also be positional)",
|
|
113
|
+
"-u": "Username (user@domain for domain accounts)",
|
|
114
|
+
"-p": "Password",
|
|
115
|
+
"-H": "NTLM hash (format: LM:NT or just NT)",
|
|
116
|
+
"-P": "Port number (default 5985, use 5986 for SSL)",
|
|
117
|
+
"-s": "Enable SSL connection",
|
|
118
|
+
"-c": "Command to execute (non-interactive mode)",
|
|
119
|
+
},
|
|
120
|
+
"notes": [
|
|
121
|
+
"Requires evil-winrm gem installed (gem install evil-winrm)",
|
|
122
|
+
"Target must have WinRM enabled (port 5985 or 5986)",
|
|
123
|
+
"For domain accounts, use user@domain or domain\\\\user format",
|
|
124
|
+
"Pass-the-hash only works with local admin accounts (not domain accounts)",
|
|
125
|
+
"Use -c for non-interactive command execution in automated chains",
|
|
126
|
+
],
|
|
127
|
+
"help_sections": [
|
|
128
|
+
{
|
|
129
|
+
"title": "What is Evil-WinRM?",
|
|
130
|
+
"color": "cyan",
|
|
131
|
+
"content": [
|
|
132
|
+
{
|
|
133
|
+
"title": "Overview",
|
|
134
|
+
"desc": "Evil-WinRM is a WinRM shell for pentesting that provides a fully interactive PowerShell session over Windows Remote Management.",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"title": "Use Cases",
|
|
138
|
+
"desc": "Post-exploitation access to Windows systems",
|
|
139
|
+
"tips": [
|
|
140
|
+
"Shell access after credential discovery",
|
|
141
|
+
"Pass-the-hash attacks with NTLM hashes",
|
|
142
|
+
"File upload/download for data exfil",
|
|
143
|
+
"Command execution for enumeration",
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"title": "How to Use",
|
|
150
|
+
"color": "green",
|
|
151
|
+
"content": [
|
|
152
|
+
{
|
|
153
|
+
"title": "Basic Workflow",
|
|
154
|
+
"desc": "1. Find valid credentials (Hydra, secretsdump, etc.)\n 2. Check if WinRM is open (port 5985/5986)\n 3. Connect with evil-winrm using creds\n 4. Run commands or drop into interactive shell",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"title": "Authentication Methods",
|
|
158
|
+
"desc": "Different ways to authenticate",
|
|
159
|
+
"tips": [
|
|
160
|
+
"Password: -u user -p password",
|
|
161
|
+
"NTLM Hash: -u user -H hash (pass-the-hash)",
|
|
162
|
+
"Kerberos: -u user@domain -r REALM",
|
|
163
|
+
"SSL: Add -s flag for port 5986",
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"title": "Tips & Best Practices",
|
|
170
|
+
"color": "yellow",
|
|
171
|
+
"content": [
|
|
172
|
+
(
|
|
173
|
+
"Best Practices:",
|
|
174
|
+
[
|
|
175
|
+
"Use -c flag for automated command execution",
|
|
176
|
+
"Check 'whoami /priv' for privilege escalation vectors",
|
|
177
|
+
"Use domain\\\\user or user@domain format for AD",
|
|
178
|
+
"Try both port 5985 and 5986 if one fails",
|
|
179
|
+
],
|
|
180
|
+
),
|
|
181
|
+
(
|
|
182
|
+
"Common Issues:",
|
|
183
|
+
[
|
|
184
|
+
"Access denied: Check credentials and permissions",
|
|
185
|
+
"Connection refused: WinRM may be disabled",
|
|
186
|
+
"Timeout: Target may be filtering WinRM ports",
|
|
187
|
+
"Kerberos errors: Check realm and DNS settings",
|
|
188
|
+
],
|
|
189
|
+
),
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Flatten presets from categories
|
|
196
|
+
for category_presets in HELP["preset_categories"].values():
|
|
197
|
+
HELP["presets"].extend(category_presets)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class EvilWinRMPlugin(PluginBase):
|
|
201
|
+
name = "Evil-WinRM"
|
|
202
|
+
tool = "evil_winrm"
|
|
203
|
+
category = "lateral_movement"
|
|
204
|
+
HELP = HELP
|
|
205
|
+
|
|
206
|
+
def build_command(
|
|
207
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
208
|
+
):
|
|
209
|
+
"""Build command for background execution with PID tracking."""
|
|
210
|
+
args = args or []
|
|
211
|
+
|
|
212
|
+
# Build evil-winrm command
|
|
213
|
+
cmd = ["evil-winrm", "-i", target]
|
|
214
|
+
|
|
215
|
+
# Add any extra arguments
|
|
216
|
+
cmd.extend(args)
|
|
217
|
+
|
|
218
|
+
return {"cmd": cmd, "timeout": 300} # 5 minute timeout for commands
|
|
219
|
+
|
|
220
|
+
def run(
|
|
221
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
222
|
+
) -> int:
|
|
223
|
+
"""Execute Evil-WinRM."""
|
|
224
|
+
args = args or []
|
|
225
|
+
|
|
226
|
+
if log_path:
|
|
227
|
+
return self._run_with_logpath(target, args, log_path)
|
|
228
|
+
|
|
229
|
+
return self._run_legacy(target, args)
|
|
230
|
+
|
|
231
|
+
def _run_with_logpath(self, target: str, args: List[str], log_path: str) -> int:
|
|
232
|
+
"""Run Evil-WinRM and write output to log_path."""
|
|
233
|
+
try:
|
|
234
|
+
cmd = ["evil-winrm", "-i", target]
|
|
235
|
+
cmd.extend(args)
|
|
236
|
+
|
|
237
|
+
with open(log_path, "w", encoding="utf-8", errors="replace") as fh:
|
|
238
|
+
fh.write("=== Evil-WinRM Session ===\n")
|
|
239
|
+
fh.write(f"Target: {target}\n")
|
|
240
|
+
fh.write(f"Args: {' '.join(args)}\n")
|
|
241
|
+
fh.write(
|
|
242
|
+
f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n\n"
|
|
243
|
+
)
|
|
244
|
+
fh.write(f"Command: {' '.join(cmd)}\n\n")
|
|
245
|
+
fh.flush()
|
|
246
|
+
|
|
247
|
+
# Run evil-winrm
|
|
248
|
+
proc = subprocess.run(
|
|
249
|
+
cmd,
|
|
250
|
+
stdout=fh,
|
|
251
|
+
stderr=subprocess.STDOUT,
|
|
252
|
+
timeout=300, # 5 minutes
|
|
253
|
+
check=False,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
fh.write(
|
|
257
|
+
f"\n\nCompleted: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n"
|
|
258
|
+
)
|
|
259
|
+
fh.write(f"Exit Code: {proc.returncode}\n")
|
|
260
|
+
|
|
261
|
+
return proc.returncode
|
|
262
|
+
|
|
263
|
+
except subprocess.TimeoutExpired:
|
|
264
|
+
with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
|
|
265
|
+
fh.write("\nERROR: Evil-WinRM command timed out after 300 seconds\n")
|
|
266
|
+
return 124
|
|
267
|
+
|
|
268
|
+
except FileNotFoundError:
|
|
269
|
+
with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
|
|
270
|
+
fh.write("\nERROR: evil-winrm not found in PATH\n")
|
|
271
|
+
fh.write("Install with: gem install evil-winrm\n")
|
|
272
|
+
return 127
|
|
273
|
+
|
|
274
|
+
except Exception as e:
|
|
275
|
+
with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
|
|
276
|
+
fh.write(f"\nERROR: {type(e).__name__}: {e}\n")
|
|
277
|
+
return 1
|
|
278
|
+
|
|
279
|
+
def _run_legacy(self, target: str, args: List[str]) -> int:
|
|
280
|
+
"""Legacy execution without log_path."""
|
|
281
|
+
cmd = ["evil-winrm", "-i", target]
|
|
282
|
+
cmd.extend(args)
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
proc = subprocess.run(cmd, capture_output=True, timeout=300, check=False)
|
|
286
|
+
return proc.returncode
|
|
287
|
+
except Exception:
|
|
288
|
+
return 1
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
plugin = EvilWinRMPlugin()
|
souleyez/plugins/ffuf.py
CHANGED
|
@@ -26,11 +26,11 @@ HELP = {
|
|
|
26
26
|
"- Use -e flag to append extensions automatically\n"
|
|
27
27
|
"- Results are JSON-formatted for easy parsing\n"
|
|
28
28
|
),
|
|
29
|
-
"usage":
|
|
29
|
+
"usage": 'souleyez jobs enqueue ffuf <target> --args "-w wordlist.txt"',
|
|
30
30
|
"examples": [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
'souleyez jobs enqueue ffuf http://example.com/FUZZ --args "-w data/wordlists/web_dirs_common.txt"',
|
|
32
|
+
'souleyez jobs enqueue ffuf http://example.com/FUZZ --args "-w wordlist.txt -e .php,.html,.txt"',
|
|
33
|
+
'souleyez jobs enqueue ffuf http://example.com/?id=FUZZ --args "-w numbers.txt"',
|
|
34
34
|
],
|
|
35
35
|
"flags": [
|
|
36
36
|
["-w <wordlist>", "Wordlist file path"],
|
|
@@ -46,100 +46,178 @@ HELP = {
|
|
|
46
46
|
{
|
|
47
47
|
"name": "Directory Fuzzing",
|
|
48
48
|
"args": ["-w", "data/wordlists/web_dirs_common.txt"],
|
|
49
|
-
"desc": "Basic directory discovery"
|
|
49
|
+
"desc": "Basic directory discovery",
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"name": "File Fuzzing (PHP)",
|
|
53
|
-
"args": [
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
"args": [
|
|
54
|
+
"-w",
|
|
55
|
+
"data/wordlists/web_files_common.txt",
|
|
56
|
+
"-e",
|
|
57
|
+
".php,.phps,.php3,.php4,.php5",
|
|
58
|
+
],
|
|
59
|
+
"desc": "Fuzz for PHP files",
|
|
60
|
+
},
|
|
56
61
|
],
|
|
57
62
|
"parameter_fuzzing": [
|
|
58
63
|
{
|
|
59
64
|
"name": "GET Parameters",
|
|
60
65
|
"args": ["-w", "data/wordlists/web_files_common.txt"],
|
|
61
|
-
"desc": "Discover GET parameters (add ?FUZZ=test to URL)"
|
|
66
|
+
"desc": "Discover GET parameters (add ?FUZZ=test to URL)",
|
|
62
67
|
},
|
|
63
68
|
{
|
|
64
69
|
"name": "POST Parameters",
|
|
65
|
-
"args": [
|
|
66
|
-
|
|
70
|
+
"args": [
|
|
71
|
+
"-w",
|
|
72
|
+
"data/wordlists/web_files_common.txt",
|
|
73
|
+
"-X",
|
|
74
|
+
"POST",
|
|
75
|
+
"-d",
|
|
76
|
+
"FUZZ=test",
|
|
77
|
+
],
|
|
78
|
+
"desc": "Discover POST parameters",
|
|
67
79
|
},
|
|
68
80
|
{
|
|
69
81
|
"name": "Header Fuzzing",
|
|
70
|
-
"args": [
|
|
71
|
-
|
|
82
|
+
"args": [
|
|
83
|
+
"-w",
|
|
84
|
+
"data/wordlists/web_files_common.txt",
|
|
85
|
+
"-H",
|
|
86
|
+
"FUZZ: test",
|
|
87
|
+
],
|
|
88
|
+
"desc": "Find header-based vulnerabilities",
|
|
72
89
|
},
|
|
73
90
|
{
|
|
74
91
|
"name": "Value Fuzzing",
|
|
75
92
|
"args": ["-w", "data/wordlists/web_files_common.txt"],
|
|
76
|
-
"desc": "Test parameter values (use ?param=FUZZ)"
|
|
77
|
-
}
|
|
93
|
+
"desc": "Test parameter values (use ?param=FUZZ)",
|
|
94
|
+
},
|
|
78
95
|
],
|
|
79
96
|
"vhost_fuzzing": [
|
|
80
97
|
{
|
|
81
98
|
"name": "Virtual Hosts",
|
|
82
|
-
"args": [
|
|
83
|
-
|
|
99
|
+
"args": [
|
|
100
|
+
"-w",
|
|
101
|
+
"data/wordlists/subdomains_common.txt",
|
|
102
|
+
"-H",
|
|
103
|
+
"Host: FUZZ.target.com",
|
|
104
|
+
],
|
|
105
|
+
"desc": "Discover virtual hosts",
|
|
84
106
|
}
|
|
85
|
-
]
|
|
107
|
+
],
|
|
86
108
|
},
|
|
87
109
|
"presets": [
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
110
|
+
{
|
|
111
|
+
"name": "Directory Fuzzing",
|
|
112
|
+
"args": ["-w", "data/wordlists/web_dirs_common.txt"],
|
|
113
|
+
"desc": "Basic directory discovery",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "File Fuzzing (PHP)",
|
|
117
|
+
"args": [
|
|
118
|
+
"-w",
|
|
119
|
+
"data/wordlists/web_files_common.txt",
|
|
120
|
+
"-e",
|
|
121
|
+
".php,.phps,.php3,.php4,.php5",
|
|
122
|
+
],
|
|
123
|
+
"desc": "Fuzz for PHP files",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "GET Parameters",
|
|
127
|
+
"args": ["-w", "data/wordlists/web_files_common.txt"],
|
|
128
|
+
"desc": "Discover GET parameters (add ?FUZZ=test to URL)",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "POST Parameters",
|
|
132
|
+
"args": [
|
|
133
|
+
"-w",
|
|
134
|
+
"data/wordlists/web_files_common.txt",
|
|
135
|
+
"-X",
|
|
136
|
+
"POST",
|
|
137
|
+
"-d",
|
|
138
|
+
"FUZZ=test",
|
|
139
|
+
],
|
|
140
|
+
"desc": "Discover POST parameters",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "Header Fuzzing",
|
|
144
|
+
"args": ["-w", "data/wordlists/web_files_common.txt", "-H", "FUZZ: test"],
|
|
145
|
+
"desc": "Find header-based vulnerabilities",
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "Value Fuzzing",
|
|
149
|
+
"args": ["-w", "data/wordlists/web_files_common.txt"],
|
|
150
|
+
"desc": "Test parameter values (use ?param=FUZZ)",
|
|
151
|
+
},
|
|
94
152
|
],
|
|
95
153
|
"help_sections": [
|
|
96
154
|
{
|
|
97
155
|
"title": "What is ffuf?",
|
|
98
156
|
"color": "cyan",
|
|
99
157
|
"content": [
|
|
100
|
-
{
|
|
101
|
-
|
|
102
|
-
"Fuzz
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
|
|
108
|
-
|
|
158
|
+
{
|
|
159
|
+
"title": "Overview",
|
|
160
|
+
"desc": "ffuf (Fuzz Faster U Fool) is a modern, fast web fuzzer that can fuzz any part of an HTTP request - URLs, headers, POST data, and more.",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"title": "Use Cases",
|
|
164
|
+
"desc": "Advanced web fuzzing beyond simple directory scans",
|
|
165
|
+
"tips": [
|
|
166
|
+
"Fuzz for hidden files with specific extensions",
|
|
167
|
+
"Discover GET/POST parameters",
|
|
168
|
+
"Find virtual hosts",
|
|
169
|
+
"Test for IDOR vulnerabilities",
|
|
170
|
+
"Fuzz headers and cookies",
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
],
|
|
109
174
|
},
|
|
110
175
|
{
|
|
111
176
|
"title": "How to Use",
|
|
112
177
|
"color": "green",
|
|
113
178
|
"content": [
|
|
114
|
-
{
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
179
|
+
{
|
|
180
|
+
"title": "Basic Workflow",
|
|
181
|
+
"desc": "1. Use FUZZ keyword to mark position to fuzz\n 2. Apply filters (-fc, -fs, -fw) to reduce noise\n 3. Use -e flag to append extensions automatically\n 4. Review JSON output for results",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"title": "Key Features",
|
|
185
|
+
"desc": "Powerful fuzzing capabilities",
|
|
186
|
+
"tips": [
|
|
187
|
+
"Directory fuzzing: ffuf -u http://site/FUZZ -w wordlist.txt",
|
|
188
|
+
"Parameter fuzzing: ffuf -u http://site/?FUZZ=value -w params.txt",
|
|
189
|
+
"Extension fuzzing: ffuf -u http://site/FUZZ -w words.txt -e .php,.html",
|
|
190
|
+
"Filter results: -fc 404 (filter code), -fs 1234 (filter size)",
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
],
|
|
122
194
|
},
|
|
123
195
|
{
|
|
124
196
|
"title": "Tips & Best Practices",
|
|
125
197
|
"color": "yellow",
|
|
126
198
|
"content": [
|
|
127
|
-
(
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
199
|
+
(
|
|
200
|
+
"Best Practices:",
|
|
201
|
+
[
|
|
202
|
+
"Use filters early to reduce noise (-fc 404,403)",
|
|
203
|
+
"Start with common wordlists, expand as needed",
|
|
204
|
+
"Match response codes carefully (-mc 200,204,301,302)",
|
|
205
|
+
"Save JSON output for parsing and analysis",
|
|
206
|
+
"Use -t to control threads (default 40)",
|
|
207
|
+
],
|
|
208
|
+
),
|
|
209
|
+
(
|
|
210
|
+
"Common Issues:",
|
|
211
|
+
[
|
|
212
|
+
"Too many results: Add -fc or -fs filters",
|
|
213
|
+
"Missing FUZZ keyword: Add FUZZ to URL or headers",
|
|
214
|
+
"Rate limiting: Reduce -t threads or add delays",
|
|
215
|
+
"No matches: Check filters aren't too restrictive",
|
|
216
|
+
],
|
|
217
|
+
),
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
],
|
|
143
221
|
}
|
|
144
222
|
|
|
145
223
|
|
|
@@ -149,74 +227,74 @@ class FfufPlugin(PluginBase):
|
|
|
149
227
|
category = "scanning"
|
|
150
228
|
HELP = HELP
|
|
151
229
|
|
|
152
|
-
|
|
153
|
-
|
|
230
|
+
def build_command(
|
|
231
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
232
|
+
):
|
|
154
233
|
"""Build command for background execution with PID tracking."""
|
|
155
234
|
if not target:
|
|
156
235
|
if log_path:
|
|
157
|
-
with open(log_path,
|
|
236
|
+
with open(log_path, "w") as f:
|
|
158
237
|
f.write("ERROR: Target URL is required\n")
|
|
159
238
|
return None
|
|
160
|
-
|
|
239
|
+
|
|
161
240
|
# Add FUZZ placeholder if not present
|
|
162
|
-
if
|
|
163
|
-
target = target.rstrip(
|
|
164
|
-
|
|
241
|
+
if "FUZZ" not in target:
|
|
242
|
+
target = target.rstrip("/") + "/FUZZ"
|
|
243
|
+
|
|
165
244
|
# Validate URL (skip if FUZZ is present)
|
|
166
|
-
if
|
|
245
|
+
if "FUZZ" not in target:
|
|
167
246
|
try:
|
|
168
247
|
target = validate_url(target)
|
|
169
248
|
except ValidationError as e:
|
|
170
249
|
if log_path:
|
|
171
|
-
with open(log_path,
|
|
250
|
+
with open(log_path, "w") as f:
|
|
172
251
|
f.write(f"ERROR: Invalid URL: {e}\n")
|
|
173
252
|
return None
|
|
174
|
-
|
|
253
|
+
|
|
175
254
|
args = args or []
|
|
176
|
-
|
|
255
|
+
|
|
177
256
|
# Replace <target> placeholder
|
|
178
257
|
args = [arg.replace("<target>", target) for arg in args]
|
|
179
|
-
|
|
258
|
+
|
|
180
259
|
# ffuf uses -u flag for URL
|
|
181
260
|
cmd = ["ffuf", "-u", target]
|
|
182
|
-
|
|
261
|
+
|
|
183
262
|
# Force JSON output
|
|
184
263
|
if log_path and "-o" not in args:
|
|
185
264
|
cmd.extend(["-o", log_path, "-of", "json"])
|
|
186
|
-
|
|
265
|
+
|
|
187
266
|
# Add user args
|
|
188
267
|
cmd.extend(args)
|
|
189
|
-
|
|
268
|
+
|
|
190
269
|
# Set defaults if not in args
|
|
191
270
|
if "-mc" not in args and "-fc" not in args:
|
|
192
271
|
cmd.extend(["-mc", "200,204,301,302,307,401,403"])
|
|
193
|
-
|
|
272
|
+
|
|
194
273
|
if "-t" not in args:
|
|
195
274
|
cmd.extend(["-t", "40"])
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
'cmd': cmd,
|
|
199
|
-
'timeout': 1800
|
|
200
|
-
}
|
|
201
275
|
|
|
202
|
-
|
|
276
|
+
return {"cmd": cmd, "timeout": 1800}
|
|
277
|
+
|
|
278
|
+
def run(
|
|
279
|
+
self, target: str, args: List[str] = None, label: str = "", log_path: str = None
|
|
280
|
+
) -> int:
|
|
203
281
|
"""Execute ffuf and write JSON output to log_path."""
|
|
204
282
|
|
|
205
283
|
# Validate URL
|
|
206
|
-
if not target.startswith((
|
|
284
|
+
if not target.startswith(("http://", "https://")):
|
|
207
285
|
target = f"http://{target}"
|
|
208
286
|
|
|
209
287
|
# ffuf needs FUZZ keyword in URL
|
|
210
|
-
if
|
|
211
|
-
target = target.rstrip(
|
|
288
|
+
if "FUZZ" not in target:
|
|
289
|
+
target = target.rstrip("/") + "/FUZZ"
|
|
212
290
|
|
|
213
291
|
try:
|
|
214
292
|
# Don't validate if FUZZ is in URL (it's not a real URL)
|
|
215
|
-
if
|
|
293
|
+
if "FUZZ" not in target:
|
|
216
294
|
target = validate_url(target)
|
|
217
295
|
except ValidationError as e:
|
|
218
296
|
if log_path:
|
|
219
|
-
with open(log_path,
|
|
297
|
+
with open(log_path, "w") as f:
|
|
220
298
|
f.write(f"ERROR: Invalid URL: {e}\n")
|
|
221
299
|
return 1
|
|
222
300
|
raise ValueError(f"Invalid URL: {e}")
|
|
@@ -245,7 +323,9 @@ class FfufPlugin(PluginBase):
|
|
|
245
323
|
|
|
246
324
|
if not log_path:
|
|
247
325
|
try:
|
|
248
|
-
proc = subprocess.run(
|
|
326
|
+
proc = subprocess.run(
|
|
327
|
+
cmd, capture_output=True, timeout=600, check=False
|
|
328
|
+
)
|
|
249
329
|
return proc.returncode
|
|
250
330
|
except Exception:
|
|
251
331
|
return 1
|
|
@@ -253,11 +333,7 @@ class FfufPlugin(PluginBase):
|
|
|
253
333
|
try:
|
|
254
334
|
# ffuf writes JSON directly to output file
|
|
255
335
|
proc = subprocess.run(
|
|
256
|
-
cmd,
|
|
257
|
-
capture_output=True,
|
|
258
|
-
timeout=600,
|
|
259
|
-
check=False,
|
|
260
|
-
text=True
|
|
336
|
+
cmd, capture_output=True, timeout=600, check=False, text=True
|
|
261
337
|
)
|
|
262
338
|
|
|
263
339
|
# If there was an error, write it to log
|