souleyez 2.43.29__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- souleyez/__init__.py +1 -2
- souleyez/ai/__init__.py +21 -15
- souleyez/ai/action_mapper.py +249 -150
- souleyez/ai/chain_advisor.py +116 -100
- souleyez/ai/claude_provider.py +29 -28
- souleyez/ai/context_builder.py +80 -62
- souleyez/ai/executor.py +158 -117
- souleyez/ai/feedback_handler.py +136 -121
- souleyez/ai/llm_factory.py +27 -20
- souleyez/ai/llm_provider.py +4 -2
- souleyez/ai/ollama_provider.py +6 -9
- souleyez/ai/ollama_service.py +44 -37
- souleyez/ai/path_scorer.py +91 -76
- souleyez/ai/recommender.py +176 -144
- souleyez/ai/report_context.py +74 -73
- souleyez/ai/report_service.py +84 -66
- souleyez/ai/result_parser.py +222 -229
- souleyez/ai/safety.py +67 -44
- souleyez/auth/__init__.py +23 -22
- souleyez/auth/audit.py +36 -26
- souleyez/auth/engagement_access.py +65 -48
- souleyez/auth/permissions.py +14 -3
- souleyez/auth/session_manager.py +54 -37
- souleyez/auth/user_manager.py +109 -64
- souleyez/commands/audit.py +40 -43
- souleyez/commands/auth.py +35 -15
- souleyez/commands/deliverables.py +55 -50
- souleyez/commands/engagement.py +47 -28
- souleyez/commands/license.py +32 -23
- souleyez/commands/screenshots.py +36 -32
- souleyez/commands/user.py +82 -36
- souleyez/config.py +52 -44
- souleyez/core/credential_tester.py +87 -81
- souleyez/core/cve_mappings.py +179 -192
- souleyez/core/cve_matcher.py +162 -148
- souleyez/core/msf_auto_mapper.py +100 -83
- souleyez/core/msf_chain_engine.py +294 -256
- souleyez/core/msf_database.py +153 -70
- souleyez/core/msf_integration.py +679 -673
- souleyez/core/msf_rpc_client.py +40 -42
- souleyez/core/msf_rpc_manager.py +77 -79
- souleyez/core/msf_sync_manager.py +241 -181
- souleyez/core/network_utils.py +22 -15
- souleyez/core/parser_handler.py +34 -25
- souleyez/core/pending_chains.py +114 -63
- souleyez/core/templates.py +158 -107
- souleyez/core/tool_chaining.py +9564 -2881
- souleyez/core/version_utils.py +79 -94
- souleyez/core/vuln_correlation.py +136 -89
- souleyez/core/web_utils.py +33 -32
- souleyez/data/wordlists/ad_users.txt +378 -0
- souleyez/data/wordlists/api_endpoints_large.txt +769 -0
- souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
- souleyez/data/wordlists/lfi_payloads.txt +82 -0
- souleyez/data/wordlists/passwords_brute.txt +1548 -0
- souleyez/data/wordlists/passwords_crack.txt +2479 -0
- souleyez/data/wordlists/passwords_spray.txt +386 -0
- souleyez/data/wordlists/subdomains_large.txt +5057 -0
- souleyez/data/wordlists/usernames_common.txt +694 -0
- souleyez/data/wordlists/web_dirs_large.txt +4769 -0
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +12 -17
- souleyez/detection/mitre_mappings.py +61 -55
- souleyez/detection/validator.py +97 -86
- souleyez/devtools.py +23 -10
- souleyez/docs/README.md +4 -4
- souleyez/docs/api-reference/cli-commands.md +2 -2
- souleyez/docs/developer-guide/adding-new-tools.md +562 -0
- souleyez/docs/user-guide/auto-chaining.md +30 -8
- souleyez/docs/user-guide/getting-started.md +1 -1
- souleyez/docs/user-guide/installation.md +26 -3
- souleyez/docs/user-guide/metasploit-integration.md +2 -2
- souleyez/docs/user-guide/rbac.md +1 -1
- souleyez/docs/user-guide/scope-management.md +1 -1
- souleyez/docs/user-guide/siem-integration.md +1 -1
- souleyez/docs/user-guide/tools-reference.md +1 -8
- souleyez/docs/user-guide/worker-management.md +1 -1
- souleyez/engine/background.py +1239 -535
- souleyez/engine/base.py +4 -1
- souleyez/engine/job_status.py +17 -49
- souleyez/engine/log_sanitizer.py +103 -77
- souleyez/engine/manager.py +38 -7
- souleyez/engine/result_handler.py +2200 -1550
- souleyez/engine/worker_manager.py +50 -41
- souleyez/export/evidence_bundle.py +72 -62
- souleyez/feature_flags/features.py +16 -20
- souleyez/feature_flags.py +5 -9
- souleyez/handlers/__init__.py +11 -0
- souleyez/handlers/base.py +188 -0
- souleyez/handlers/bash_handler.py +277 -0
- souleyez/handlers/bloodhound_handler.py +243 -0
- souleyez/handlers/certipy_handler.py +311 -0
- souleyez/handlers/crackmapexec_handler.py +486 -0
- souleyez/handlers/dnsrecon_handler.py +344 -0
- souleyez/handlers/enum4linux_handler.py +400 -0
- souleyez/handlers/evil_winrm_handler.py +493 -0
- souleyez/handlers/ffuf_handler.py +815 -0
- souleyez/handlers/gobuster_handler.py +1114 -0
- souleyez/handlers/gpp_extract_handler.py +334 -0
- souleyez/handlers/hashcat_handler.py +444 -0
- souleyez/handlers/hydra_handler.py +564 -0
- souleyez/handlers/impacket_getuserspns_handler.py +343 -0
- souleyez/handlers/impacket_psexec_handler.py +222 -0
- souleyez/handlers/impacket_secretsdump_handler.py +426 -0
- souleyez/handlers/john_handler.py +286 -0
- souleyez/handlers/katana_handler.py +425 -0
- souleyez/handlers/kerbrute_handler.py +298 -0
- souleyez/handlers/ldapsearch_handler.py +636 -0
- souleyez/handlers/lfi_extract_handler.py +464 -0
- souleyez/handlers/msf_auxiliary_handler.py +409 -0
- souleyez/handlers/msf_exploit_handler.py +380 -0
- souleyez/handlers/nikto_handler.py +413 -0
- souleyez/handlers/nmap_handler.py +821 -0
- souleyez/handlers/nuclei_handler.py +359 -0
- souleyez/handlers/nxc_handler.py +417 -0
- souleyez/handlers/rdp_sec_check_handler.py +353 -0
- souleyez/handlers/registry.py +292 -0
- souleyez/handlers/responder_handler.py +232 -0
- souleyez/handlers/service_explorer_handler.py +434 -0
- souleyez/handlers/smbclient_handler.py +344 -0
- souleyez/handlers/smbmap_handler.py +510 -0
- souleyez/handlers/smbpasswd_handler.py +296 -0
- souleyez/handlers/sqlmap_handler.py +1116 -0
- souleyez/handlers/theharvester_handler.py +601 -0
- souleyez/handlers/web_login_test_handler.py +327 -0
- souleyez/handlers/whois_handler.py +277 -0
- souleyez/handlers/wpscan_handler.py +554 -0
- souleyez/history.py +32 -16
- souleyez/importers/msf_importer.py +106 -75
- souleyez/importers/smart_importer.py +208 -147
- souleyez/integrations/siem/__init__.py +10 -10
- souleyez/integrations/siem/base.py +17 -18
- souleyez/integrations/siem/elastic.py +108 -122
- souleyez/integrations/siem/factory.py +207 -80
- souleyez/integrations/siem/googlesecops.py +146 -154
- souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
- souleyez/integrations/siem/sentinel.py +107 -109
- souleyez/integrations/siem/splunk.py +246 -212
- souleyez/integrations/siem/wazuh.py +65 -71
- souleyez/integrations/wazuh/__init__.py +5 -5
- souleyez/integrations/wazuh/client.py +70 -93
- souleyez/integrations/wazuh/config.py +85 -57
- souleyez/integrations/wazuh/host_mapper.py +28 -36
- souleyez/integrations/wazuh/sync.py +78 -68
- souleyez/intelligence/__init__.py +4 -5
- souleyez/intelligence/correlation_analyzer.py +309 -295
- souleyez/intelligence/exploit_knowledge.py +661 -623
- souleyez/intelligence/exploit_suggestions.py +159 -139
- souleyez/intelligence/gap_analyzer.py +132 -97
- souleyez/intelligence/gap_detector.py +251 -214
- souleyez/intelligence/sensitive_tables.py +266 -129
- souleyez/intelligence/service_parser.py +137 -123
- souleyez/intelligence/surface_analyzer.py +407 -268
- souleyez/intelligence/target_parser.py +159 -162
- souleyez/licensing/__init__.py +6 -6
- souleyez/licensing/validator.py +17 -19
- souleyez/log_config.py +79 -54
- souleyez/main.py +1505 -687
- souleyez/migrations/fix_job_counter.py +16 -14
- souleyez/parsers/bloodhound_parser.py +41 -39
- souleyez/parsers/crackmapexec_parser.py +178 -111
- souleyez/parsers/dalfox_parser.py +72 -77
- souleyez/parsers/dnsrecon_parser.py +103 -91
- souleyez/parsers/enum4linux_parser.py +183 -153
- souleyez/parsers/ffuf_parser.py +29 -25
- souleyez/parsers/gobuster_parser.py +301 -41
- souleyez/parsers/hashcat_parser.py +324 -79
- souleyez/parsers/http_fingerprint_parser.py +350 -103
- souleyez/parsers/hydra_parser.py +131 -111
- souleyez/parsers/impacket_parser.py +231 -178
- souleyez/parsers/john_parser.py +98 -86
- souleyez/parsers/katana_parser.py +316 -0
- souleyez/parsers/msf_parser.py +943 -498
- souleyez/parsers/nikto_parser.py +346 -65
- souleyez/parsers/nmap_parser.py +262 -174
- souleyez/parsers/nuclei_parser.py +40 -44
- souleyez/parsers/responder_parser.py +26 -26
- souleyez/parsers/searchsploit_parser.py +74 -74
- souleyez/parsers/service_explorer_parser.py +279 -0
- souleyez/parsers/smbmap_parser.py +180 -124
- souleyez/parsers/sqlmap_parser.py +434 -308
- souleyez/parsers/theharvester_parser.py +75 -57
- souleyez/parsers/whois_parser.py +135 -94
- souleyez/parsers/wpscan_parser.py +278 -190
- souleyez/plugins/afp.py +44 -36
- souleyez/plugins/afp_brute.py +114 -46
- souleyez/plugins/ard.py +48 -37
- souleyez/plugins/bloodhound.py +95 -61
- souleyez/plugins/certipy.py +303 -0
- souleyez/plugins/crackmapexec.py +186 -85
- souleyez/plugins/dalfox.py +120 -59
- souleyez/plugins/dns_hijack.py +146 -41
- souleyez/plugins/dnsrecon.py +97 -61
- souleyez/plugins/enum4linux.py +91 -66
- souleyez/plugins/evil_winrm.py +291 -0
- souleyez/plugins/ffuf.py +166 -90
- souleyez/plugins/firmware_extract.py +133 -29
- souleyez/plugins/gobuster.py +387 -190
- souleyez/plugins/gpp_extract.py +393 -0
- souleyez/plugins/hashcat.py +100 -73
- souleyez/plugins/http_fingerprint.py +913 -267
- souleyez/plugins/hydra.py +566 -200
- souleyez/plugins/impacket_getnpusers.py +117 -69
- souleyez/plugins/impacket_psexec.py +84 -64
- souleyez/plugins/impacket_secretsdump.py +103 -69
- souleyez/plugins/impacket_smbclient.py +89 -75
- souleyez/plugins/john.py +86 -69
- souleyez/plugins/katana.py +313 -0
- souleyez/plugins/kerbrute.py +237 -0
- souleyez/plugins/lfi_extract.py +541 -0
- souleyez/plugins/macos_ssh.py +117 -48
- souleyez/plugins/mdns.py +35 -30
- souleyez/plugins/msf_auxiliary.py +253 -130
- souleyez/plugins/msf_exploit.py +239 -161
- souleyez/plugins/nikto.py +134 -78
- souleyez/plugins/nmap.py +275 -91
- souleyez/plugins/nuclei.py +180 -89
- souleyez/plugins/nxc.py +285 -0
- souleyez/plugins/plugin_base.py +35 -36
- souleyez/plugins/plugin_template.py +13 -5
- souleyez/plugins/rdp_sec_check.py +130 -0
- souleyez/plugins/responder.py +112 -71
- souleyez/plugins/router_http_brute.py +76 -65
- souleyez/plugins/router_ssh_brute.py +118 -41
- souleyez/plugins/router_telnet_brute.py +124 -42
- souleyez/plugins/routersploit.py +91 -59
- souleyez/plugins/routersploit_exploit.py +77 -55
- souleyez/plugins/searchsploit.py +91 -77
- souleyez/plugins/service_explorer.py +1160 -0
- souleyez/plugins/smbmap.py +122 -72
- souleyez/plugins/smbpasswd.py +215 -0
- souleyez/plugins/sqlmap.py +301 -113
- souleyez/plugins/theharvester.py +127 -75
- souleyez/plugins/tr069.py +79 -57
- souleyez/plugins/upnp.py +65 -47
- souleyez/plugins/upnp_abuse.py +73 -55
- souleyez/plugins/vnc_access.py +129 -42
- souleyez/plugins/vnc_brute.py +109 -38
- souleyez/plugins/web_login_test.py +417 -0
- souleyez/plugins/whois.py +77 -58
- souleyez/plugins/wpscan.py +219 -69
- souleyez/reporting/__init__.py +2 -1
- souleyez/reporting/attack_chain.py +411 -346
- souleyez/reporting/charts.py +436 -501
- souleyez/reporting/compliance_mappings.py +334 -201
- souleyez/reporting/detection_report.py +126 -125
- souleyez/reporting/formatters.py +828 -591
- souleyez/reporting/generator.py +386 -302
- souleyez/reporting/metrics.py +72 -75
- souleyez/scanner.py +35 -29
- souleyez/security/__init__.py +37 -11
- souleyez/security/scope_validator.py +175 -106
- souleyez/security/validation.py +237 -149
- souleyez/security.py +22 -6
- souleyez/storage/credentials.py +247 -186
- souleyez/storage/crypto.py +296 -129
- souleyez/storage/database.py +73 -50
- souleyez/storage/db.py +58 -36
- souleyez/storage/deliverable_evidence.py +177 -128
- souleyez/storage/deliverable_exporter.py +282 -246
- souleyez/storage/deliverable_templates.py +134 -116
- souleyez/storage/deliverables.py +135 -130
- souleyez/storage/engagements.py +109 -56
- souleyez/storage/evidence.py +181 -152
- souleyez/storage/execution_log.py +31 -17
- souleyez/storage/exploit_attempts.py +93 -57
- souleyez/storage/exploits.py +67 -36
- souleyez/storage/findings.py +48 -61
- souleyez/storage/hosts.py +176 -144
- souleyez/storage/migrate_to_engagements.py +43 -19
- souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
- souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
- souleyez/storage/migrations/_003_add_execution_log.py +14 -8
- souleyez/storage/migrations/_005_screenshots.py +13 -5
- souleyez/storage/migrations/_006_deliverables.py +13 -5
- souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
- souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
- souleyez/storage/migrations/_010_evidence_linking.py +17 -10
- souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
- souleyez/storage/migrations/_012_team_collaboration.py +34 -21
- souleyez/storage/migrations/_013_add_host_tags.py +12 -6
- souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
- souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
- souleyez/storage/migrations/_016_add_domain_field.py +10 -4
- souleyez/storage/migrations/_017_msf_sessions.py +16 -8
- souleyez/storage/migrations/_018_add_osint_target.py +10 -6
- souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
- souleyez/storage/migrations/_020_add_rbac.py +36 -15
- souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
- souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
- souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
- souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
- souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
- souleyez/storage/migrations/__init__.py +26 -26
- souleyez/storage/migrations/migration_manager.py +19 -19
- souleyez/storage/msf_sessions.py +100 -65
- souleyez/storage/osint.py +17 -24
- souleyez/storage/recommendation_engine.py +269 -235
- souleyez/storage/screenshots.py +33 -32
- souleyez/storage/smb_shares.py +136 -92
- souleyez/storage/sqlmap_data.py +183 -128
- souleyez/storage/team_collaboration.py +135 -141
- souleyez/storage/timeline_tracker.py +122 -94
- souleyez/storage/wazuh_vulns.py +64 -66
- souleyez/storage/web_paths.py +33 -37
- souleyez/testing/credential_tester.py +221 -205
- souleyez/ui/__init__.py +1 -1
- souleyez/ui/ai_quotes.py +12 -12
- souleyez/ui/attack_surface.py +2439 -1516
- souleyez/ui/chain_rules_view.py +914 -382
- souleyez/ui/correlation_view.py +312 -230
- souleyez/ui/dashboard.py +2382 -1130
- souleyez/ui/deliverables_view.py +148 -62
- souleyez/ui/design_system.py +13 -13
- souleyez/ui/errors.py +49 -49
- souleyez/ui/evidence_linking_view.py +284 -179
- souleyez/ui/evidence_vault.py +393 -285
- souleyez/ui/exploit_suggestions_view.py +555 -349
- souleyez/ui/export_view.py +100 -66
- souleyez/ui/gap_analysis_view.py +315 -171
- souleyez/ui/help_system.py +105 -97
- souleyez/ui/intelligence_view.py +436 -293
- souleyez/ui/interactive.py +23034 -10679
- souleyez/ui/interactive_selector.py +75 -68
- souleyez/ui/log_formatter.py +47 -39
- souleyez/ui/menu_components.py +22 -13
- souleyez/ui/msf_auxiliary_menu.py +184 -133
- souleyez/ui/pending_chains_view.py +336 -172
- souleyez/ui/progress_indicators.py +5 -3
- souleyez/ui/recommendations_view.py +195 -137
- souleyez/ui/rule_builder.py +343 -225
- souleyez/ui/setup_wizard.py +678 -284
- souleyez/ui/shortcuts.py +217 -165
- souleyez/ui/splunk_gap_analysis_view.py +452 -270
- souleyez/ui/splunk_vulns_view.py +139 -86
- souleyez/ui/team_dashboard.py +498 -335
- souleyez/ui/template_selector.py +196 -105
- souleyez/ui/terminal.py +6 -6
- souleyez/ui/timeline_view.py +198 -127
- souleyez/ui/tool_setup.py +264 -164
- souleyez/ui/tutorial.py +202 -72
- souleyez/ui/tutorial_state.py +40 -40
- souleyez/ui/wazuh_vulns_view.py +235 -141
- souleyez/ui/wordlist_browser.py +260 -107
- souleyez/ui.py +464 -312
- souleyez/utils/tool_checker.py +427 -367
- souleyez/utils.py +33 -29
- souleyez/wordlists.py +134 -167
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/METADATA +2 -2
- souleyez-3.0.0.dist-info/RECORD +443 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
- souleyez-2.43.29.dist-info/RECORD +0 -379
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
# Adding New Tools to SoulEyez
|
|
2
|
+
|
|
3
|
+
This guide covers the complete process for integrating a new external tool into SoulEyez. Follow ALL steps to ensure proper integration.
|
|
4
|
+
|
|
5
|
+
## Quick Checklist
|
|
6
|
+
|
|
7
|
+
Use this checklist when adding a new tool:
|
|
8
|
+
|
|
9
|
+
- [ ] 1. Create plugin file (`souleyez/plugins/<tool>.py`)
|
|
10
|
+
- [ ] 2. Create handler file (`souleyez/handlers/<tool>_handler.py`)
|
|
11
|
+
- [ ] 3. Register handler in registry (`souleyez/handlers/registry.py`)
|
|
12
|
+
- [ ] 4. Add to tool checker (`souleyez/utils/tool_checker.py`)
|
|
13
|
+
- [ ] 5. Add to interactive UI menu (`souleyez/ui/interactive.py`)
|
|
14
|
+
- [ ] 6. Add chain rules if applicable (`souleyez/core/tool_chaining.py`)
|
|
15
|
+
- [ ] 7. Test the integration
|
|
16
|
+
- [ ] 8. Commit and push
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Step 1: Create the Plugin
|
|
21
|
+
|
|
22
|
+
**File:** `souleyez/plugins/<tool_name>.py`
|
|
23
|
+
|
|
24
|
+
The plugin defines how to build and execute the tool command.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
#!/usr/bin/env python3
|
|
28
|
+
"""
|
|
29
|
+
souleyez.plugins.<tool_name> - Brief description
|
|
30
|
+
"""
|
|
31
|
+
import subprocess
|
|
32
|
+
import time
|
|
33
|
+
from typing import List
|
|
34
|
+
|
|
35
|
+
from .plugin_base import PluginBase
|
|
36
|
+
|
|
37
|
+
HELP = {
|
|
38
|
+
"name": "Tool Display Name",
|
|
39
|
+
"description": (
|
|
40
|
+
"Multi-line description of what the tool does.\n\n"
|
|
41
|
+
"When to use this tool:\n"
|
|
42
|
+
"- Use case 1\n"
|
|
43
|
+
"- Use case 2\n"
|
|
44
|
+
),
|
|
45
|
+
"usage": "souleyez jobs enqueue <tool> <target> --args \"<arguments>\"",
|
|
46
|
+
"examples": [
|
|
47
|
+
"souleyez jobs enqueue <tool> 10.0.0.1 --args \"arg1 arg2\"",
|
|
48
|
+
],
|
|
49
|
+
"flags": [
|
|
50
|
+
["--flag1", "Description of flag1"],
|
|
51
|
+
["--flag2", "Description of flag2"],
|
|
52
|
+
],
|
|
53
|
+
"preset_categories": {
|
|
54
|
+
"category_name": [
|
|
55
|
+
{
|
|
56
|
+
"name": "Preset Name",
|
|
57
|
+
"args": ["arg1", "arg2", "<target>"],
|
|
58
|
+
"desc": "What this preset does"
|
|
59
|
+
},
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"presets": [] # Auto-populated from preset_categories
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Flatten presets
|
|
66
|
+
for category_presets in HELP['preset_categories'].values():
|
|
67
|
+
HELP['presets'].extend(category_presets)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ToolNamePlugin(PluginBase):
|
|
71
|
+
name = "Tool Display Name"
|
|
72
|
+
tool = "tool_command" # The actual CLI command
|
|
73
|
+
category = "category_name" # reconnaissance, scanning, exploitation, etc.
|
|
74
|
+
HELP = HELP
|
|
75
|
+
|
|
76
|
+
def build_command(self, target: str, args: List[str] = None, label: str = "", log_path: str = None):
|
|
77
|
+
"""Build command for background execution."""
|
|
78
|
+
args = args or []
|
|
79
|
+
args = [arg.replace("<target>", target) for arg in args]
|
|
80
|
+
|
|
81
|
+
cmd = ["tool_command"]
|
|
82
|
+
cmd.extend(args)
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
'cmd': cmd,
|
|
86
|
+
'timeout': 1800 # 30 minutes default
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
def run(self, target: str, args: List[str] = None, label: str = "", log_path: str = None) -> int:
|
|
90
|
+
"""Execute tool and write output to log_path."""
|
|
91
|
+
args = args or []
|
|
92
|
+
args = [arg.replace("<target>", target) for arg in args]
|
|
93
|
+
|
|
94
|
+
cmd = ["tool_command"]
|
|
95
|
+
cmd.extend(args)
|
|
96
|
+
|
|
97
|
+
if not log_path:
|
|
98
|
+
try:
|
|
99
|
+
proc = subprocess.run(cmd, capture_output=True, timeout=600, check=False)
|
|
100
|
+
return proc.returncode
|
|
101
|
+
except Exception:
|
|
102
|
+
return 1
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
with open(log_path, "w", encoding="utf-8", errors="replace") as fh:
|
|
106
|
+
fh.write(f"=== Plugin: ToolName ===\n")
|
|
107
|
+
fh.write(f"Target: {target}\n")
|
|
108
|
+
fh.write(f"Args: {args}\n")
|
|
109
|
+
fh.write(f"Command: {' '.join(cmd)}\n\n")
|
|
110
|
+
|
|
111
|
+
proc = subprocess.run(cmd, capture_output=True, timeout=600, check=False, text=True)
|
|
112
|
+
|
|
113
|
+
with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
|
|
114
|
+
if proc.stdout:
|
|
115
|
+
fh.write(proc.stdout)
|
|
116
|
+
if proc.stderr:
|
|
117
|
+
fh.write(f"\n{proc.stderr}")
|
|
118
|
+
fh.write(f"\n\nExit Code: {proc.returncode}\n")
|
|
119
|
+
|
|
120
|
+
return proc.returncode
|
|
121
|
+
|
|
122
|
+
except subprocess.TimeoutExpired:
|
|
123
|
+
with open(log_path, "a") as fh:
|
|
124
|
+
fh.write("\n\nERROR: Command timed out\n")
|
|
125
|
+
return 124
|
|
126
|
+
except FileNotFoundError:
|
|
127
|
+
with open(log_path, "w") as fh:
|
|
128
|
+
fh.write(f"ERROR: {cmd[0]} not found in PATH\n")
|
|
129
|
+
return 127
|
|
130
|
+
except Exception as e:
|
|
131
|
+
with open(log_path, "a") as fh:
|
|
132
|
+
fh.write(f"\n\nERROR: {e}\n")
|
|
133
|
+
return 1
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
plugin = ToolNamePlugin()
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Key Points:**
|
|
140
|
+
- Plugin is auto-discovered by `souleyez/engine/loader.py` via `pkgutil.iter_modules()`
|
|
141
|
+
- Must have a `plugin` attribute at module level
|
|
142
|
+
- The `tool` attribute should match the CLI command name
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Step 2: Create the Handler
|
|
147
|
+
|
|
148
|
+
**File:** `souleyez/handlers/<tool_name>_handler.py`
|
|
149
|
+
|
|
150
|
+
The handler parses tool output and displays results.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
#!/usr/bin/env python3
|
|
154
|
+
"""
|
|
155
|
+
Handler for <tool_name>.
|
|
156
|
+
"""
|
|
157
|
+
import logging
|
|
158
|
+
import os
|
|
159
|
+
import re
|
|
160
|
+
from typing import Any, Dict, Optional
|
|
161
|
+
|
|
162
|
+
import click
|
|
163
|
+
|
|
164
|
+
from souleyez.handlers.base import BaseToolHandler
|
|
165
|
+
|
|
166
|
+
logger = logging.getLogger(__name__)
|
|
167
|
+
|
|
168
|
+
STATUS_DONE = 'done'
|
|
169
|
+
STATUS_ERROR = 'error'
|
|
170
|
+
STATUS_WARNING = 'warning'
|
|
171
|
+
STATUS_NO_RESULTS = 'no_results'
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class ToolNameHandler(BaseToolHandler):
|
|
175
|
+
"""Handler for tool_name."""
|
|
176
|
+
|
|
177
|
+
tool_name = "tool_name" # Must match plugin's tool attribute
|
|
178
|
+
display_name = "Tool Display Name"
|
|
179
|
+
|
|
180
|
+
# Enable the handlers you implement
|
|
181
|
+
has_error_handler = True
|
|
182
|
+
has_warning_handler = True
|
|
183
|
+
has_no_results_handler = True
|
|
184
|
+
has_done_handler = True
|
|
185
|
+
|
|
186
|
+
# Regex patterns for parsing output
|
|
187
|
+
RESULT_PATTERN = r'RESULT:\s*(\S+)'
|
|
188
|
+
ERROR_PATTERNS = [
|
|
189
|
+
(r'connection refused', 'Connection refused'),
|
|
190
|
+
(r'timeout', 'Connection timed out'),
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
def parse_job(
|
|
194
|
+
self,
|
|
195
|
+
engagement_id: int,
|
|
196
|
+
log_path: str,
|
|
197
|
+
job: Dict[str, Any],
|
|
198
|
+
host_manager: Optional[Any] = None,
|
|
199
|
+
findings_manager: Optional[Any] = None,
|
|
200
|
+
credentials_manager: Optional[Any] = None,
|
|
201
|
+
) -> Dict[str, Any]:
|
|
202
|
+
"""Parse tool results from log file."""
|
|
203
|
+
try:
|
|
204
|
+
target = job.get('target', '')
|
|
205
|
+
|
|
206
|
+
if not log_path or not os.path.exists(log_path):
|
|
207
|
+
return {
|
|
208
|
+
'tool': self.tool_name,
|
|
209
|
+
'status': STATUS_ERROR,
|
|
210
|
+
'error': 'Log file not found'
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
214
|
+
log_content = f.read()
|
|
215
|
+
|
|
216
|
+
# Check for errors first
|
|
217
|
+
for pattern, error_msg in self.ERROR_PATTERNS:
|
|
218
|
+
if re.search(pattern, log_content, re.IGNORECASE):
|
|
219
|
+
return {
|
|
220
|
+
'tool': self.tool_name,
|
|
221
|
+
'status': STATUS_ERROR,
|
|
222
|
+
'target': target,
|
|
223
|
+
'error': error_msg
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
# Parse results
|
|
227
|
+
results = re.findall(self.RESULT_PATTERN, log_content)
|
|
228
|
+
|
|
229
|
+
if results:
|
|
230
|
+
# Store findings/credentials if applicable
|
|
231
|
+
# Example: Store credentials
|
|
232
|
+
# if credentials_manager and host_manager:
|
|
233
|
+
# host = host_manager.get_host_by_ip(engagement_id, target)
|
|
234
|
+
# if host:
|
|
235
|
+
# credentials_manager.add_credential(...)
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
'tool': self.tool_name,
|
|
239
|
+
'status': STATUS_DONE,
|
|
240
|
+
'target': target,
|
|
241
|
+
'results': results,
|
|
242
|
+
'results_found': len(results),
|
|
243
|
+
# Add counts for job summary display:
|
|
244
|
+
# 'users_found': len(users),
|
|
245
|
+
# 'credentials_added': len(credentials),
|
|
246
|
+
# 'hosts_added': len(hosts),
|
|
247
|
+
# 'findings_added': len(findings),
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
'tool': self.tool_name,
|
|
252
|
+
'status': STATUS_NO_RESULTS,
|
|
253
|
+
'target': target
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
except Exception as e:
|
|
257
|
+
logger.error(f"Error parsing {self.tool_name} job: {e}")
|
|
258
|
+
return {'tool': self.tool_name, 'status': STATUS_ERROR, 'error': str(e)}
|
|
259
|
+
|
|
260
|
+
def display_done(
|
|
261
|
+
self,
|
|
262
|
+
job: Dict[str, Any],
|
|
263
|
+
log_path: str,
|
|
264
|
+
show_all: bool = False,
|
|
265
|
+
show_passwords: bool = False,
|
|
266
|
+
) -> None:
|
|
267
|
+
"""Display successful results."""
|
|
268
|
+
click.echo()
|
|
269
|
+
click.echo(click.style("=" * 70, fg='green'))
|
|
270
|
+
click.echo(click.style(f"{self.display_name.upper()} SUCCESSFUL", fg='green', bold=True))
|
|
271
|
+
click.echo(click.style("=" * 70, fg='green'))
|
|
272
|
+
click.echo()
|
|
273
|
+
|
|
274
|
+
# Parse and display results from log
|
|
275
|
+
try:
|
|
276
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
277
|
+
log_content = f.read()
|
|
278
|
+
|
|
279
|
+
results = re.findall(self.RESULT_PATTERN, log_content)
|
|
280
|
+
if results:
|
|
281
|
+
click.echo(click.style(f" RESULTS ({len(results)})", bold=True, fg='cyan'))
|
|
282
|
+
for result in results:
|
|
283
|
+
click.echo(f" {click.style(result, fg='green')}")
|
|
284
|
+
except Exception as e:
|
|
285
|
+
click.echo(f" Error reading log: {e}")
|
|
286
|
+
|
|
287
|
+
click.echo()
|
|
288
|
+
|
|
289
|
+
def display_error(
|
|
290
|
+
self,
|
|
291
|
+
job: Dict[str, Any],
|
|
292
|
+
log_path: str,
|
|
293
|
+
show_all: bool = False,
|
|
294
|
+
) -> None:
|
|
295
|
+
"""Display error results."""
|
|
296
|
+
click.echo()
|
|
297
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
298
|
+
click.echo(click.style(f"{self.display_name.upper()} FAILED", fg='red', bold=True))
|
|
299
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
300
|
+
click.echo()
|
|
301
|
+
|
|
302
|
+
try:
|
|
303
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
304
|
+
log_content = f.read()
|
|
305
|
+
|
|
306
|
+
for pattern, error_msg in self.ERROR_PATTERNS:
|
|
307
|
+
if re.search(pattern, log_content, re.IGNORECASE):
|
|
308
|
+
click.echo(f" Error: {error_msg}")
|
|
309
|
+
break
|
|
310
|
+
else:
|
|
311
|
+
click.echo(f" {self.display_name} failed - check log for details")
|
|
312
|
+
except Exception:
|
|
313
|
+
click.echo(" Could not read error details")
|
|
314
|
+
|
|
315
|
+
click.echo()
|
|
316
|
+
|
|
317
|
+
def display_warning(
|
|
318
|
+
self,
|
|
319
|
+
job: Dict[str, Any],
|
|
320
|
+
log_path: str,
|
|
321
|
+
show_all: bool = False,
|
|
322
|
+
) -> None:
|
|
323
|
+
"""Display warning results."""
|
|
324
|
+
click.echo()
|
|
325
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
326
|
+
click.echo(click.style(f"{self.display_name.upper()} - PARTIAL RESULTS", fg='yellow', bold=True))
|
|
327
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
328
|
+
click.echo()
|
|
329
|
+
click.echo(" Completed with warnings")
|
|
330
|
+
click.echo()
|
|
331
|
+
|
|
332
|
+
def display_no_results(
|
|
333
|
+
self,
|
|
334
|
+
job: Dict[str, Any],
|
|
335
|
+
log_path: str,
|
|
336
|
+
show_all: bool = False,
|
|
337
|
+
) -> None:
|
|
338
|
+
"""Display no results message."""
|
|
339
|
+
click.echo()
|
|
340
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
341
|
+
click.echo(click.style(f"{self.display_name.upper()} - NO RESULTS", fg='yellow', bold=True))
|
|
342
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
343
|
+
click.echo()
|
|
344
|
+
click.echo(" No results found.")
|
|
345
|
+
click.echo()
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**Key Points:**
|
|
349
|
+
- `tool_name` must match the plugin's `tool` attribute
|
|
350
|
+
- Return dict must include standard fields for job summary display:
|
|
351
|
+
- `users_found`, `credentials_added`, `hosts_added`, `findings_added`, `shares_found`
|
|
352
|
+
- The `display_*` methods are called when viewing job details
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Step 3: Register Handler in Registry
|
|
357
|
+
|
|
358
|
+
**File:** `souleyez/handlers/registry.py`
|
|
359
|
+
|
|
360
|
+
Add import in the `_discover_handlers()` method:
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
try:
|
|
364
|
+
from souleyez.handlers import tool_name_handler # noqa: F401
|
|
365
|
+
except ImportError as e:
|
|
366
|
+
logger.warning(f"Failed to import tool_name_handler: {e}")
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Step 4: Add to Tool Checker
|
|
372
|
+
|
|
373
|
+
**File:** `souleyez/utils/tool_checker.py`
|
|
374
|
+
|
|
375
|
+
Add to the appropriate category in `EXTERNAL_TOOLS`:
|
|
376
|
+
|
|
377
|
+
```python
|
|
378
|
+
EXTERNAL_TOOLS = {
|
|
379
|
+
# ... existing categories ...
|
|
380
|
+
'category_name': {
|
|
381
|
+
# ... existing tools ...
|
|
382
|
+
'tool_name': {
|
|
383
|
+
'command': 'tool_command', # CLI command to check
|
|
384
|
+
'install_kali': 'sudo apt install tool-package',
|
|
385
|
+
'install_ubuntu': 'go install github.com/author/tool@latest',
|
|
386
|
+
'install_method': 'apt', # apt, go, pipx, gem, manual
|
|
387
|
+
'description': 'Brief description for setup wizard'
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Categories:**
|
|
394
|
+
- `prerequisites` - Required system tools
|
|
395
|
+
- `reconnaissance` - OSINT and info gathering
|
|
396
|
+
- `web_scanning` - Web vulnerability scanning
|
|
397
|
+
- `exploitation` - Active exploitation
|
|
398
|
+
- `credential_attacks` - Password attacks
|
|
399
|
+
- `windows_ad` - Windows/Active Directory
|
|
400
|
+
- `router_iot` - Router and IoT testing
|
|
401
|
+
- `remote_access` - Remote access tools
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Step 5: Add to Interactive UI Menu
|
|
406
|
+
|
|
407
|
+
**File:** `souleyez/ui/interactive.py`
|
|
408
|
+
|
|
409
|
+
### 5.1 Add to Phase Subsection
|
|
410
|
+
|
|
411
|
+
Find the appropriate phase and add to its subsection tools list:
|
|
412
|
+
|
|
413
|
+
```python
|
|
414
|
+
PHASES = [
|
|
415
|
+
# ...
|
|
416
|
+
{
|
|
417
|
+
"name": "PHASE 5: POST-EXPLOITATION",
|
|
418
|
+
# ...
|
|
419
|
+
"subsections": [
|
|
420
|
+
{
|
|
421
|
+
"title": "Credential Harvesting",
|
|
422
|
+
"tools": [
|
|
423
|
+
"tool_name", # Add here
|
|
424
|
+
"existing_tool",
|
|
425
|
+
],
|
|
426
|
+
},
|
|
427
|
+
],
|
|
428
|
+
},
|
|
429
|
+
]
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 5.2 Add Description
|
|
433
|
+
|
|
434
|
+
Add to `desc_map`:
|
|
435
|
+
|
|
436
|
+
```python
|
|
437
|
+
desc_map = {
|
|
438
|
+
# ...
|
|
439
|
+
"tool_name": "Brief description shown in menu",
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 5.3 Add Display Name
|
|
444
|
+
|
|
445
|
+
Add to `name_map` inside `get_display_name()`:
|
|
446
|
+
|
|
447
|
+
```python
|
|
448
|
+
name_map = {
|
|
449
|
+
# ...
|
|
450
|
+
"tool_name": "DisplayName",
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Step 6: Add Chain Rules (Optional)
|
|
457
|
+
|
|
458
|
+
**File:** `souleyez/core/tool_chaining.py`
|
|
459
|
+
|
|
460
|
+
If the tool should be triggered automatically based on other scan results:
|
|
461
|
+
|
|
462
|
+
```python
|
|
463
|
+
CHAIN_RULES = [
|
|
464
|
+
# ...
|
|
465
|
+
{
|
|
466
|
+
'id': NEXT_ID,
|
|
467
|
+
'name': 'Descriptive Chain Name',
|
|
468
|
+
'trigger_tool': 'previous_tool',
|
|
469
|
+
'trigger_status': 'done',
|
|
470
|
+
'condition': lambda job, parse: (
|
|
471
|
+
parse.get('some_condition') and
|
|
472
|
+
other_condition
|
|
473
|
+
),
|
|
474
|
+
'action_tool': 'tool_name',
|
|
475
|
+
'action_args': ['arg1', '{placeholder}', '<target>'],
|
|
476
|
+
'description': 'When to trigger this chain',
|
|
477
|
+
'category': 'category_name',
|
|
478
|
+
},
|
|
479
|
+
]
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Placeholders:**
|
|
483
|
+
- `<target>` - Target IP/hostname
|
|
484
|
+
- `{domain}` - Discovered domain name
|
|
485
|
+
- `{base_dn}` - LDAP base DN
|
|
486
|
+
- `{username}` - Username from credentials
|
|
487
|
+
- `{password}` - Password from credentials
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Step 7: Test the Integration
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
# Test plugin discovery
|
|
495
|
+
python3 -c "
|
|
496
|
+
from souleyez.engine.loader import discover_plugins
|
|
497
|
+
plugins = discover_plugins()
|
|
498
|
+
print('tool_name' in plugins)
|
|
499
|
+
print(plugins.get('tool_name'))
|
|
500
|
+
"
|
|
501
|
+
|
|
502
|
+
# Test handler registration
|
|
503
|
+
python3 -c "
|
|
504
|
+
from souleyez.handlers.registry import get_handler
|
|
505
|
+
handler = get_handler('tool_name')
|
|
506
|
+
print(handler)
|
|
507
|
+
print(handler.has_done_handler if handler else 'NOT REGISTERED')
|
|
508
|
+
"
|
|
509
|
+
|
|
510
|
+
# Test tool checker
|
|
511
|
+
python3 -c "
|
|
512
|
+
from souleyez.utils.tool_checker import EXTERNAL_TOOLS
|
|
513
|
+
for cat, tools in EXTERNAL_TOOLS.items():
|
|
514
|
+
if 'tool_name' in tools:
|
|
515
|
+
print(f'Found in {cat}')
|
|
516
|
+
print(tools['tool_name'])
|
|
517
|
+
"
|
|
518
|
+
|
|
519
|
+
# Run the tool manually
|
|
520
|
+
souleyez jobs enqueue tool_name <target> --args "test args"
|
|
521
|
+
souleyez jobs list
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## Step 8: Commit and Push
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
git add souleyez/plugins/tool_name.py
|
|
530
|
+
git add souleyez/handlers/tool_name_handler.py
|
|
531
|
+
git add souleyez/handlers/registry.py
|
|
532
|
+
git add souleyez/utils/tool_checker.py
|
|
533
|
+
git add souleyez/ui/interactive.py
|
|
534
|
+
git add souleyez/core/tool_chaining.py # If chain rules added
|
|
535
|
+
|
|
536
|
+
git commit -m "feat: add tool_name plugin for <purpose>"
|
|
537
|
+
git push
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## Common Mistakes to Avoid
|
|
543
|
+
|
|
544
|
+
1. **Forgetting to register handler** - Tool works but results aren't parsed
|
|
545
|
+
2. **Missing from tool_checker** - Won't appear in `souleyez setup` wizard
|
|
546
|
+
3. **Missing from UI menu** - Users can't find the tool
|
|
547
|
+
4. **Wrong tool_name in handler** - Handler won't be matched to jobs
|
|
548
|
+
5. **Missing count fields in parse_job return** - Job summary won't show results
|
|
549
|
+
6. **Not testing chain rules** - Automation won't trigger
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## Files Modified When Adding a Tool
|
|
554
|
+
|
|
555
|
+
| File | Purpose |
|
|
556
|
+
|------|---------|
|
|
557
|
+
| `souleyez/plugins/<tool>.py` | Plugin (command building, execution) |
|
|
558
|
+
| `souleyez/handlers/<tool>_handler.py` | Handler (parsing, display) |
|
|
559
|
+
| `souleyez/handlers/registry.py` | Handler registration |
|
|
560
|
+
| `souleyez/utils/tool_checker.py` | Installation instructions |
|
|
561
|
+
| `souleyez/ui/interactive.py` | UI menu entry |
|
|
562
|
+
| `souleyez/core/tool_chaining.py` | Auto-chain rules (optional) |
|
|
@@ -36,9 +36,11 @@ Auto-chaining uses **trigger conditions** and **chain rules** to automatically l
|
|
|
36
36
|
```
|
|
37
37
|
Port Scan (nmap)
|
|
38
38
|
→ Discovers HTTP on port 80
|
|
39
|
-
→ Auto-chains to
|
|
40
|
-
→
|
|
41
|
-
→ Auto-chains to
|
|
39
|
+
→ Auto-chains to http_fingerprint (WAF/CDN detection)
|
|
40
|
+
→ http_fingerprint completes
|
|
41
|
+
→ Auto-chains to nikto + gobuster + nuclei
|
|
42
|
+
→ nikto finds admin panel
|
|
43
|
+
→ Auto-chains to hydra (brute force)
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
---
|
|
@@ -55,6 +57,7 @@ Each rule contains:
|
|
|
55
57
|
- **Target Tool** - Tool to run next (e.g., `nikto`, `gobuster`)
|
|
56
58
|
- **Priority** - Execution order (1-10, higher runs first)
|
|
57
59
|
- **Args Template** - Arguments to pass to target tool
|
|
60
|
+
- **Target Format** - How the target should be formatted (`ip`, `url`, or `host:port`)
|
|
58
61
|
|
|
59
62
|
### Understanding Priority
|
|
60
63
|
|
|
@@ -104,8 +107,10 @@ All 5 jobs run, but crackmapexec starts first (priority 10) and hydra starts las
|
|
|
104
107
|
|
|
105
108
|
| Trigger | Condition | Target Tool | Purpose |
|
|
106
109
|
|---------|-----------|-------------|---------|
|
|
107
|
-
| nmap | `service:http` |
|
|
108
|
-
|
|
|
110
|
+
| nmap | `service:http` | http_fingerprint | WAF/CDN/platform detection (runs first) |
|
|
111
|
+
| http_fingerprint | `has:services` | nikto | Web vulnerability scanning |
|
|
112
|
+
| http_fingerprint | `has:services` | gobuster | Directory/file enumeration |
|
|
113
|
+
| http_fingerprint | `has:services` | nuclei | CVE and misconfiguration scanning |
|
|
109
114
|
| nmap | `service:https` | sslscan | SSL/TLS configuration testing |
|
|
110
115
|
|
|
111
116
|
#### Windows/SMB Chains
|
|
@@ -400,14 +405,18 @@ Pending chains are stored in `data/chains/pending.json`:
|
|
|
400
405
|
|
|
401
406
|
```
|
|
402
407
|
1. nmap discovers HTTP/HTTPS
|
|
408
|
+
└─→ http_fingerprint (WAF/CDN/platform detection)
|
|
409
|
+
|
|
410
|
+
2. http_fingerprint completes
|
|
403
411
|
├─→ nikto (vulnerability scan)
|
|
404
412
|
├─→ gobuster (directory brute force)
|
|
413
|
+
├─→ nuclei (CVE scanning)
|
|
405
414
|
└─→ sslscan (if HTTPS)
|
|
406
415
|
|
|
407
|
-
|
|
416
|
+
3. gobuster finds /admin, /api
|
|
408
417
|
└─→ hydra (login brute force)
|
|
409
418
|
|
|
410
|
-
|
|
419
|
+
4. Form detected with SQL parameter
|
|
411
420
|
└─→ sqlmap (SQL injection testing)
|
|
412
421
|
```
|
|
413
422
|
|
|
@@ -527,6 +536,7 @@ ChainRule(
|
|
|
527
536
|
|
|
528
537
|
Available placeholders in `args_template`:
|
|
529
538
|
- `{target}` - IP address or hostname
|
|
539
|
+
- `{target_url}` - Full URL with scheme and port (e.g., `http://192.168.1.1:8080`)
|
|
530
540
|
- `{port}` - Port number from trigger
|
|
531
541
|
- `{service}` - Service name
|
|
532
542
|
- `{nuclei_tags}` - Auto-detected technology tags for Nuclei (see below)
|
|
@@ -534,6 +544,18 @@ Available placeholders in `args_template`:
|
|
|
534
544
|
- `{dc_ip}` - Domain controller IP
|
|
535
545
|
- `{subnet}` - /24 subnet of target (e.g., 10.0.0.0/24)
|
|
536
546
|
|
|
547
|
+
### Target Format
|
|
548
|
+
|
|
549
|
+
The `target_format` field controls how the target is passed to chained tools:
|
|
550
|
+
|
|
551
|
+
| Format | Example | Use Case |
|
|
552
|
+
|--------|---------|----------|
|
|
553
|
+
| `ip` (default) | `192.168.1.1` | Most tools (crackmapexec, nmap, etc.) |
|
|
554
|
+
| `url` | `http://192.168.1.1:8080` | Web tools (gobuster, nuclei, nikto) |
|
|
555
|
+
| `host:port` | `192.168.1.1:445` | Tools needing explicit port |
|
|
556
|
+
|
|
557
|
+
**Example:** When http_fingerprint triggers gobuster, the rule has `target_format=url` so gobuster receives the full URL (e.g., `http://192.168.1.1:8080`) instead of just the IP.
|
|
558
|
+
|
|
537
559
|
### Smart Scanning Features
|
|
538
560
|
|
|
539
561
|
#### Tech-Based Template Selection (Nuclei)
|
|
@@ -672,4 +694,4 @@ Auto-chaining can launch many parallel jobs:
|
|
|
672
694
|
|
|
673
695
|
---
|
|
674
696
|
|
|
675
|
-
**Last Updated:**
|
|
697
|
+
**Last Updated:** 2026-01-18 | **Version:** 2.2.0
|
|
@@ -466,7 +466,7 @@ souleyez jobs enqueue nmap 192.168.1.100 -a "-sV -sC -p 80,443,22" -l "Service S
|
|
|
466
466
|
souleyez jobs enqueue nikto http://192.168.1.100 -l "Nikto Scan"
|
|
467
467
|
|
|
468
468
|
# 2. Directory enumeration
|
|
469
|
-
souleyez jobs enqueue gobuster http://192.168.1.100 -a "dir -w /
|
|
469
|
+
souleyez jobs enqueue gobuster http://192.168.1.100 -a "dir -w data/wordlists/web_dirs_common.txt" -l "Dir Brute"
|
|
470
470
|
|
|
471
471
|
# 3. SQL injection testing
|
|
472
472
|
souleyez jobs enqueue sqlmap http://192.168.1.100/login.php?id=1 -l "SQLMap"
|
|
@@ -83,8 +83,8 @@ For developers who want to modify the source code:
|
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
85
|
# Clone the repository
|
|
86
|
-
git clone https://github.com/cyber-soul-security/
|
|
87
|
-
cd
|
|
86
|
+
git clone https://github.com/cyber-soul-security/SoulEyez.git
|
|
87
|
+
cd SoulEyez
|
|
88
88
|
|
|
89
89
|
# Install python3-venv if not already installed
|
|
90
90
|
sudo apt install python3-venv
|
|
@@ -242,6 +242,29 @@ nuclei -version
|
|
|
242
242
|
nuclei -update-templates
|
|
243
243
|
```
|
|
244
244
|
|
|
245
|
+
### Web Crawling (Katana)
|
|
246
|
+
|
|
247
|
+
**Katana** - Web crawler for parameter and endpoint discovery:
|
|
248
|
+
|
|
249
|
+
Katana crawls web applications to discover URLs with parameters, forms, and JavaScript-rendered endpoints. It's essential for finding attack surface before running injection tests.
|
|
250
|
+
|
|
251
|
+
> **Note**: Katana requires Chromium for headless browser mode (enabled by default).
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Install Go and Chromium first
|
|
255
|
+
sudo apt install -y golang-go chromium
|
|
256
|
+
|
|
257
|
+
# Install katana via Go
|
|
258
|
+
go install github.com/projectdiscovery/katana/cmd/katana@latest
|
|
259
|
+
|
|
260
|
+
# Add Go bin to PATH if not already done
|
|
261
|
+
echo 'export PATH=$PATH:~/go/bin' >> ~/.zshrc # Kali uses zsh
|
|
262
|
+
source ~/.zshrc
|
|
263
|
+
|
|
264
|
+
# Verify installation
|
|
265
|
+
katana -version
|
|
266
|
+
```
|
|
267
|
+
|
|
245
268
|
### Directory Bruteforcing
|
|
246
269
|
|
|
247
270
|
**Gobuster** - Fast directory/file & DNS brute-forcer:
|
|
@@ -544,5 +567,5 @@ See [Uninstall Guide](uninstall.md) for more options.
|
|
|
544
567
|
|
|
545
568
|
## Support
|
|
546
569
|
|
|
547
|
-
**Issues**: https://github.com/cyber-soul-security/
|
|
570
|
+
**Issues**: https://github.com/cyber-soul-security/SoulEyez/issues
|
|
548
571
|
**Security Concerns**: See [SECURITY.md](../../SECURITY.md)
|