souleyez 2.25.0__tar.gz → 2.26.0__tar.gz
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-2.25.0 → souleyez-2.26.0}/BETA_README.md +1 -1
- {souleyez-2.25.0/souleyez.egg-info → souleyez-2.26.0}/PKG-INFO +2 -2
- {souleyez-2.25.0 → souleyez-2.26.0}/pyproject.toml +2 -2
- souleyez-2.26.0/souleyez/__init__.py +1 -0
- souleyez-2.26.0/souleyez/assets/__init__.py +1 -0
- souleyez-2.26.0/souleyez/assets/souleyez-icon.png +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/tool_chaining.py +124 -15
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/README.md +1 -1
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/result_handler.py +89 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/main.py +93 -1
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/crackmapexec_parser.py +101 -43
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/dnsrecon_parser.py +50 -35
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/enum4linux_parser.py +101 -21
- souleyez-2.26.0/souleyez/parsers/http_fingerprint_parser.py +319 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/hydra_parser.py +56 -5
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/impacket_parser.py +123 -44
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/john_parser.py +47 -14
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/msf_parser.py +20 -5
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/nmap_parser.py +48 -27
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/smbmap_parser.py +39 -23
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/sqlmap_parser.py +18 -9
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/theharvester_parser.py +21 -13
- souleyez-2.26.0/souleyez/plugins/http_fingerprint.py +592 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/setup_wizard.py +71 -0
- {souleyez-2.25.0 → souleyez-2.26.0/souleyez.egg-info}/PKG-INFO +2 -2
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez.egg-info/SOURCES.txt +4 -0
- souleyez-2.25.0/souleyez/__init__.py +0 -1
- {souleyez-2.25.0 → souleyez-2.26.0}/LICENSE +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/MANIFEST.in +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/README.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/setup.cfg +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/action_mapper.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/chain_advisor.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/claude_provider.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/context_builder.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/executor.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/feedback_handler.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/llm_factory.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/llm_provider.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/ollama_provider.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/ollama_service.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/path_scorer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/recommender.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/report_context.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/report_prompts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/report_service.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/result_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ai/safety.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/audit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/engagement_access.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/permissions.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/session_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/auth/user_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/audit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/auth.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/deliverables.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/engagement.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/license.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/screenshots.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/commands/user.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/config.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/credential_tester.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/cve_mappings.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/cve_matcher.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_auto_mapper.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_chain_engine.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_database.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_integration.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_rpc_client.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_rpc_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/msf_sync_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/network_utils.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/parser_handler.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/pending_chains.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/templates.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/version_utils.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/vuln_correlation.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/core/web_utils.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/README.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/active_directory.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/cis_controls_v8.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/cloud_security.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/cmmc_2.0.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/external_network.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/ffiec_cat.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/gdpr_article32.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/glba_safeguards.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/hipaa_security.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/hitrust_csf.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/internal_network.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/iso27001.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/nerc_cip.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/nist_csf.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/owasp_top10_2021.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/pci_dss_4.0.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/ptes_standard.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/red_team.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/soc2_type2.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/templates/webapp_advanced.json +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/README.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/all_users.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/api_endpoints.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/default_credentials.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/macos_users.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/router_passwords.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/router_users.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/soul_pass.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/soul_users.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/subdomains_common.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/top100.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/top20_quick.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/vnc_passwords.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/web_dirs_common.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/web_extensions.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/data/wordlists/web_files_common.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/detection/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/detection/attack_signatures.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/detection/mitre_mappings.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/detection/validator.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/devtools.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/api-reference/cli-commands.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/api-reference/engagement-api.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/api-reference/integration-guide.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/api-reference/parser-formats.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/architecture/decisions/000-template.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/architecture/decisions/001-local-llm-over-cloud.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/architecture/decisions/002-master-password-approach.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/architecture/decisions/003-database-schema-design.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/architecture/overview.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/database/MIGRATIONS.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/database/SCHEMA.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/database/SCHEMA_ERD.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/developer-guide/test_coverage_plan.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/developer-guide/ui-design-system.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/images/README.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/security/best-practices.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/security/credential-encryption.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/security/password-protected-commands.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/security/secure-defaults.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/security/threat-model.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/ai-integration.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/attack-surface.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/auto-chaining.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/configuration.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/deliverables-screenshots.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/dependencies.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/evidence-vault.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/exploit-suggestions.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/getting-started.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/installation.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/metasploit-integration.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/rbac.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/report-generation.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/siem-integration.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/tools-reference.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/troubleshooting.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/uninstall.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/worker-management.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/docs/user-guide/workflows.md +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/background.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/base.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/job_status.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/loader.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/log_sanitizer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/engine/worker_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/export/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/export/evidence_bundle.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/feature_flags/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/feature_flags/features.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/feature_flags.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/history.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/importers/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/importers/msf_importer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/importers/smart_importer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/base.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/elastic.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/factory.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/rule_mappings/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/rule_mappings/wazuh_rules.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/sentinel.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/splunk.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/siem/wazuh.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/wazuh/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/wazuh/client.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/wazuh/config.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/wazuh/host_mapper.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/integrations/wazuh/sync.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/correlation_analyzer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/exploit_knowledge.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/exploit_suggestions.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/gap_analyzer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/gap_detector.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/sensitive_tables.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/service_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/surface_analyzer.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/intelligence/target_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/licensing/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/licensing/validator.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/log_config.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/migrations/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/migrations/fix_job_counter.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/bloodhound_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/dalfox_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/ffuf_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/gobuster_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/hashcat_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/nikto_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/nuclei_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/responder_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/searchsploit_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/whois_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/parsers/wpscan_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/afp.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/afp_brute.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/ard.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/bloodhound.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/crackmapexec.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/dalfox.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/dns_hijack.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/dnsrecon.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/enum4linux.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/ffuf.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/firmware_extract.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/gobuster.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/hashcat.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/hydra.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/impacket_getnpusers.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/impacket_psexec.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/impacket_secretsdump.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/impacket_smbclient.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/john.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/macos_ssh.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/mdns.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/msf_auxiliary.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/msf_exploit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/nikto.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/nmap.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/nuclei.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/plugin_base.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/plugin_template.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/responder.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/router_http_brute.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/router_ssh_brute.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/router_telnet_brute.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/routersploit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/routersploit_exploit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/searchsploit.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/smbmap.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/sqlmap.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/theharvester.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/tr069.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/upnp.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/upnp_abuse.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/vnc_access.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/vnc_brute.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/whois.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/plugins/wpscan.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/attack_chain.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/charts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/compliance_mappings.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/detection_report.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/formatters.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/generator.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/reporting/metrics.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/scanner.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/security/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/security/validation.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/security.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/credentials.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/crypto.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/database.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/db.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/deliverable_evidence.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/deliverable_exporter.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/deliverable_templates.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/deliverables.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/engagements.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/evidence.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/execution_log.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/exploit_attempts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/exploits.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/findings.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/hosts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrate_to_engagements.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_001_add_credential_enhancements.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_002_add_status_tracking.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_003_add_execution_log.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_005_screenshots.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_006_deliverables.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_007_deliverable_templates.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_008_add_nuclei_table.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_009_add_cme_tables.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_010_evidence_linking.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_011_timeline_tracking.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_012_team_collaboration.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_013_add_host_tags.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_014_exploit_attempts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_015_add_mac_os_fields.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_016_add_domain_field.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_017_msf_sessions.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_018_add_osint_target.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_019_add_engagement_type.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_020_add_rbac.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_021_wazuh_integration.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_022_wazuh_indexer_columns.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_023_fix_detection_results_fk.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/_025_multi_siem_support.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/migrations/migration_manager.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/msf_sessions.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/osint.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/recommendation_engine.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/schema.sql +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/screenshots.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/smb_shares.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/sqlmap_data.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/team_collaboration.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/timeline_tracker.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/wazuh_vulns.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/storage/web_paths.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/testing/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/testing/credential_tester.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/ai_quotes.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/attack_surface.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/chain_rules_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/correlation_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/dashboard.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/deliverables_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/design_system.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/errors.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/evidence_linking_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/evidence_vault.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/exploit_suggestions_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/export_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/gap_analysis_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/help_system.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/intelligence_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/interactive.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/interactive_selector.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/log_formatter.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/menu_components.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/msf_auxiliary_menu.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/pending_chains_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/progress_indicators.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/recommendations_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/rule_builder.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/shortcuts.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/splunk_gap_analysis_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/splunk_vulns_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/team_dashboard.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/template_selector.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/terminal.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/timeline_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/tool_setup.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/tutorial.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/tutorial_state.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui/wazuh_vulns_view.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/ui.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/utils/__init__.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/utils/tool_checker.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/utils.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez/wordlists.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez.egg-info/dependency_links.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez.egg-info/entry_points.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez.egg-info/requires.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/souleyez.egg-info/top_level.txt +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_config.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_config_enhanced.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_crypto.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_database_100_final.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_engagements.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_engagements_simple.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_job_status_tracking.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_logging.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_network_utils.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_ollama_service.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_plugin_base.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_recommender.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_result_handler_sqlmap.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_schema.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_security_hardening.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_security_validation.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_sqlmap_parser.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_storage.py +0 -0
- {souleyez-2.25.0 → souleyez-2.26.0}/tests/test_version_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: souleyez
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.26.0
|
|
4
4
|
Summary: AI-Powered Penetration Testing Platform with 40+ integrated tools
|
|
5
5
|
Author-email: CyberSoul Security <contact@cybersoulsecurity.com>
|
|
6
6
|
Maintainer-email: CyberSoul Security <contact@cybersoulsecurity.com>
|
|
@@ -72,7 +72,7 @@ Welcome to the SoulEyez beta! Thank you for helping us test and improve this pen
|
|
|
72
72
|
|
|
73
73
|
> ⚠️ **Important**: Only use SoulEyez on systems you have explicit authorization to test.
|
|
74
74
|
|
|
75
|
-
## Version: 2.
|
|
75
|
+
## Version: 2.26.0
|
|
76
76
|
|
|
77
77
|
### What's Included
|
|
78
78
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "souleyez"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.26.0"
|
|
8
8
|
description = "AI-Powered Penetration Testing Platform with 40+ integrated tools"
|
|
9
9
|
readme = "BETA_README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -71,7 +71,7 @@ include = ["souleyez*"]
|
|
|
71
71
|
exclude = ["tests*", "scripts*", "reports*", "venv*", "debian*"]
|
|
72
72
|
|
|
73
73
|
[tool.setuptools.package-data]
|
|
74
|
-
souleyez = ["docs/**/*.md", "data/wordlists/*.txt", "data/wordlists/*.md", "data/templates/*.json", "data/templates/*.md"]
|
|
74
|
+
souleyez = ["docs/**/*.md", "data/wordlists/*.txt", "data/wordlists/*.md", "data/templates/*.json", "data/templates/*.md", "assets/*.png"]
|
|
75
75
|
|
|
76
76
|
[tool.pytest.ini_options]
|
|
77
77
|
testpaths = ["tests"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.26.0'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# SoulEyez assets package
|
|
Binary file
|
|
@@ -15,6 +15,17 @@ CATEGORY_CTF = "ctf" # Lab/learning scenarios - vulnerable by design
|
|
|
15
15
|
CATEGORY_ENTERPRISE = "enterprise" # Real-world enterprise testing
|
|
16
16
|
CATEGORY_GENERAL = "general" # Standard recon that applies everywhere
|
|
17
17
|
|
|
18
|
+
# Managed hosting platforms - skip CGI enumeration (pointless on these)
|
|
19
|
+
# These are detected from server headers/banners and product names
|
|
20
|
+
MANAGED_HOSTING_PLATFORMS = {
|
|
21
|
+
'squarespace', 'wix', 'shopify', 'webflow', 'weebly',
|
|
22
|
+
'wordpress.com', 'ghost.io', 'medium', 'tumblr', 'blogger',
|
|
23
|
+
'netlify', 'vercel', 'github.io', 'pages.dev', 'cloudflare',
|
|
24
|
+
'heroku', 'railway', 'render.com', 'fly.io',
|
|
25
|
+
'aws cloudfront', 'akamai', 'fastly', 'cloudflare',
|
|
26
|
+
'azure', 'google cloud', 'firebase',
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
# Category display icons
|
|
19
30
|
CATEGORY_ICONS = {
|
|
20
31
|
CATEGORY_CTF: "🎯",
|
|
@@ -140,6 +151,75 @@ def classify_os_device(os_string: str, services: list) -> dict:
|
|
|
140
151
|
return {'os_family': 'unknown', 'device_type': 'unknown', 'vendor': None}
|
|
141
152
|
|
|
142
153
|
|
|
154
|
+
def is_managed_hosting(services: List[Dict[str, Any]], http_fingerprint: Dict[str, Any] = None) -> bool:
|
|
155
|
+
"""
|
|
156
|
+
Detect if target is a managed hosting platform.
|
|
157
|
+
|
|
158
|
+
These platforms don't have CGI directories, so tools like nikto
|
|
159
|
+
should skip CGI enumeration to avoid long, pointless scans.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
services: List of service dicts from nmap parser
|
|
163
|
+
http_fingerprint: Optional fingerprint data from http_fingerprint plugin
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
True if managed hosting detected, False otherwise
|
|
167
|
+
"""
|
|
168
|
+
# Check fingerprint data first (most reliable, comes from actual HTTP headers)
|
|
169
|
+
if http_fingerprint:
|
|
170
|
+
managed = http_fingerprint.get('managed_hosting')
|
|
171
|
+
if managed:
|
|
172
|
+
return True
|
|
173
|
+
|
|
174
|
+
# Fall back to checking services data (less reliable, from nmap banners)
|
|
175
|
+
for service in services:
|
|
176
|
+
# Check product field
|
|
177
|
+
product = (service.get('product') or '').lower()
|
|
178
|
+
raw_version = (service.get('raw_version') or '').lower()
|
|
179
|
+
service_name = (service.get('service') or '').lower()
|
|
180
|
+
|
|
181
|
+
# Combine all fields for matching
|
|
182
|
+
combined = f"{product} {raw_version} {service_name}"
|
|
183
|
+
|
|
184
|
+
# Check against known managed hosting platforms
|
|
185
|
+
for platform in MANAGED_HOSTING_PLATFORMS:
|
|
186
|
+
if platform in combined:
|
|
187
|
+
return True
|
|
188
|
+
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def get_managed_hosting_platform(services: List[Dict[str, Any]], http_fingerprint: Dict[str, Any] = None) -> Optional[str]:
|
|
193
|
+
"""
|
|
194
|
+
Get the name of the managed hosting platform if detected.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
services: List of service dicts from nmap parser
|
|
198
|
+
http_fingerprint: Optional fingerprint data from http_fingerprint plugin
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
Platform name or None
|
|
202
|
+
"""
|
|
203
|
+
# Check fingerprint data first
|
|
204
|
+
if http_fingerprint:
|
|
205
|
+
managed = http_fingerprint.get('managed_hosting')
|
|
206
|
+
if managed:
|
|
207
|
+
return managed
|
|
208
|
+
|
|
209
|
+
# Fall back to services check
|
|
210
|
+
for service in services:
|
|
211
|
+
product = (service.get('product') or '').lower()
|
|
212
|
+
raw_version = (service.get('raw_version') or '').lower()
|
|
213
|
+
service_name = (service.get('service') or '').lower()
|
|
214
|
+
combined = f"{product} {raw_version} {service_name}"
|
|
215
|
+
|
|
216
|
+
for platform in MANAGED_HOSTING_PLATFORMS:
|
|
217
|
+
if platform in combined:
|
|
218
|
+
return platform.title()
|
|
219
|
+
|
|
220
|
+
return None
|
|
221
|
+
|
|
222
|
+
|
|
143
223
|
# Technology to Nuclei tags mapping
|
|
144
224
|
# Maps detected products/technologies to relevant nuclei template tags
|
|
145
225
|
TECH_TO_NUCLEI_TAGS = {
|
|
@@ -575,6 +655,25 @@ class ChainRule:
|
|
|
575
655
|
new_args.append(arg)
|
|
576
656
|
args = new_args
|
|
577
657
|
|
|
658
|
+
# For Nikto: Skip CGI enumeration on managed hosting platforms
|
|
659
|
+
# This prevents long, pointless scans on Squarespace, Wix, etc.
|
|
660
|
+
if self.target_tool == 'nikto':
|
|
661
|
+
services = context.get('services', [])
|
|
662
|
+
http_fingerprint = context.get('http_fingerprint', {})
|
|
663
|
+
if is_managed_hosting(services, http_fingerprint):
|
|
664
|
+
# Add -C none to skip CGI dirs (pointless on managed hosting)
|
|
665
|
+
if '-C' not in str(args):
|
|
666
|
+
args.extend(['-C', 'none'])
|
|
667
|
+
# Add -Tuning x6 to skip remote file inclusion tests
|
|
668
|
+
if '-Tuning' not in str(args):
|
|
669
|
+
args.extend(['-Tuning', 'x6'])
|
|
670
|
+
# Log which platform was detected
|
|
671
|
+
platform = get_managed_hosting_platform(services, http_fingerprint)
|
|
672
|
+
if platform:
|
|
673
|
+
from souleyez.log_config import get_logger
|
|
674
|
+
logger = get_logger(__name__)
|
|
675
|
+
logger.info(f"[FINGERPRINT] Managed hosting detected ({platform}) - nikto using optimized scan config")
|
|
676
|
+
|
|
578
677
|
# For SQLMap with POST injections, add --data if we have POST data
|
|
579
678
|
if self.target_tool == 'sqlmap' and post_data and '--data' not in str(args):
|
|
580
679
|
# Insert --data after -u argument
|
|
@@ -642,32 +741,42 @@ class ToolChaining:
|
|
|
642
741
|
|
|
643
742
|
# Web service discovered → run web scanners
|
|
644
743
|
self.rules.extend([
|
|
645
|
-
#
|
|
646
|
-
#
|
|
744
|
+
# HTTP Fingerprinting - runs FIRST to detect WAF/CDN/managed hosting
|
|
745
|
+
# This enables smarter tool configuration for downstream scanners
|
|
647
746
|
ChainRule(
|
|
648
747
|
trigger_tool='nmap',
|
|
649
748
|
trigger_condition='service:http',
|
|
749
|
+
target_tool='http_fingerprint',
|
|
750
|
+
priority=11, # Highest priority - runs before all other web tools
|
|
751
|
+
args_template=[],
|
|
752
|
+
description='Web server detected, fingerprinting for WAF/CDN/platform detection'
|
|
753
|
+
),
|
|
754
|
+
# Nikto triggered by http_fingerprint (uses fingerprint data for smart config)
|
|
755
|
+
ChainRule(
|
|
756
|
+
trigger_tool='http_fingerprint',
|
|
757
|
+
trigger_condition='has:services',
|
|
758
|
+
target_tool='nikto',
|
|
759
|
+
priority=8,
|
|
760
|
+
args_template=['-nointeractive', '-timeout', '10'],
|
|
761
|
+
description='Fingerprinting complete, scanning for server misconfigurations with Nikto'
|
|
762
|
+
),
|
|
763
|
+
# Nuclei triggered by http_fingerprint
|
|
764
|
+
ChainRule(
|
|
765
|
+
trigger_tool='http_fingerprint',
|
|
766
|
+
trigger_condition='has:services',
|
|
650
767
|
target_tool='nuclei',
|
|
651
768
|
priority=9,
|
|
652
769
|
args_template=['-tags', '{nuclei_tags}', '-severity', 'critical,high', '-rate-limit', '50', '-c', '10', '-timeout', '10'],
|
|
653
|
-
description='
|
|
770
|
+
description='Fingerprinting complete, scanning with Nuclei'
|
|
654
771
|
),
|
|
772
|
+
# Gobuster triggered by http_fingerprint
|
|
655
773
|
ChainRule(
|
|
656
|
-
trigger_tool='
|
|
657
|
-
trigger_condition='
|
|
774
|
+
trigger_tool='http_fingerprint',
|
|
775
|
+
trigger_condition='has:services',
|
|
658
776
|
target_tool='gobuster',
|
|
659
777
|
priority=7,
|
|
660
778
|
args_template=['dir', '-u', 'http://{target}:{port}', '-w', 'data/wordlists/web_dirs_common.txt', '-x', 'js,json,php,asp,aspx,html,txt,bak,old,zip', '--no-error', '--timeout', '30s', '-t', '5', '--delay', '20ms'],
|
|
661
|
-
description='
|
|
662
|
-
),
|
|
663
|
-
# Nikto - web server vulnerability scanner (complements nuclei)
|
|
664
|
-
ChainRule(
|
|
665
|
-
trigger_tool='nmap',
|
|
666
|
-
trigger_condition='service:http',
|
|
667
|
-
target_tool='nikto',
|
|
668
|
-
priority=8,
|
|
669
|
-
args_template=['-nointeractive', '-timeout', '10'],
|
|
670
|
-
description='Web server detected, scanning for server misconfigurations with Nikto'
|
|
779
|
+
description='Fingerprinting complete, discovering directories and files'
|
|
671
780
|
),
|
|
672
781
|
# Dalfox - XSS scanner triggered after gobuster finds pages
|
|
673
782
|
ChainRule(
|
|
@@ -108,6 +108,8 @@ def handle_job_result(job: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
|
108
108
|
parse_result = parse_nikto_job(engagement_id, log_path, job)
|
|
109
109
|
elif tool == 'dalfox':
|
|
110
110
|
parse_result = parse_dalfox_job(engagement_id, log_path, job)
|
|
111
|
+
elif tool == 'http_fingerprint':
|
|
112
|
+
parse_result = parse_http_fingerprint_job(engagement_id, log_path, job)
|
|
111
113
|
|
|
112
114
|
# NOTE: Auto-chaining is now handled in background.py after parsing completes
|
|
113
115
|
# This avoids duplicate job creation and gives better control over timing
|
|
@@ -204,6 +206,8 @@ def reparse_job(job_id: int) -> Dict[str, Any]:
|
|
|
204
206
|
parse_result = parse_nikto_job(engagement_id, log_path, job)
|
|
205
207
|
elif tool == 'dalfox':
|
|
206
208
|
parse_result = parse_dalfox_job(engagement_id, log_path, job)
|
|
209
|
+
elif tool == 'http_fingerprint':
|
|
210
|
+
parse_result = parse_http_fingerprint_job(engagement_id, log_path, job)
|
|
207
211
|
else:
|
|
208
212
|
return {'success': False, 'message': f'No parser available for tool: {tool}'}
|
|
209
213
|
|
|
@@ -3068,6 +3072,91 @@ def parse_nikto_job(engagement_id: int, log_path: str, job: Dict[str, Any]) -> D
|
|
|
3068
3072
|
return {'error': str(e)}
|
|
3069
3073
|
|
|
3070
3074
|
|
|
3075
|
+
def parse_http_fingerprint_job(engagement_id: int, log_path: str, job: Dict[str, Any]) -> Dict[str, Any]:
|
|
3076
|
+
"""
|
|
3077
|
+
Parse HTTP fingerprint results.
|
|
3078
|
+
|
|
3079
|
+
Returns fingerprint data for use in auto-chaining context.
|
|
3080
|
+
This enables downstream tools (nikto, nuclei, etc.) to make smarter decisions
|
|
3081
|
+
based on detected WAF, CDN, or managed hosting platform.
|
|
3082
|
+
"""
|
|
3083
|
+
try:
|
|
3084
|
+
from souleyez.parsers.http_fingerprint_parser import (
|
|
3085
|
+
parse_http_fingerprint_output,
|
|
3086
|
+
build_fingerprint_context,
|
|
3087
|
+
get_tool_recommendations
|
|
3088
|
+
)
|
|
3089
|
+
from souleyez.storage.hosts import HostManager
|
|
3090
|
+
from urllib.parse import urlparse
|
|
3091
|
+
|
|
3092
|
+
target = job.get('target', '')
|
|
3093
|
+
|
|
3094
|
+
# Read log file
|
|
3095
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
3096
|
+
output = f.read()
|
|
3097
|
+
|
|
3098
|
+
parsed = parse_http_fingerprint_output(output, target)
|
|
3099
|
+
|
|
3100
|
+
# Extract host from target URL
|
|
3101
|
+
parsed_url = urlparse(target)
|
|
3102
|
+
target_host = parsed_url.hostname or target
|
|
3103
|
+
|
|
3104
|
+
# Update host with fingerprint info if we have useful data
|
|
3105
|
+
if target_host and (parsed.get('server') or parsed.get('managed_hosting')):
|
|
3106
|
+
hm = HostManager()
|
|
3107
|
+
host_data = {
|
|
3108
|
+
'ip': target_host,
|
|
3109
|
+
'status': 'up'
|
|
3110
|
+
}
|
|
3111
|
+
# Store server info in notes or a dedicated field
|
|
3112
|
+
# For now, we just ensure the host exists
|
|
3113
|
+
hm.add_or_update_host(engagement_id, host_data)
|
|
3114
|
+
|
|
3115
|
+
# Build fingerprint context for chaining
|
|
3116
|
+
fingerprint_context = build_fingerprint_context(parsed)
|
|
3117
|
+
|
|
3118
|
+
# Get tool recommendations
|
|
3119
|
+
recommendations = get_tool_recommendations(parsed)
|
|
3120
|
+
|
|
3121
|
+
# Determine status
|
|
3122
|
+
if parsed.get('error'):
|
|
3123
|
+
status = STATUS_ERROR
|
|
3124
|
+
elif parsed.get('managed_hosting') or parsed.get('waf') or parsed.get('cdn'):
|
|
3125
|
+
status = STATUS_DONE # Found useful info
|
|
3126
|
+
elif parsed.get('server'):
|
|
3127
|
+
status = STATUS_DONE
|
|
3128
|
+
else:
|
|
3129
|
+
status = STATUS_NO_RESULTS
|
|
3130
|
+
|
|
3131
|
+
return {
|
|
3132
|
+
'tool': 'http_fingerprint',
|
|
3133
|
+
'status': status,
|
|
3134
|
+
'target': target,
|
|
3135
|
+
'target_host': target_host,
|
|
3136
|
+
# Core fingerprint data
|
|
3137
|
+
'server': parsed.get('server'),
|
|
3138
|
+
'managed_hosting': parsed.get('managed_hosting'),
|
|
3139
|
+
'waf': parsed.get('waf', []),
|
|
3140
|
+
'cdn': parsed.get('cdn', []),
|
|
3141
|
+
'technologies': parsed.get('technologies', []),
|
|
3142
|
+
'status_code': parsed.get('status_code'),
|
|
3143
|
+
# For auto-chaining context
|
|
3144
|
+
'http_fingerprint': fingerprint_context.get('http_fingerprint', {}),
|
|
3145
|
+
'recommendations': recommendations,
|
|
3146
|
+
# Pass through for downstream chains
|
|
3147
|
+
'services': [{
|
|
3148
|
+
'ip': target_host,
|
|
3149
|
+
'port': parsed_url.port or (443 if parsed_url.scheme == 'https' else 80),
|
|
3150
|
+
'service_name': 'https' if parsed_url.scheme == 'https' else 'http',
|
|
3151
|
+
'product': parsed.get('server', ''),
|
|
3152
|
+
}],
|
|
3153
|
+
}
|
|
3154
|
+
|
|
3155
|
+
except Exception as e:
|
|
3156
|
+
logger.error(f"Error parsing http_fingerprint job: {e}")
|
|
3157
|
+
return {'error': str(e)}
|
|
3158
|
+
|
|
3159
|
+
|
|
3071
3160
|
def parse_dalfox_job(engagement_id: int, log_path: str, job: Dict[str, Any]) -> Dict[str, Any]:
|
|
3072
3161
|
"""Parse Dalfox XSS scanner results."""
|
|
3073
3162
|
try:
|
|
@@ -173,7 +173,7 @@ def _check_privileged_tools():
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
@click.group()
|
|
176
|
-
@click.version_option(version='2.
|
|
176
|
+
@click.version_option(version='2.26.0')
|
|
177
177
|
def cli():
|
|
178
178
|
"""SoulEyez - AI-Powered Pentesting Platform by CyberSoul Security"""
|
|
179
179
|
from souleyez.log_config import init_logging
|
|
@@ -1520,6 +1520,98 @@ def tutorial():
|
|
|
1520
1520
|
run_tutorial()
|
|
1521
1521
|
|
|
1522
1522
|
|
|
1523
|
+
@cli.command('install-desktop')
|
|
1524
|
+
@click.option('--remove', is_flag=True, help='Remove the desktop shortcut')
|
|
1525
|
+
def install_desktop(remove):
|
|
1526
|
+
"""Install SoulEyez desktop shortcut in Applications menu.
|
|
1527
|
+
|
|
1528
|
+
Creates a .desktop file so SoulEyez appears in your
|
|
1529
|
+
Applications > Security menu with its icon.
|
|
1530
|
+
"""
|
|
1531
|
+
import shutil
|
|
1532
|
+
from importlib import resources
|
|
1533
|
+
|
|
1534
|
+
applications_dir = Path.home() / '.local' / 'share' / 'applications'
|
|
1535
|
+
icons_dir = Path.home() / '.local' / 'share' / 'icons'
|
|
1536
|
+
desktop_file = applications_dir / 'souleyez.desktop'
|
|
1537
|
+
icon_dest = icons_dir / 'souleyez.png'
|
|
1538
|
+
|
|
1539
|
+
if remove:
|
|
1540
|
+
# Remove desktop shortcut
|
|
1541
|
+
removed = False
|
|
1542
|
+
if desktop_file.exists():
|
|
1543
|
+
desktop_file.unlink()
|
|
1544
|
+
click.echo(click.style(" Removed desktop shortcut", fg='green'))
|
|
1545
|
+
removed = True
|
|
1546
|
+
if icon_dest.exists():
|
|
1547
|
+
icon_dest.unlink()
|
|
1548
|
+
click.echo(click.style(" Removed icon", fg='green'))
|
|
1549
|
+
removed = True
|
|
1550
|
+
if removed:
|
|
1551
|
+
click.echo(click.style("\nSoulEyez removed from Applications menu.", fg='cyan'))
|
|
1552
|
+
else:
|
|
1553
|
+
click.echo(click.style("No desktop shortcut found.", fg='yellow'))
|
|
1554
|
+
return
|
|
1555
|
+
|
|
1556
|
+
click.echo(click.style("\nInstalling SoulEyez desktop shortcut...\n", fg='cyan', bold=True))
|
|
1557
|
+
|
|
1558
|
+
# Create directories
|
|
1559
|
+
applications_dir.mkdir(parents=True, exist_ok=True)
|
|
1560
|
+
icons_dir.mkdir(parents=True, exist_ok=True)
|
|
1561
|
+
|
|
1562
|
+
# Find and copy icon
|
|
1563
|
+
try:
|
|
1564
|
+
# Try importlib.resources first (Python 3.9+)
|
|
1565
|
+
try:
|
|
1566
|
+
from importlib.resources import files
|
|
1567
|
+
icon_source = files('souleyez.assets').joinpath('souleyez-icon.png')
|
|
1568
|
+
with open(icon_source, 'rb') as src:
|
|
1569
|
+
icon_data = src.read()
|
|
1570
|
+
except (ImportError, TypeError, FileNotFoundError):
|
|
1571
|
+
# Fallback: find icon relative to this file
|
|
1572
|
+
icon_source = Path(__file__).parent / 'assets' / 'souleyez-icon.png'
|
|
1573
|
+
with open(icon_source, 'rb') as src:
|
|
1574
|
+
icon_data = src.read()
|
|
1575
|
+
|
|
1576
|
+
with open(icon_dest, 'wb') as dst:
|
|
1577
|
+
dst.write(icon_data)
|
|
1578
|
+
click.echo(click.style(" Installed icon", fg='green'))
|
|
1579
|
+
except Exception as e:
|
|
1580
|
+
click.echo(click.style(f" Warning: Could not copy icon: {e}", fg='yellow'))
|
|
1581
|
+
icon_dest = "utilities-terminal" # Fallback to system icon
|
|
1582
|
+
|
|
1583
|
+
# Create .desktop file
|
|
1584
|
+
desktop_content = f"""[Desktop Entry]
|
|
1585
|
+
Name=SoulEyez
|
|
1586
|
+
Comment=AI-Powered Penetration Testing Platform
|
|
1587
|
+
Exec=souleyez interactive
|
|
1588
|
+
Icon={icon_dest}
|
|
1589
|
+
Terminal=true
|
|
1590
|
+
Type=Application
|
|
1591
|
+
Categories=Security;System;Network;
|
|
1592
|
+
Keywords=pentest;security;hacking;nmap;metasploit;
|
|
1593
|
+
"""
|
|
1594
|
+
|
|
1595
|
+
desktop_file.write_text(desktop_content)
|
|
1596
|
+
click.echo(click.style(" Created desktop entry", fg='green'))
|
|
1597
|
+
|
|
1598
|
+
# Update desktop database (optional, may not be available)
|
|
1599
|
+
try:
|
|
1600
|
+
import subprocess
|
|
1601
|
+
subprocess.run(['update-desktop-database', str(applications_dir)],
|
|
1602
|
+
capture_output=True, check=False)
|
|
1603
|
+
except Exception:
|
|
1604
|
+
pass # Not critical if this fails
|
|
1605
|
+
|
|
1606
|
+
click.echo()
|
|
1607
|
+
click.echo(click.style("SoulEyez added to Applications menu!", fg='green', bold=True))
|
|
1608
|
+
click.echo()
|
|
1609
|
+
click.echo("You can find it under:")
|
|
1610
|
+
click.echo(click.style(" Applications > Security > SoulEyez", fg='cyan'))
|
|
1611
|
+
click.echo()
|
|
1612
|
+
click.echo("To remove: souleyez install-desktop --remove")
|
|
1613
|
+
|
|
1614
|
+
|
|
1523
1615
|
def main():
|
|
1524
1616
|
"""Main entry point."""
|
|
1525
1617
|
cli()
|
|
@@ -72,42 +72,61 @@ def _parse_content(content: str, target: str) -> Dict[str, Any]:
|
|
|
72
72
|
'auth_info': {}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
# Remove ANSI color codes first
|
|
76
|
+
content = re.sub(r'\x1b\[[0-9;]*m', '', content)
|
|
77
|
+
|
|
75
78
|
for line in content.split('\n'):
|
|
76
79
|
# Parse host information (Windows OR Unix/Samba)
|
|
77
|
-
# Format
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
# Format variations:
|
|
81
|
+
# SMB 10.0.0.88 445 HOSTNAME [*] Windows/Unix ... (name:HOSTNAME) (domain:DOMAIN) ...
|
|
82
|
+
# SMB 10.0.0.88 445 HOSTNAME [*] Windows Server 2016 ...
|
|
83
|
+
# WINRM 10.0.0.88 5985 HOSTNAME [*] http://10.0.0.88:5985/wsman
|
|
84
|
+
|
|
85
|
+
os_keywords = ['Windows', 'Unix', 'Samba', 'Linux', 'Server', 'Microsoft']
|
|
86
|
+
if any(proto in line for proto in ['SMB', 'WINRM', 'SSH', 'RDP']) and '[*]' in line:
|
|
87
|
+
# Try multiple patterns for host info
|
|
88
|
+
host_match = None
|
|
89
|
+
|
|
90
|
+
# Pattern 1: Standard format with flexible whitespace
|
|
91
|
+
host_match = re.search(r'(\d+\.\d+\.\d+\.\d+)\s+(\d+)\s+(\S+)\s+\[\*\]\s*(.+)', line)
|
|
92
|
+
|
|
93
|
+
# Pattern 2: Protocol prefix format
|
|
94
|
+
if not host_match:
|
|
95
|
+
host_match = re.search(r'(?:SMB|WINRM|SSH|RDP)\s+(\d+\.\d+\.\d+\.\d+)\s+(\d+)\s+(\S+)\s+\[\*\]\s*(.+)', line)
|
|
96
|
+
|
|
80
97
|
if host_match:
|
|
81
98
|
ip = host_match.group(1)
|
|
82
99
|
port = int(host_match.group(2))
|
|
83
100
|
hostname = host_match.group(3)
|
|
84
101
|
details = host_match.group(4).strip()
|
|
85
102
|
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
# Only process as host info if it looks like OS/version info
|
|
104
|
+
if any(kw in details for kw in os_keywords) or '(domain:' in details:
|
|
105
|
+
# Extract domain from (domain:DOMAIN) or domain: pattern
|
|
106
|
+
domain_match = re.search(r'\(?domain:?\s*([^)\s]+)\)?', details, re.IGNORECASE)
|
|
107
|
+
domain = domain_match.group(1) if domain_match else None
|
|
108
|
+
|
|
109
|
+
# Extract OS info (everything before the first parenthesis)
|
|
110
|
+
os_match = re.match(r'([^(]+)', details)
|
|
111
|
+
os_info = os_match.group(1).strip() if os_match else details
|
|
112
|
+
|
|
113
|
+
# Extract SMB signing status (multiple formats)
|
|
114
|
+
signing_match = re.search(r'\(?signing:?\s*(\w+)\)?', details, re.IGNORECASE)
|
|
115
|
+
signing = signing_match.group(1) if signing_match else None
|
|
116
|
+
|
|
117
|
+
# Extract SMBv1 status
|
|
118
|
+
smbv1_match = re.search(r'\(?SMBv1:?\s*(\w+)\)?', details, re.IGNORECASE)
|
|
119
|
+
smbv1 = smbv1_match.group(1) if smbv1_match else None
|
|
120
|
+
|
|
121
|
+
findings['hosts'].append({
|
|
122
|
+
'ip': ip,
|
|
123
|
+
'port': port,
|
|
124
|
+
'hostname': hostname,
|
|
125
|
+
'domain': domain,
|
|
126
|
+
'os': os_info,
|
|
127
|
+
'signing': signing,
|
|
128
|
+
'smbv1': smbv1
|
|
129
|
+
})
|
|
111
130
|
|
|
112
131
|
# Parse authentication status
|
|
113
132
|
# Format: SMB 10.0.0.14 445 HOSTNAME [+] \: (Guest)
|
|
@@ -122,13 +141,23 @@ def _parse_content(content: str, target: str) -> Dict[str, Any]:
|
|
|
122
141
|
}
|
|
123
142
|
|
|
124
143
|
# Parse share enumeration (shares WITH permissions)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
# Format variations:
|
|
145
|
+
# SMB ... ADMIN$ READ,WRITE Remote Admin
|
|
146
|
+
# SMB ... ADMIN$ READ, WRITE Remote Admin (with space)
|
|
147
|
+
# SMB ... C$ READ ONLY Default share
|
|
148
|
+
share_perm_match = re.search(
|
|
149
|
+
r'SMB.*\s+(\S+\$?)\s+(READ,?\s*WRITE|READ\s*ONLY|WRITE\s*ONLY|READ|WRITE|NO\s*ACCESS)\s*(.*)$',
|
|
150
|
+
line, re.IGNORECASE
|
|
151
|
+
)
|
|
152
|
+
if share_perm_match:
|
|
153
|
+
share_name = share_perm_match.group(1)
|
|
154
|
+
# Skip if it looks like a header or status line
|
|
155
|
+
if share_name not in ['Share', 'Permissions', 'shares']:
|
|
156
|
+
findings['shares'].append({
|
|
157
|
+
'name': share_name,
|
|
158
|
+
'permissions': share_perm_match.group(2).upper().replace(' ', ''),
|
|
159
|
+
'comment': share_perm_match.group(3).strip() if share_perm_match.group(3) else ''
|
|
160
|
+
})
|
|
132
161
|
# Parse share enumeration (shares WITHOUT explicit permissions - just listed)
|
|
133
162
|
elif 'SMB' in line and not ('Share' in line and 'Permissions' in line) and not '-----' in line:
|
|
134
163
|
# Look for lines with share names (ending with $, or common names like print$, public, IPC$)
|
|
@@ -146,9 +175,16 @@ def _parse_content(content: str, target: str) -> Dict[str, Any]:
|
|
|
146
175
|
'comment': remark
|
|
147
176
|
})
|
|
148
177
|
|
|
149
|
-
# Parse user enumeration
|
|
150
|
-
|
|
151
|
-
|
|
178
|
+
# Parse user enumeration with flexible format
|
|
179
|
+
# Format variations:
|
|
180
|
+
# username badpwdcount: 0 desc: Description
|
|
181
|
+
# username badpwdcount:0 desc:Description
|
|
182
|
+
# username baddpwdcount: 0 description: Description
|
|
183
|
+
if 'badpwdcount' in line.lower() or 'baddpwdcount' in line.lower():
|
|
184
|
+
user_match = re.search(
|
|
185
|
+
r'(\S+)\s+bad+pwdcount:?\s*(\d+)\s+(?:desc(?:ription)?:?\s*)?(.+)?',
|
|
186
|
+
line, re.IGNORECASE
|
|
187
|
+
)
|
|
152
188
|
if user_match:
|
|
153
189
|
findings['users'].append({
|
|
154
190
|
'username': user_match.group(1),
|
|
@@ -165,15 +201,37 @@ def _parse_content(content: str, target: str) -> Dict[str, Any]:
|
|
|
165
201
|
})
|
|
166
202
|
|
|
167
203
|
# Parse valid credentials (but not Guest authentication)
|
|
168
|
-
|
|
169
|
-
|
|
204
|
+
# Format variations:
|
|
205
|
+
# [+] DOMAIN\username:password (Pwn3d!)
|
|
206
|
+
# [+] DOMAIN\\username:password (Pwn3d!)
|
|
207
|
+
# [+] username:password (Pwn3d!)
|
|
208
|
+
# [+] DOMAIN/username:password (Pwn3d!)
|
|
209
|
+
if '[+]' in line and ('Pwn3d' in line or ':' in line):
|
|
210
|
+
# Try domain\user:pass format first
|
|
211
|
+
cred_match = re.search(
|
|
212
|
+
r'\[\+\]\s*([^\\/:]+)[\\\/]+([^:]+):([^\s(]+)\s*(\(Pwn3d!?\))?',
|
|
213
|
+
line, re.IGNORECASE
|
|
214
|
+
)
|
|
170
215
|
if cred_match:
|
|
171
216
|
findings['credentials'].append({
|
|
172
|
-
'domain': cred_match.group(1),
|
|
173
|
-
'username': cred_match.group(2),
|
|
174
|
-
'password': cred_match.group(3),
|
|
217
|
+
'domain': cred_match.group(1).strip(),
|
|
218
|
+
'username': cred_match.group(2).strip(),
|
|
219
|
+
'password': cred_match.group(3).strip(),
|
|
175
220
|
'admin': bool(cred_match.group(4))
|
|
176
221
|
})
|
|
222
|
+
else:
|
|
223
|
+
# Try user:pass format (no domain)
|
|
224
|
+
cred_match = re.search(
|
|
225
|
+
r'\[\+\]\s*([^:@\s]+):([^\s(]+)\s*(\(Pwn3d!?\))?',
|
|
226
|
+
line, re.IGNORECASE
|
|
227
|
+
)
|
|
228
|
+
if cred_match and '@' not in cred_match.group(1):
|
|
229
|
+
findings['credentials'].append({
|
|
230
|
+
'domain': '',
|
|
231
|
+
'username': cred_match.group(1).strip(),
|
|
232
|
+
'password': cred_match.group(2).strip(),
|
|
233
|
+
'admin': bool(cred_match.group(3))
|
|
234
|
+
})
|
|
177
235
|
|
|
178
236
|
# Extract admin credentials for auto-chaining
|
|
179
237
|
admin_creds = [c for c in findings['credentials'] if c.get('admin')]
|