souleyez 3.0.0__py3-none-any.whl → 3.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of souleyez might be problematic. Click here for more details.
- souleyez/__init__.py +1 -1
- souleyez/ai/__init__.py +7 -7
- souleyez/ai/action_mapper.py +3 -2
- souleyez/ai/chain_advisor.py +2 -1
- souleyez/ai/claude_provider.py +2 -2
- souleyez/ai/context_builder.py +4 -2
- souleyez/ai/executor.py +9 -6
- souleyez/ai/feedback_handler.py +4 -2
- souleyez/ai/llm_provider.py +2 -2
- souleyez/ai/ollama_provider.py +2 -2
- souleyez/ai/ollama_service.py +10 -26
- souleyez/ai/path_scorer.py +2 -1
- souleyez/ai/recommender.py +6 -4
- souleyez/ai/report_context.py +2 -2
- souleyez/ai/report_service.py +5 -5
- souleyez/ai/result_parser.py +3 -2
- souleyez/ai/safety.py +5 -2
- souleyez/auth/__init__.py +6 -6
- souleyez/auth/audit.py +2 -2
- souleyez/auth/engagement_access.py +5 -7
- souleyez/auth/permissions.py +1 -1
- souleyez/auth/session_manager.py +5 -5
- souleyez/auth/user_manager.py +4 -5
- souleyez/commands/audit.py +6 -5
- souleyez/commands/auth.py +6 -5
- souleyez/commands/deliverables.py +2 -3
- souleyez/commands/engagement.py +3 -3
- souleyez/commands/license.py +3 -2
- souleyez/commands/screenshots.py +5 -4
- souleyez/commands/user.py +10 -8
- souleyez/config.py +4 -2
- souleyez/core/credential_tester.py +4 -2
- souleyez/core/cve_mappings.py +2 -1
- souleyez/core/cve_matcher.py +2 -1
- souleyez/core/msf_auto_mapper.py +2 -0
- souleyez/core/msf_chain_engine.py +3 -1
- souleyez/core/msf_database.py +7 -13
- souleyez/core/msf_integration.py +2 -2
- souleyez/core/msf_rpc_client.py +3 -2
- souleyez/core/msf_rpc_manager.py +4 -4
- souleyez/core/msf_sync_manager.py +7 -7
- souleyez/core/network_utils.py +1 -1
- souleyez/core/parser_handler.py +2 -1
- souleyez/core/pending_chains.py +4 -3
- souleyez/core/templates.py +5 -2
- souleyez/core/tool_chaining.py +101 -70
- souleyez/core/version_utils.py +1 -0
- souleyez/core/vuln_correlation.py +3 -2
- souleyez/core/web_utils.py +2 -1
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +1 -1
- souleyez/detection/mitre_mappings.py +1 -2
- souleyez/detection/validator.py +5 -4
- souleyez/devtools.py +4 -2
- souleyez/docs/README.md +2 -2
- souleyez/engine/background.py +168 -7
- souleyez/engine/base.py +2 -1
- souleyez/engine/loader.py +4 -2
- souleyez/engine/log_sanitizer.py +1 -0
- souleyez/engine/manager.py +3 -1
- souleyez/engine/result_handler.py +50 -67
- souleyez/engine/worker_manager.py +6 -4
- souleyez/export/evidence_bundle.py +1 -0
- souleyez/handlers/base.py +1 -0
- souleyez/handlers/bash_handler.py +1 -0
- souleyez/handlers/bloodhound_handler.py +1 -0
- souleyez/handlers/certipy_handler.py +1 -0
- souleyez/handlers/crackmapexec_handler.py +2 -20
- souleyez/handlers/dnsrecon_handler.py +2 -1
- souleyez/handlers/enum4linux_handler.py +65 -37
- souleyez/handlers/evil_winrm_handler.py +1 -0
- souleyez/handlers/ffuf_handler.py +3 -1
- souleyez/handlers/gobuster_handler.py +7 -6
- souleyez/handlers/gpp_extract_handler.py +1 -0
- souleyez/handlers/hashcat_handler.py +1 -0
- souleyez/handlers/hydra_handler.py +5 -2
- souleyez/handlers/impacket_getuserspns_handler.py +1 -0
- souleyez/handlers/impacket_psexec_handler.py +1 -0
- souleyez/handlers/impacket_secretsdump_handler.py +1 -0
- souleyez/handlers/john_handler.py +1 -0
- souleyez/handlers/katana_handler.py +39 -2
- souleyez/handlers/kerbrute_handler.py +1 -0
- souleyez/handlers/ldapsearch_handler.py +90 -17
- souleyez/handlers/lfi_extract_handler.py +1 -0
- souleyez/handlers/msf_auxiliary_handler.py +1 -0
- souleyez/handlers/msf_exploit_handler.py +1 -0
- souleyez/handlers/nikto_handler.py +2 -1
- souleyez/handlers/nmap_handler.py +2 -1
- souleyez/handlers/nuclei_handler.py +2 -1
- souleyez/handlers/nxc_handler.py +3 -18
- souleyez/handlers/rdp_sec_check_handler.py +1 -0
- souleyez/handlers/registry.py +1 -0
- souleyez/handlers/responder_handler.py +1 -0
- souleyez/handlers/service_explorer_handler.py +2 -1
- souleyez/handlers/smbclient_handler.py +1 -0
- souleyez/handlers/smbmap_handler.py +3 -2
- souleyez/handlers/sqlmap_handler.py +6 -4
- souleyez/handlers/theharvester_handler.py +2 -1
- souleyez/handlers/web_login_test_handler.py +1 -0
- souleyez/handlers/whois_handler.py +3 -2
- souleyez/handlers/wpscan_handler.py +2 -1
- souleyez/history.py +4 -3
- souleyez/importers/msf_importer.py +5 -3
- souleyez/importers/smart_importer.py +6 -4
- souleyez/integrations/siem/__init__.py +6 -6
- souleyez/integrations/siem/base.py +1 -1
- souleyez/integrations/siem/elastic.py +3 -3
- souleyez/integrations/siem/factory.py +1 -2
- souleyez/integrations/siem/googlesecops.py +4 -4
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +1 -1
- souleyez/integrations/siem/sentinel.py +3 -3
- souleyez/integrations/siem/splunk.py +3 -3
- souleyez/integrations/siem/wazuh.py +4 -4
- souleyez/integrations/wazuh/__init__.py +1 -1
- souleyez/integrations/wazuh/client.py +3 -2
- souleyez/integrations/wazuh/config.py +3 -2
- souleyez/integrations/wazuh/host_mapper.py +3 -1
- souleyez/integrations/wazuh/sync.py +4 -1
- souleyez/intelligence/__init__.py +1 -1
- souleyez/intelligence/correlation_analyzer.py +6 -5
- souleyez/intelligence/exploit_knowledge.py +4 -4
- souleyez/intelligence/exploit_suggestions.py +4 -3
- souleyez/intelligence/gap_analyzer.py +5 -3
- souleyez/intelligence/gap_detector.py +2 -0
- souleyez/intelligence/sensitive_tables.py +1 -1
- souleyez/intelligence/service_parser.py +1 -0
- souleyez/intelligence/surface_analyzer.py +9 -9
- souleyez/intelligence/target_parser.py +1 -0
- souleyez/licensing/__init__.py +3 -3
- souleyez/main.py +25 -18
- souleyez/migrations/fix_job_counter.py +2 -1
- souleyez/parsers/bloodhound_parser.py +1 -0
- souleyez/parsers/crackmapexec_parser.py +2 -1
- souleyez/parsers/dalfox_parser.py +3 -2
- souleyez/parsers/dnsrecon_parser.py +2 -1
- souleyez/parsers/enum4linux_parser.py +2 -1
- souleyez/parsers/ffuf_parser.py +2 -1
- souleyez/parsers/gobuster_parser.py +2 -1
- souleyez/parsers/hashcat_parser.py +3 -2
- souleyez/parsers/http_fingerprint_parser.py +2 -1
- souleyez/parsers/hydra_parser.py +2 -1
- souleyez/parsers/impacket_parser.py +2 -1
- souleyez/parsers/john_parser.py +4 -3
- souleyez/parsers/katana_parser.py +134 -2
- souleyez/parsers/msf_parser.py +2 -1
- souleyez/parsers/nikto_parser.py +2 -1
- souleyez/parsers/nmap_parser.py +14 -3
- souleyez/parsers/nuclei_parser.py +3 -2
- souleyez/parsers/responder_parser.py +1 -0
- souleyez/parsers/searchsploit_parser.py +3 -2
- souleyez/parsers/service_explorer_parser.py +1 -0
- souleyez/parsers/smbmap_parser.py +2 -1
- souleyez/parsers/sqlmap_parser.py +36 -2
- souleyez/parsers/theharvester_parser.py +2 -1
- souleyez/parsers/whois_parser.py +2 -1
- souleyez/parsers/wpscan_parser.py +3 -2
- souleyez/plugins/afp.py +3 -1
- souleyez/plugins/afp_brute.py +3 -1
- souleyez/plugins/ard.py +3 -1
- souleyez/plugins/bloodhound.py +3 -2
- souleyez/plugins/certipy.py +1 -0
- souleyez/plugins/crackmapexec.py +11 -7
- souleyez/plugins/dalfox.py +5 -2
- souleyez/plugins/dns_hijack.py +3 -1
- souleyez/plugins/dnsrecon.py +3 -1
- souleyez/plugins/enum4linux.py +3 -1
- souleyez/plugins/evil_winrm.py +1 -0
- souleyez/plugins/ffuf.py +3 -1
- souleyez/plugins/firmware_extract.py +3 -2
- souleyez/plugins/gobuster.py +6 -3
- souleyez/plugins/gpp_extract.py +1 -0
- souleyez/plugins/hashcat.py +2 -1
- souleyez/plugins/http_fingerprint.py +57 -7
- souleyez/plugins/hydra.py +5 -3
- souleyez/plugins/impacket_common.py +40 -0
- souleyez/plugins/impacket_getnpusers.py +19 -2
- souleyez/plugins/impacket_getuserspns.py +158 -0
- souleyez/plugins/impacket_psexec.py +19 -2
- souleyez/plugins/impacket_secretsdump.py +19 -2
- souleyez/plugins/impacket_smbclient.py +19 -2
- souleyez/plugins/john.py +2 -1
- souleyez/plugins/katana.py +48 -6
- souleyez/plugins/kerbrute.py +1 -0
- souleyez/plugins/lfi_extract.py +1 -0
- souleyez/plugins/macos_ssh.py +3 -1
- souleyez/plugins/mdns.py +3 -1
- souleyez/plugins/msf_auxiliary.py +3 -2
- souleyez/plugins/msf_exploit.py +6 -5
- souleyez/plugins/nikto.py +5 -2
- souleyez/plugins/nmap.py +6 -4
- souleyez/plugins/nuclei.py +3 -1
- souleyez/plugins/nxc.py +1 -0
- souleyez/plugins/plugin_base.py +3 -2
- souleyez/plugins/plugin_template.py +3 -2
- souleyez/plugins/rdp_sec_check.py +1 -0
- souleyez/plugins/responder.py +2 -1
- souleyez/plugins/router_http_brute.py +3 -1
- souleyez/plugins/router_ssh_brute.py +3 -1
- souleyez/plugins/router_telnet_brute.py +3 -1
- souleyez/plugins/routersploit.py +5 -3
- souleyez/plugins/routersploit_exploit.py +5 -3
- souleyez/plugins/searchsploit.py +1 -0
- souleyez/plugins/service_explorer.py +2 -1
- souleyez/plugins/smbmap.py +3 -1
- souleyez/plugins/smbpasswd.py +1 -0
- souleyez/plugins/sqlmap.py +3 -1
- souleyez/plugins/theharvester.py +3 -1
- souleyez/plugins/tr069.py +3 -1
- souleyez/plugins/upnp.py +3 -1
- souleyez/plugins/upnp_abuse.py +4 -2
- souleyez/plugins/vnc_access.py +4 -2
- souleyez/plugins/vnc_brute.py +3 -1
- souleyez/plugins/web_login_test.py +1 -0
- souleyez/plugins/whois.py +3 -1
- souleyez/plugins/wpscan.py +3 -1
- souleyez/reporting/attack_chain.py +2 -1
- souleyez/reporting/charts.py +1 -0
- souleyez/reporting/compliance_mappings.py +1 -0
- souleyez/reporting/detection_report.py +10 -10
- souleyez/reporting/formatters.py +7 -12
- souleyez/reporting/generator.py +34 -46
- souleyez/reporting/metrics.py +2 -1
- souleyez/scanner.py +6 -3
- souleyez/security/__init__.py +7 -5
- souleyez/security/scope_validator.py +5 -4
- souleyez/security.py +5 -2
- souleyez/storage/credentials.py +14 -19
- souleyez/storage/crypto.py +7 -4
- souleyez/storage/database.py +6 -6
- souleyez/storage/db.py +8 -8
- souleyez/storage/deliverable_evidence.py +2 -1
- souleyez/storage/deliverable_exporter.py +3 -2
- souleyez/storage/deliverable_templates.py +2 -1
- souleyez/storage/deliverables.py +2 -1
- souleyez/storage/engagements.py +6 -4
- souleyez/storage/evidence.py +5 -4
- souleyez/storage/execution_log.py +4 -2
- souleyez/storage/exploit_attempts.py +3 -2
- souleyez/storage/exploits.py +3 -1
- souleyez/storage/findings.py +3 -1
- souleyez/storage/hosts.py +5 -2
- souleyez/storage/migrate_to_engagements.py +14 -24
- souleyez/storage/migrations/_001_add_credential_enhancements.py +12 -21
- souleyez/storage/migrations/_003_add_execution_log.py +8 -13
- souleyez/storage/migrations/_005_screenshots.py +2 -4
- souleyez/storage/migrations/_006_deliverables.py +2 -4
- souleyez/storage/migrations/_007_deliverable_templates.py +4 -8
- souleyez/storage/migrations/_008_add_nuclei_table.py +2 -4
- souleyez/storage/migrations/_010_evidence_linking.py +6 -12
- souleyez/storage/migrations/_012_team_collaboration.py +12 -24
- souleyez/storage/migrations/_013_add_host_tags.py +2 -4
- souleyez/storage/migrations/_014_exploit_attempts.py +10 -20
- souleyez/storage/migrations/_015_add_mac_os_fields.py +4 -8
- souleyez/storage/migrations/_016_add_domain_field.py +2 -4
- souleyez/storage/migrations/_017_msf_sessions.py +8 -16
- souleyez/storage/migrations/_018_add_osint_target.py +4 -8
- souleyez/storage/migrations/_019_add_engagement_type.py +4 -8
- souleyez/storage/migrations/_020_add_rbac.py +9 -17
- souleyez/storage/migrations/_021_wazuh_integration.py +4 -8
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +2 -4
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +4 -8
- souleyez/storage/migrations/_026_add_engagement_scope.py +4 -8
- souleyez/storage/migrations/_027_multi_siem_persistence.py +8 -16
- souleyez/storage/migrations/__init__.py +1 -4
- souleyez/storage/migrations/migration_manager.py +6 -9
- souleyez/storage/msf_sessions.py +1 -1
- souleyez/storage/osint.py +3 -1
- souleyez/storage/recommendation_engine.py +3 -2
- souleyez/storage/screenshots.py +2 -1
- souleyez/storage/smb_shares.py +3 -1
- souleyez/storage/sqlmap_data.py +6 -4
- souleyez/storage/team_collaboration.py +3 -2
- souleyez/storage/timeline_tracker.py +2 -1
- souleyez/storage/wazuh_vulns.py +3 -1
- souleyez/storage/web_paths.py +3 -1
- souleyez/testing/credential_tester.py +2 -0
- souleyez/ui/__init__.py +2 -1
- souleyez/ui/ai_quotes.py +1 -1
- souleyez/ui/attack_surface.py +50 -28
- souleyez/ui/chain_rules_view.py +6 -3
- souleyez/ui/correlation_view.py +3 -2
- souleyez/ui/dashboard.py +85 -139
- souleyez/ui/deliverables_view.py +1 -1
- souleyez/ui/design_system.py +5 -3
- souleyez/ui/errors.py +3 -1
- souleyez/ui/evidence_linking_view.py +2 -1
- souleyez/ui/evidence_vault.py +11 -6
- souleyez/ui/exploit_suggestions_view.py +11 -7
- souleyez/ui/export_view.py +3 -1
- souleyez/ui/gap_analysis_view.py +6 -3
- souleyez/ui/help_system.py +4 -1
- souleyez/ui/intelligence_view.py +7 -3
- souleyez/ui/interactive.py +1280 -558
- souleyez/ui/interactive_selector.py +3 -2
- souleyez/ui/log_formatter.py +1 -0
- souleyez/ui/menu_components.py +3 -1
- souleyez/ui/msf_auxiliary_menu.py +4 -1
- souleyez/ui/pending_chains_view.py +15 -12
- souleyez/ui/progress_indicators.py +5 -2
- souleyez/ui/recommendations_view.py +4 -2
- souleyez/ui/rule_builder.py +4 -1
- souleyez/ui/setup_wizard.py +10 -8
- souleyez/ui/shortcuts.py +1 -1
- souleyez/ui/splunk_gap_analysis_view.py +7 -4
- souleyez/ui/splunk_vulns_view.py +4 -1
- souleyez/ui/team_dashboard.py +7 -5
- souleyez/ui/template_selector.py +2 -1
- souleyez/ui/terminal.py +3 -2
- souleyez/ui/timeline_view.py +2 -1
- souleyez/ui/tool_setup.py +92 -31
- souleyez/ui/tutorial.py +7 -4
- souleyez/ui/tutorial_state.py +3 -2
- souleyez/ui/wazuh_vulns_view.py +5 -2
- souleyez/ui/wordlist_browser.py +4 -3
- souleyez/ui.py +13 -7
- souleyez/utils/tool_checker.py +95 -17
- souleyez/utils.py +4 -4
- souleyez/wordlists.py +1 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/METADATA +1 -1
- souleyez-3.0.9.dist-info/RECORD +445 -0
- souleyez-3.0.0.dist-info/RECORD +0 -443
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/WHEEL +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/entry_points.txt +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/licenses/LICENSE +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/top_level.txt +0 -0
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
Exploit suggestion engine.
|
|
4
4
|
Orchestrates version extraction, exploit matching, and ranking.
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
import re
|
|
7
8
|
import time
|
|
8
9
|
from typing import Dict, List, Optional
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
from souleyez.intelligence.exploit_knowledge import ExploitKnowledgeBase
|
|
12
|
+
from souleyez.intelligence.service_parser import ServiceVersionExtractor
|
|
11
13
|
from souleyez.storage import exploit_attempts
|
|
12
14
|
|
|
13
|
-
|
|
14
15
|
# Module-level cache shared across all instances
|
|
15
16
|
_SUGGESTION_CACHE = {}
|
|
16
17
|
_CACHE_TIMEOUT = 30
|
|
@@ -102,8 +103,8 @@ class ExploitSuggestionEngine:
|
|
|
102
103
|
return cached_result
|
|
103
104
|
|
|
104
105
|
# Cache miss or expired - do the analysis
|
|
105
|
-
from souleyez.storage.hosts import HostManager
|
|
106
106
|
from souleyez.storage.findings import FindingsManager
|
|
107
|
+
from souleyez.storage.hosts import HostManager
|
|
107
108
|
from souleyez.storage.wazuh_vulns import WazuhVulnsManager
|
|
108
109
|
|
|
109
110
|
hm = HostManager()
|
|
@@ -5,12 +5,14 @@ souleyez.intelligence.gap_analyzer - Gap analysis between Wazuh and scan finding
|
|
|
5
5
|
Compares vulnerabilities found by Wazuh (passive, agent-based) vs
|
|
6
6
|
SoulEyez scans (active, network-based) to identify detection gaps.
|
|
7
7
|
"""
|
|
8
|
-
|
|
9
|
-
from typing import List, Dict, Any, Optional
|
|
8
|
+
|
|
10
9
|
import re
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
from souleyez.log_config import get_logger
|
|
11
14
|
from souleyez.storage.database import get_db
|
|
12
15
|
from souleyez.storage.wazuh_vulns import WazuhVulnsManager
|
|
13
|
-
from souleyez.log_config import get_logger
|
|
14
16
|
|
|
15
17
|
logger = get_logger(__name__)
|
|
16
18
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Module for detecting sensitive tables during SQLMap enumeration.
|
|
4
4
|
"""
|
|
5
|
-
from typing import Dict, List, Tuple, Optional
|
|
6
5
|
|
|
6
|
+
from typing import Dict, List, Optional, Tuple
|
|
7
7
|
|
|
8
8
|
# System databases to NEVER dump (true system metadata only)
|
|
9
9
|
# NOTE: Only skip databases that are ALWAYS system/metadata databases
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Attack surface analysis and scoring.
|
|
4
4
|
Analyzes engagement data to identify high-value targets and exploitation gaps.
|
|
5
5
|
"""
|
|
6
|
-
from typing import List, Dict, Optional
|
|
7
|
-
import time
|
|
8
|
-
import math
|
|
9
6
|
|
|
7
|
+
import math
|
|
8
|
+
import time
|
|
9
|
+
from typing import Dict, List, Optional
|
|
10
10
|
|
|
11
11
|
# Module-level cache shared across all instances
|
|
12
12
|
_ANALYSIS_CACHE = {}
|
|
@@ -17,9 +17,9 @@ class AttackSurfaceAnalyzer:
|
|
|
17
17
|
"""Analyzes and scores attack surface for pentesting engagements."""
|
|
18
18
|
|
|
19
19
|
def __init__(self):
|
|
20
|
-
from souleyez.storage.hosts import HostManager
|
|
21
|
-
from souleyez.storage.findings import FindingsManager
|
|
22
20
|
from souleyez.storage.credentials import CredentialsManager
|
|
21
|
+
from souleyez.storage.findings import FindingsManager
|
|
22
|
+
from souleyez.storage.hosts import HostManager
|
|
23
23
|
from souleyez.storage.wazuh_vulns import WazuhVulnsManager
|
|
24
24
|
|
|
25
25
|
self.hosts_mgr = HostManager()
|
|
@@ -130,8 +130,8 @@ class AttackSurfaceAnalyzer:
|
|
|
130
130
|
f
|
|
131
131
|
for f in findings
|
|
132
132
|
if f.get("ip_address") == host_ip
|
|
133
|
-
or f.get("url"
|
|
134
|
-
or f.get("url"
|
|
133
|
+
or (f.get("url") or "").startswith(f"http://{host_ip}")
|
|
134
|
+
or (f.get("url") or "").startswith(f"https://{host_ip}")
|
|
135
135
|
]
|
|
136
136
|
critical_findings = [
|
|
137
137
|
f for f in host_findings if f.get("severity") == "critical"
|
|
@@ -200,11 +200,11 @@ class AttackSurfaceAnalyzer:
|
|
|
200
200
|
for f in host_findings
|
|
201
201
|
if f.get("port") == service["port"]
|
|
202
202
|
or (
|
|
203
|
-
f.get("path"
|
|
203
|
+
(f.get("path") or "").startswith("https://")
|
|
204
204
|
and service["port"] == 443
|
|
205
205
|
)
|
|
206
206
|
or (
|
|
207
|
-
f.get("path"
|
|
207
|
+
(f.get("path") or "").startswith("http://")
|
|
208
208
|
and service["port"] == 80
|
|
209
209
|
)
|
|
210
210
|
]
|
souleyez/licensing/__init__.py
CHANGED
|
@@ -6,12 +6,12 @@ License keys are signed JSON payloads that can be validated without internet.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from souleyez.licensing.validator import (
|
|
9
|
-
LicenseValidator,
|
|
10
9
|
LicenseInfo,
|
|
11
|
-
|
|
10
|
+
LicenseValidator,
|
|
12
11
|
activate_license,
|
|
13
|
-
get_active_license,
|
|
14
12
|
deactivate_license,
|
|
13
|
+
get_active_license,
|
|
14
|
+
validate_license,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
__all__ = [
|
souleyez/main.py
CHANGED
|
@@ -2,30 +2,33 @@
|
|
|
2
2
|
"""
|
|
3
3
|
souleyez.main - CLI entry point
|
|
4
4
|
"""
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
import datetime
|
|
7
|
+
import getpass
|
|
7
8
|
import os
|
|
8
9
|
import shutil
|
|
9
10
|
import sys
|
|
10
|
-
import getpass
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
from souleyez.security import require_password, unlock_credentials_if_needed
|
|
12
|
+
|
|
13
|
+
import click
|
|
15
14
|
from rich.console import Console
|
|
16
15
|
from rich.table import Table
|
|
17
16
|
|
|
17
|
+
from souleyez.security import require_password, unlock_credentials_if_needed
|
|
18
|
+
from souleyez.storage.crypto import get_crypto_manager
|
|
19
|
+
from souleyez.ui.design_system import DesignSystem
|
|
20
|
+
|
|
18
21
|
try:
|
|
19
22
|
from souleyez.engine.background import (
|
|
20
23
|
enqueue_job,
|
|
21
|
-
list_jobs,
|
|
22
24
|
get_job,
|
|
25
|
+
list_jobs,
|
|
23
26
|
start_worker,
|
|
24
27
|
worker_loop,
|
|
25
28
|
)
|
|
26
29
|
from souleyez.storage.engagements import EngagementManager
|
|
27
|
-
from souleyez.ui.interactive import run_interactive_menu
|
|
28
30
|
from souleyez.ui.dashboard import run_dashboard
|
|
31
|
+
from souleyez.ui.interactive import run_interactive_menu
|
|
29
32
|
except ImportError as e:
|
|
30
33
|
click.echo(f"Import error: {e}", err=True)
|
|
31
34
|
sys.exit(1)
|
|
@@ -185,7 +188,7 @@ def _check_privileged_tools():
|
|
|
185
188
|
|
|
186
189
|
|
|
187
190
|
@click.group()
|
|
188
|
-
@click.version_option(version="3.0.
|
|
191
|
+
@click.version_option(version="3.0.9")
|
|
189
192
|
def cli():
|
|
190
193
|
"""SoulEyez - AI-Powered Pentesting Platform by CyberSoul Security"""
|
|
191
194
|
from souleyez.log_config import init_logging
|
|
@@ -1446,8 +1449,8 @@ def db():
|
|
|
1446
1449
|
@db.command("migrate")
|
|
1447
1450
|
def db_migrate():
|
|
1448
1451
|
"""Apply pending database migrations."""
|
|
1449
|
-
from souleyez.storage.migrations.migration_manager import MigrationManager
|
|
1450
1452
|
from souleyez.storage.database import get_db
|
|
1453
|
+
from souleyez.storage.migrations.migration_manager import MigrationManager
|
|
1451
1454
|
|
|
1452
1455
|
click.echo()
|
|
1453
1456
|
click.echo(click.style("🔄 DATABASE MIGRATION", bold=True, fg="cyan"))
|
|
@@ -1467,8 +1470,8 @@ def db_migrate():
|
|
|
1467
1470
|
@db.command("status")
|
|
1468
1471
|
def db_status():
|
|
1469
1472
|
"""Show database migration status."""
|
|
1470
|
-
from souleyez.storage.migrations.migration_manager import MigrationManager
|
|
1471
1473
|
from souleyez.storage.database import get_db
|
|
1474
|
+
from souleyez.storage.migrations.migration_manager import MigrationManager
|
|
1472
1475
|
|
|
1473
1476
|
# Get database path
|
|
1474
1477
|
db_instance = get_db()
|
|
@@ -1483,6 +1486,7 @@ def db_status():
|
|
|
1483
1486
|
def db_encrypt():
|
|
1484
1487
|
"""Encrypt all plaintext credentials in the database."""
|
|
1485
1488
|
import getpass
|
|
1489
|
+
|
|
1486
1490
|
from souleyez.storage.credentials import CredentialsManager
|
|
1487
1491
|
from souleyez.storage.crypto import get_crypto_manager
|
|
1488
1492
|
|
|
@@ -1786,7 +1790,7 @@ def _run_doctor(fix=False, verbose=False):
|
|
|
1786
1790
|
# Check dashboard cache status
|
|
1787
1791
|
if verbose:
|
|
1788
1792
|
try:
|
|
1789
|
-
from souleyez.ui.dashboard import
|
|
1793
|
+
from souleyez.ui.dashboard import _HEADER_CACHE_TTL, _header_cache
|
|
1790
1794
|
|
|
1791
1795
|
cache_entries = len(_header_cache)
|
|
1792
1796
|
if cache_entries > 0:
|
|
@@ -1800,8 +1804,8 @@ def _run_doctor(fix=False, verbose=False):
|
|
|
1800
1804
|
|
|
1801
1805
|
try:
|
|
1802
1806
|
from souleyez.intelligence.exploit_suggestions import (
|
|
1803
|
-
_SUGGESTION_CACHE,
|
|
1804
1807
|
_CACHE_TIMEOUT,
|
|
1808
|
+
_SUGGESTION_CACHE,
|
|
1805
1809
|
)
|
|
1806
1810
|
|
|
1807
1811
|
cache_entries = len(_SUGGESTION_CACHE)
|
|
@@ -2061,9 +2065,9 @@ def main():
|
|
|
2061
2065
|
@click.confirmation_option(prompt="Are you sure you want to uninstall SoulEyez?")
|
|
2062
2066
|
def uninstall(purge_data):
|
|
2063
2067
|
"""Uninstall SoulEyez and optionally remove all user data."""
|
|
2064
|
-
import subprocess
|
|
2065
2068
|
import shutil
|
|
2066
2069
|
import signal
|
|
2070
|
+
import subprocess
|
|
2067
2071
|
|
|
2068
2072
|
click.echo(click.style("\n🗑️ Uninstalling SoulEyez...", fg="yellow", bold=True))
|
|
2069
2073
|
click.echo()
|
|
@@ -2904,8 +2908,8 @@ def paths():
|
|
|
2904
2908
|
@click.option("--host", "-h", default=None, help="Filter by host IP or hostname")
|
|
2905
2909
|
def paths_list(engagement, status, host):
|
|
2906
2910
|
"""List discovered web paths."""
|
|
2907
|
-
from souleyez.storage.web_paths import WebPathsManager
|
|
2908
2911
|
from souleyez.storage.hosts import HostManager
|
|
2912
|
+
from souleyez.storage.web_paths import WebPathsManager
|
|
2909
2913
|
|
|
2910
2914
|
em = EngagementManager()
|
|
2911
2915
|
|
|
@@ -3370,6 +3374,7 @@ def creds_cleanup(engagement, confirm, show_all):
|
|
|
3370
3374
|
souleyez creds cleanup -e 5 # Preview for engagement 5 only
|
|
3371
3375
|
"""
|
|
3372
3376
|
import re
|
|
3377
|
+
|
|
3373
3378
|
from souleyez.storage.credentials import CredentialsManager
|
|
3374
3379
|
from souleyez.storage.engagements import EngagementManager
|
|
3375
3380
|
|
|
@@ -3658,9 +3663,10 @@ def report_generate(format, type, output, engagement, ai):
|
|
|
3658
3663
|
- Creates prioritized remediation plan
|
|
3659
3664
|
- Requires Claude API key or local Ollama
|
|
3660
3665
|
"""
|
|
3666
|
+
import datetime
|
|
3667
|
+
|
|
3661
3668
|
from souleyez.reporting.generator import ReportGenerator
|
|
3662
3669
|
from souleyez.storage.engagements import EngagementManager
|
|
3663
|
-
import datetime
|
|
3664
3670
|
|
|
3665
3671
|
# Get engagement
|
|
3666
3672
|
em = EngagementManager()
|
|
@@ -4107,8 +4113,8 @@ def ai_recommend(engagement, steps):
|
|
|
4107
4113
|
)
|
|
4108
4114
|
def ai_paths(engagement, number):
|
|
4109
4115
|
"""Generate and rank multiple attack paths."""
|
|
4110
|
-
from souleyez.storage.engagements import EngagementManager
|
|
4111
4116
|
from souleyez.ai.recommender import AttackRecommender
|
|
4117
|
+
from souleyez.storage.engagements import EngagementManager
|
|
4112
4118
|
|
|
4113
4119
|
em = EngagementManager()
|
|
4114
4120
|
|
|
@@ -4413,7 +4419,7 @@ def config_set(key, value):
|
|
|
4413
4419
|
souleyez config set ai.ollama_model llama3.1:8b
|
|
4414
4420
|
souleyez config set settings.threads 20
|
|
4415
4421
|
"""
|
|
4416
|
-
from souleyez.config import read_config, write_config
|
|
4422
|
+
from souleyez.config import _set_nested, read_config, write_config
|
|
4417
4423
|
|
|
4418
4424
|
# Read current config
|
|
4419
4425
|
cfg = read_config()
|
|
@@ -4461,9 +4467,10 @@ def config_list():
|
|
|
4461
4467
|
"""
|
|
4462
4468
|
List all configuration values.
|
|
4463
4469
|
"""
|
|
4464
|
-
from souleyez.config import read_config
|
|
4465
4470
|
import json
|
|
4466
4471
|
|
|
4472
|
+
from souleyez.config import read_config
|
|
4473
|
+
|
|
4467
4474
|
cfg = read_config()
|
|
4468
4475
|
click.echo(json.dumps(cfg, indent=2))
|
|
4469
4476
|
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
"""
|
|
3
3
|
souleyez.parsers.crackmapexec_parser - Parse CrackMapExec (NetExec) output
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import re
|
|
6
|
-
from typing import
|
|
7
|
+
from typing import Any, Dict, List
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def parse_crackmapexec_output(content: str, target: str = "") -> Dict[str, Any]:
|
|
@@ -4,9 +4,10 @@ souleyez.parsers.dalfox_parser
|
|
|
4
4
|
|
|
5
5
|
Parses Dalfox XSS scanner output into structured data.
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
import json
|
|
9
|
-
|
|
9
|
+
import re
|
|
10
|
+
from typing import Any, Dict, List
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def parse_dalfox_output(output: str, target: str = "") -> Dict[str, Any]:
|
|
@@ -4,8 +4,9 @@ souleyez.parsers.dnsrecon_parser
|
|
|
4
4
|
|
|
5
5
|
Parses DNSRecon output into host records and OSINT data.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import re
|
|
8
|
-
from typing import Dict, List
|
|
9
|
+
from typing import Any, Dict, List
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_dnsrecon_output(output: str, target: str = "") -> Dict[str, Any]:
|
|
@@ -4,8 +4,9 @@ souleyez.parsers.enum4linux_parser
|
|
|
4
4
|
|
|
5
5
|
Parses enum4linux SMB enumeration output into structured data.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import re
|
|
8
|
-
from typing import
|
|
9
|
+
from typing import Any, Dict
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_enum4linux_output(output: str, target: str = "") -> Dict[str, Any]:
|
souleyez/parsers/ffuf_parser.py
CHANGED
|
@@ -4,8 +4,9 @@ souleyez.parsers.hashcat_parser
|
|
|
4
4
|
|
|
5
5
|
Parse hashcat output and extract cracked passwords.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import re
|
|
8
|
-
from typing import
|
|
9
|
+
from typing import Any, Dict, List
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_hashcat_output(output: str, hash_file: str = "") -> Dict[str, Any]:
|
|
@@ -275,8 +276,8 @@ def _get_potfile_cracked(
|
|
|
275
276
|
Returns:
|
|
276
277
|
List of cracked password dicts with username, hash, password
|
|
277
278
|
"""
|
|
278
|
-
import subprocess
|
|
279
279
|
import os
|
|
280
|
+
import subprocess
|
|
280
281
|
|
|
281
282
|
cracked = []
|
|
282
283
|
|
|
@@ -5,9 +5,10 @@ souleyez.parsers.http_fingerprint_parser
|
|
|
5
5
|
Parses HTTP fingerprint output to extract WAF, CDN, managed hosting,
|
|
6
6
|
and technology information.
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
import json
|
|
9
10
|
import re
|
|
10
|
-
from typing import
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def parse_http_fingerprint_output(output: str, target: str = "") -> Dict[str, Any]:
|
souleyez/parsers/hydra_parser.py
CHANGED
|
@@ -4,8 +4,9 @@ souleyez.parsers.hydra_parser
|
|
|
4
4
|
|
|
5
5
|
Parses Hydra brute-force attack output and extracts successful credentials.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import re
|
|
8
|
-
from typing import Dict, List,
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_hydra_output(output: str, target: str = "") -> Dict[str, Any]:
|
|
@@ -8,8 +8,9 @@ Handles parsing for:
|
|
|
8
8
|
- psexec (command execution)
|
|
9
9
|
- smbclient (file operations)
|
|
10
10
|
"""
|
|
11
|
+
|
|
11
12
|
import re
|
|
12
|
-
from typing import
|
|
13
|
+
from typing import Any, Dict, List
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def parse_secretsdump(log_path: str, target: str) -> Dict[str, Any]:
|
souleyez/parsers/john_parser.py
CHANGED
|
@@ -4,8 +4,9 @@ souleyez.parsers.john_parser
|
|
|
4
4
|
|
|
5
5
|
Parser for John the Ripper output.
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
import os
|
|
9
|
+
import re
|
|
9
10
|
from typing import Dict, List, Tuple
|
|
10
11
|
|
|
11
12
|
|
|
@@ -200,14 +201,14 @@ def extract_credentials_to_db(
|
|
|
200
201
|
hash_file: Path to hash file
|
|
201
202
|
engagement_id: Current engagement ID
|
|
202
203
|
"""
|
|
203
|
-
from souleyez.storage.credentials import
|
|
204
|
+
from souleyez.storage.credentials import CredentialsManager
|
|
204
205
|
|
|
205
206
|
results = parse_john_output(output, hash_file)
|
|
206
207
|
|
|
207
208
|
if not results["cracked"]:
|
|
208
209
|
return 0
|
|
209
210
|
|
|
210
|
-
cred_mgr =
|
|
211
|
+
cred_mgr = CredentialsManager()
|
|
211
212
|
added = 0
|
|
212
213
|
|
|
213
214
|
for cred in results["cracked"]:
|
|
@@ -5,9 +5,10 @@ souleyez.parsers.katana_parser - Parse Katana JSONL output
|
|
|
5
5
|
Katana is a web crawler from ProjectDiscovery that discovers endpoints,
|
|
6
6
|
parameters, and JavaScript-rendered routes.
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
import json
|
|
9
|
-
from typing import
|
|
10
|
-
from urllib.parse import
|
|
10
|
+
from typing import Any, Dict, List, Set
|
|
11
|
+
from urllib.parse import parse_qs, urlparse
|
|
11
12
|
|
|
12
13
|
# LFI-suspicious parameter names - these typically include files, not query databases
|
|
13
14
|
LFI_PARAM_NAMES = {
|
|
@@ -314,3 +315,134 @@ def extract_lfi_urls(parsed_data: Dict[str, Any]) -> List[str]:
|
|
|
314
315
|
List of URLs suitable for LFI testing
|
|
315
316
|
"""
|
|
316
317
|
return parsed_data.get("lfi_candidate_urls", [])
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def extract_endpoints_from_javascript(js_content: str, base_url: str) -> List[str]:
|
|
321
|
+
"""
|
|
322
|
+
Extract API endpoints from JavaScript source code.
|
|
323
|
+
|
|
324
|
+
This parses JavaScript to find REST API endpoints that katana's standard
|
|
325
|
+
crawling might miss, especially template strings like:
|
|
326
|
+
`${this.hostServer}/rest/products/search?q=${e}`
|
|
327
|
+
|
|
328
|
+
Args:
|
|
329
|
+
js_content: JavaScript source code content
|
|
330
|
+
base_url: Base URL of the target (e.g., http://192.168.1.126:3000)
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
List of discovered endpoint URLs with parameters
|
|
334
|
+
"""
|
|
335
|
+
import re
|
|
336
|
+
|
|
337
|
+
endpoints = []
|
|
338
|
+
base_url = base_url.rstrip("/")
|
|
339
|
+
|
|
340
|
+
# Pattern 1: Template strings with REST endpoints
|
|
341
|
+
# Matches: `/rest/something/action?param=${var}` or `${base}/rest/...?param=${var}`
|
|
342
|
+
template_patterns = [
|
|
343
|
+
# REST API with query params in template strings
|
|
344
|
+
r'[`"\'](?:\$\{[^}]+\})?(/(?:rest|api)/[a-zA-Z0-9/_-]+\?[a-zA-Z0-9_]+=)',
|
|
345
|
+
# Direct path with query params
|
|
346
|
+
r'[`"\'](/(?:rest|api)/[a-zA-Z0-9/_-]+\?[a-zA-Z0-9_]+=)\$?\{?',
|
|
347
|
+
# http.get/post with template string
|
|
348
|
+
r'\.(?:get|post|put|delete)\s*\(\s*[`"\'](?:\$\{[^}]+\})?(/[a-zA-Z0-9/_-]+\?[a-zA-Z0-9_]+=)',
|
|
349
|
+
]
|
|
350
|
+
|
|
351
|
+
for pattern in template_patterns:
|
|
352
|
+
matches = re.findall(pattern, js_content, re.IGNORECASE)
|
|
353
|
+
for match in matches:
|
|
354
|
+
# Clean up the path
|
|
355
|
+
path = match.strip("`'\"")
|
|
356
|
+
if path.startswith("/"):
|
|
357
|
+
full_url = f"{base_url}{path}"
|
|
358
|
+
if full_url not in endpoints:
|
|
359
|
+
endpoints.append(full_url)
|
|
360
|
+
|
|
361
|
+
# Pattern 2: REST endpoint patterns without explicit params
|
|
362
|
+
# Look for patterns like /rest/products/search and add common params
|
|
363
|
+
rest_patterns = [
|
|
364
|
+
r'[`"\'](/rest/[a-zA-Z0-9/_-]+/search)[`"\']',
|
|
365
|
+
r'[`"\'](/api/[a-zA-Z0-9/_-]+/search)[`"\']',
|
|
366
|
+
r'[`"\'](/rest/[a-zA-Z0-9/_-]+/query)[`"\']',
|
|
367
|
+
r'[`"\'](/api/[a-zA-Z0-9/_-]+/query)[`"\']',
|
|
368
|
+
r'[`"\'](/rest/[a-zA-Z0-9/_-]+/find)[`"\']',
|
|
369
|
+
r'[`"\'](/api/[a-zA-Z0-9/_-]+/find)[`"\']',
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
for pattern in rest_patterns:
|
|
373
|
+
matches = re.findall(pattern, js_content, re.IGNORECASE)
|
|
374
|
+
for match in matches:
|
|
375
|
+
path = match.strip("`'\"")
|
|
376
|
+
# Add common search parameters
|
|
377
|
+
for param in ["q", "query", "search", "term", "keyword"]:
|
|
378
|
+
full_url = f"{base_url}{path}?{param}="
|
|
379
|
+
if full_url not in endpoints:
|
|
380
|
+
endpoints.append(full_url)
|
|
381
|
+
|
|
382
|
+
# Pattern 3: Find fetch/http calls with URL construction
|
|
383
|
+
# Matches: this.http.get(`${x}/rest/products/search?q=${y}`)
|
|
384
|
+
fetch_pattern = r'\.(?:get|post|put|delete|fetch)\s*\([^)]*[`"\']([^`"\']*(?:rest|api)[^`"\']*\?[^`"\']*)[`"\']'
|
|
385
|
+
matches = re.findall(fetch_pattern, js_content, re.IGNORECASE)
|
|
386
|
+
for match in matches:
|
|
387
|
+
# Extract just the path part, removing template variables
|
|
388
|
+
path = re.sub(r"\$\{[^}]+\}", "", match)
|
|
389
|
+
if path.startswith("/"):
|
|
390
|
+
full_url = f"{base_url}{path}"
|
|
391
|
+
if full_url not in endpoints:
|
|
392
|
+
endpoints.append(full_url)
|
|
393
|
+
|
|
394
|
+
return endpoints
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def fetch_and_extract_js_endpoints(
|
|
398
|
+
base_url: str, js_urls: List[str], timeout: int = 10
|
|
399
|
+
) -> List[str]:
|
|
400
|
+
"""
|
|
401
|
+
Fetch JavaScript files and extract API endpoints from them.
|
|
402
|
+
|
|
403
|
+
This is used when katana's headless mode is unavailable (e.g., ARM64 Linux)
|
|
404
|
+
to find dynamic API endpoints that standard crawling misses.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
base_url: Base URL of the target
|
|
408
|
+
js_urls: List of JavaScript file URLs to fetch
|
|
409
|
+
timeout: Request timeout in seconds
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
List of discovered endpoint URLs with parameters
|
|
413
|
+
"""
|
|
414
|
+
import urllib.request
|
|
415
|
+
import urllib.error
|
|
416
|
+
import ssl
|
|
417
|
+
|
|
418
|
+
all_endpoints = []
|
|
419
|
+
|
|
420
|
+
# Create SSL context that doesn't verify (for self-signed certs)
|
|
421
|
+
ctx = ssl.create_default_context()
|
|
422
|
+
ctx.check_hostname = False
|
|
423
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
424
|
+
|
|
425
|
+
for js_url in js_urls:
|
|
426
|
+
# Only process actual .js files
|
|
427
|
+
if not js_url.endswith(".js"):
|
|
428
|
+
continue
|
|
429
|
+
|
|
430
|
+
try:
|
|
431
|
+
req = urllib.request.Request(
|
|
432
|
+
js_url,
|
|
433
|
+
headers={"User-Agent": "Mozilla/5.0 (compatible; SoulEyez/1.0)"},
|
|
434
|
+
)
|
|
435
|
+
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as response:
|
|
436
|
+
content = response.read().decode("utf-8", errors="replace")
|
|
437
|
+
|
|
438
|
+
# Extract endpoints from this JS file
|
|
439
|
+
endpoints = extract_endpoints_from_javascript(content, base_url)
|
|
440
|
+
for ep in endpoints:
|
|
441
|
+
if ep not in all_endpoints:
|
|
442
|
+
all_endpoints.append(ep)
|
|
443
|
+
|
|
444
|
+
except (urllib.error.URLError, TimeoutError, Exception):
|
|
445
|
+
# Skip files we can't fetch
|
|
446
|
+
continue
|
|
447
|
+
|
|
448
|
+
return all_endpoints
|
souleyez/parsers/msf_parser.py
CHANGED
souleyez/parsers/nikto_parser.py
CHANGED
|
@@ -4,8 +4,9 @@ souleyez.parsers.nikto_parser
|
|
|
4
4
|
|
|
5
5
|
Parses Nikto web server scanner output into structured data.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import re
|
|
8
|
-
from typing import
|
|
9
|
+
from typing import Any, Dict, List
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_nikto_output(output: str, target: str = "") -> Dict[str, Any]:
|