souleyez 2.43.23__py3-none-any.whl → 2.43.26__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 -1
- souleyez/docs/README.md +2 -2
- souleyez/main.py +1 -1
- souleyez/ui/interactive.py +383 -3
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/METADATA +1 -1
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/RECORD +10 -10
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/WHEEL +0 -0
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.23.dist-info → souleyez-2.43.26.dist-info}/top_level.txt +0 -0
souleyez/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '2.43.
|
|
1
|
+
__version__ = '2.43.26'
|
|
2
2
|
|
souleyez/docs/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# SoulEyez Documentation
|
|
2
2
|
|
|
3
|
-
**Version:** 2.43.
|
|
4
|
-
**Last Updated:** January
|
|
3
|
+
**Version:** 2.43.26
|
|
4
|
+
**Last Updated:** January 13, 2026
|
|
5
5
|
**Organization:** CyberSoul Security
|
|
6
6
|
|
|
7
7
|
Welcome to the SoulEyez documentation! This documentation covers architecture, development, user guides, and operational information for the SoulEyez penetration testing platform.
|
souleyez/main.py
CHANGED
|
@@ -173,7 +173,7 @@ def _check_privileged_tools():
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
@click.group()
|
|
176
|
-
@click.version_option(version='2.43.
|
|
176
|
+
@click.version_option(version='2.43.26')
|
|
177
177
|
def cli():
|
|
178
178
|
"""SoulEyez - AI-Powered Pentesting Platform by CyberSoul Security"""
|
|
179
179
|
from souleyez.log_config import init_logging
|
souleyez/ui/interactive.py
CHANGED
|
@@ -5607,7 +5607,8 @@ def view_job_detail(job_id: int):
|
|
|
5607
5607
|
|
|
5608
5608
|
# Parse and display ffuf/gobuster results if available (only when not showing raw logs)
|
|
5609
5609
|
# Also check 'no_results' status - background parser may have missed results due to timing
|
|
5610
|
-
|
|
5610
|
+
# Also handle 'error' status to show helpful error messages
|
|
5611
|
+
if not show_raw_logs and job.get('tool') in ['ffuf', 'gobuster'] and job.get('status') in ['done', 'completed', 'no_results', 'warning', 'error'] and log_path and os.path.exists(log_path):
|
|
5611
5612
|
try:
|
|
5612
5613
|
if job.get('tool') == 'ffuf':
|
|
5613
5614
|
from souleyez.parsers.ffuf_parser import parse_ffuf
|
|
@@ -5618,8 +5619,50 @@ def view_job_detail(job_id: int):
|
|
|
5618
5619
|
log_content = f.read()
|
|
5619
5620
|
parsed = parse_gobuster_output(log_content, job.get('target', ''))
|
|
5620
5621
|
|
|
5622
|
+
# Check for timeout in log
|
|
5623
|
+
timed_out = 'timed out' in log_content.lower() or 'Command timed out' in log_content
|
|
5624
|
+
|
|
5625
|
+
# Show error summary for jobs with error status
|
|
5626
|
+
if job.get('status') == 'error':
|
|
5627
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5628
|
+
click.echo(click.style("❌ SCAN FAILED", bold=True, fg='red'))
|
|
5629
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5630
|
+
click.echo()
|
|
5631
|
+
|
|
5632
|
+
# Check if it was a timeout
|
|
5633
|
+
if timed_out:
|
|
5634
|
+
click.echo(" Scan reached timeout before completing.")
|
|
5635
|
+
click.echo()
|
|
5636
|
+
click.echo(click.style(" Possible causes:", fg='bright_black'))
|
|
5637
|
+
click.echo(click.style(" • Target is rate limiting requests", fg='bright_black'))
|
|
5638
|
+
click.echo(click.style(" • Wordlist too large for timeout window", fg='bright_black'))
|
|
5639
|
+
click.echo(click.style(" • Network latency issues", fg='bright_black'))
|
|
5640
|
+
click.echo()
|
|
5641
|
+
click.echo(click.style(" Suggestions:", fg='bright_black'))
|
|
5642
|
+
click.echo(click.style(" • Try smaller wordlist", fg='bright_black'))
|
|
5643
|
+
click.echo(click.style(" • Increase --delay between requests", fg='bright_black'))
|
|
5644
|
+
click.echo(click.style(" • Reduce threads with -t", fg='bright_black'))
|
|
5645
|
+
else:
|
|
5646
|
+
# Try to extract error message from log
|
|
5647
|
+
import re
|
|
5648
|
+
error_msg = None
|
|
5649
|
+
if 'ERROR:' in log_content:
|
|
5650
|
+
match = re.search(r'ERROR:\s*(.+?)(?:\n|$)', log_content)
|
|
5651
|
+
if match:
|
|
5652
|
+
error_msg = match.group(1).strip()
|
|
5653
|
+
|
|
5654
|
+
if error_msg:
|
|
5655
|
+
click.echo(f" Error: {error_msg}")
|
|
5656
|
+
else:
|
|
5657
|
+
click.echo(" Scan failed - see raw logs for details.")
|
|
5658
|
+
click.echo(" Press [r] to view raw logs.")
|
|
5659
|
+
|
|
5660
|
+
click.echo()
|
|
5661
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5662
|
+
click.echo()
|
|
5663
|
+
|
|
5621
5664
|
# Show warning summary for jobs with warning status
|
|
5622
|
-
|
|
5665
|
+
elif job.get('status') == 'warning':
|
|
5623
5666
|
click.echo(click.style("=" * 70, fg='yellow'))
|
|
5624
5667
|
click.echo(click.style("⚠️ SCAN WARNING", bold=True, fg='yellow'))
|
|
5625
5668
|
click.echo(click.style("=" * 70, fg='yellow'))
|
|
@@ -5826,11 +5869,86 @@ def view_job_detail(job_id: int):
|
|
|
5826
5869
|
if not show_all_paths and len(status_groups[status]) > 10:
|
|
5827
5870
|
click.echo(f" ... and {len(status_groups[status]) - 10} more")
|
|
5828
5871
|
click.echo()
|
|
5829
|
-
|
|
5872
|
+
|
|
5873
|
+
# No paths found - show helpful no_results summary
|
|
5874
|
+
elif job.get('status') in ['no_results', 'done', 'completed'] and not job.get('status') == 'error':
|
|
5875
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
5876
|
+
click.echo(click.style("GOBUSTER SCAN RESULTS", bold=True, fg='cyan'))
|
|
5877
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
5878
|
+
click.echo()
|
|
5879
|
+
click.echo(" No paths discovered.")
|
|
5880
|
+
click.echo()
|
|
5881
|
+
|
|
5882
|
+
# Extract wordlist name from args
|
|
5883
|
+
args = job.get('args', [])
|
|
5884
|
+
for i, arg in enumerate(args):
|
|
5885
|
+
if arg == '-w' and i + 1 < len(args):
|
|
5886
|
+
import os
|
|
5887
|
+
wordlist = os.path.basename(args[i + 1])
|
|
5888
|
+
click.echo(f" Wordlist: {wordlist}")
|
|
5889
|
+
break
|
|
5890
|
+
|
|
5891
|
+
# Extract extensions
|
|
5892
|
+
for i, arg in enumerate(args):
|
|
5893
|
+
if arg == '-x' and i + 1 < len(args):
|
|
5894
|
+
click.echo(f" Extensions: {args[i + 1]}")
|
|
5895
|
+
break
|
|
5896
|
+
|
|
5897
|
+
click.echo()
|
|
5898
|
+
click.echo(click.style(" This could mean:", fg='bright_black'))
|
|
5899
|
+
click.echo(click.style(" • Target has good security (no exposed paths)", fg='bright_black'))
|
|
5900
|
+
click.echo(click.style(" • Try a different/larger wordlist", fg='bright_black'))
|
|
5901
|
+
click.echo(click.style(" • Target may be blocking automated requests", fg='bright_black'))
|
|
5902
|
+
click.echo()
|
|
5903
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
5904
|
+
click.echo()
|
|
5905
|
+
|
|
5830
5906
|
except Exception as e:
|
|
5831
5907
|
# Silently fail - not critical
|
|
5832
5908
|
pass
|
|
5833
5909
|
|
|
5910
|
+
# SQLMap ERROR handler
|
|
5911
|
+
if not show_raw_logs and job.get('tool') == 'sqlmap' and job.get('status') == 'error' and log_path and os.path.exists(log_path):
|
|
5912
|
+
try:
|
|
5913
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
5914
|
+
log_text = f.read()
|
|
5915
|
+
|
|
5916
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5917
|
+
click.echo(click.style("[ERROR] SQLMAP SCAN FAILED", bold=True, fg='red'))
|
|
5918
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5919
|
+
click.echo()
|
|
5920
|
+
|
|
5921
|
+
# Check for common sqlmap errors
|
|
5922
|
+
error_msg = None
|
|
5923
|
+
if 'connection timed out' in log_text.lower():
|
|
5924
|
+
error_msg = "Connection timed out - target may be slow or filtering"
|
|
5925
|
+
elif 'unable to connect' in log_text.lower():
|
|
5926
|
+
error_msg = "Unable to connect to target URL"
|
|
5927
|
+
elif 'page not found' in log_text.lower() or '404' in log_text:
|
|
5928
|
+
error_msg = "Target page not found (404)"
|
|
5929
|
+
elif 'invalid target url' in log_text.lower():
|
|
5930
|
+
error_msg = "Invalid target URL - check the URL format"
|
|
5931
|
+
elif 'WAF/IPS' in log_text or 'firewall' in log_text.lower():
|
|
5932
|
+
error_msg = "WAF/IPS detected - try --tamper scripts"
|
|
5933
|
+
elif 'all tested parameters do not appear' in log_text.lower():
|
|
5934
|
+
error_msg = "No injectable parameters found"
|
|
5935
|
+
elif '[CRITICAL]' in log_text:
|
|
5936
|
+
match = re.search(r'\[CRITICAL\]\s*(.+?)(?:\n|$)', log_text)
|
|
5937
|
+
if match:
|
|
5938
|
+
error_msg = match.group(1).strip()[:100]
|
|
5939
|
+
|
|
5940
|
+
if error_msg:
|
|
5941
|
+
click.echo(f" {error_msg}")
|
|
5942
|
+
else:
|
|
5943
|
+
click.echo(" Scan failed - see raw logs for details (press 'r')")
|
|
5944
|
+
|
|
5945
|
+
click.echo()
|
|
5946
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
5947
|
+
click.echo()
|
|
5948
|
+
|
|
5949
|
+
except Exception:
|
|
5950
|
+
pass
|
|
5951
|
+
|
|
5834
5952
|
# Parse and display SQLMap results if available (only when not showing raw logs)
|
|
5835
5953
|
if not show_raw_logs and job.get('tool') == 'sqlmap' and job.get('status') in ['done', 'completed', 'no_results'] and log_path and os.path.exists(log_path):
|
|
5836
5954
|
try:
|
|
@@ -6303,6 +6421,78 @@ def view_job_detail(job_id: int):
|
|
|
6303
6421
|
# Parse and display Nmap results if available (only when not showing raw logs)
|
|
6304
6422
|
# ARD plugin uses nmap under the hood, so include it here
|
|
6305
6423
|
nmap_based_tools = ['nmap', 'ard']
|
|
6424
|
+
|
|
6425
|
+
# Nmap ERROR handler
|
|
6426
|
+
if not show_raw_logs and job.get('tool') in nmap_based_tools and job.get('status') == 'error' and log_path and os.path.exists(log_path):
|
|
6427
|
+
try:
|
|
6428
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
6429
|
+
log_text = f.read()
|
|
6430
|
+
|
|
6431
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6432
|
+
click.echo(click.style("[ERROR] NMAP SCAN FAILED", bold=True, fg='red'))
|
|
6433
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6434
|
+
click.echo()
|
|
6435
|
+
|
|
6436
|
+
# Check for common nmap errors
|
|
6437
|
+
error_msg = None
|
|
6438
|
+
if 'Failed to resolve' in log_text or 'Failed to open' in log_text:
|
|
6439
|
+
error_msg = "Failed to resolve target hostname"
|
|
6440
|
+
elif 'No targets were specified' in log_text:
|
|
6441
|
+
error_msg = "No valid targets specified"
|
|
6442
|
+
elif 'requires root privileges' in log_text or 'Operation not permitted' in log_text:
|
|
6443
|
+
error_msg = "Scan type requires root privileges (try sudo)"
|
|
6444
|
+
elif 'Host seems down' in log_text:
|
|
6445
|
+
error_msg = "Host appears to be down or blocking probes"
|
|
6446
|
+
elif 'timed out' in log_text.lower() or 'timeout' in log_text.lower():
|
|
6447
|
+
error_msg = "Scan timed out - target may be slow or filtering"
|
|
6448
|
+
elif 'Connection refused' in log_text:
|
|
6449
|
+
error_msg = "Connection refused - no services on target ports"
|
|
6450
|
+
|
|
6451
|
+
if error_msg:
|
|
6452
|
+
click.echo(f" {error_msg}")
|
|
6453
|
+
else:
|
|
6454
|
+
click.echo(" Scan failed - see raw logs for details (press 'r')")
|
|
6455
|
+
|
|
6456
|
+
click.echo()
|
|
6457
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6458
|
+
click.echo()
|
|
6459
|
+
|
|
6460
|
+
except Exception:
|
|
6461
|
+
pass
|
|
6462
|
+
|
|
6463
|
+
# Nmap NO_RESULTS handler
|
|
6464
|
+
if not show_raw_logs and job.get('tool') in nmap_based_tools and job.get('status') == 'no_results' and log_path and os.path.exists(log_path):
|
|
6465
|
+
try:
|
|
6466
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
6467
|
+
log_text = f.read()
|
|
6468
|
+
|
|
6469
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
6470
|
+
click.echo(click.style("NMAP SCAN RESULTS", bold=True, fg='cyan'))
|
|
6471
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
6472
|
+
click.echo()
|
|
6473
|
+
click.echo(" No open ports or services discovered.")
|
|
6474
|
+
click.echo()
|
|
6475
|
+
|
|
6476
|
+
# Check for additional context
|
|
6477
|
+
if 'Host seems down' in log_text:
|
|
6478
|
+
click.echo(click.style(" Note: Host appears to be down or blocking probes", fg='yellow'))
|
|
6479
|
+
elif 'filtered' in log_text.lower():
|
|
6480
|
+
click.echo(click.style(" Note: Ports may be filtered by firewall", fg='yellow'))
|
|
6481
|
+
|
|
6482
|
+
click.echo()
|
|
6483
|
+
click.echo(click.style(" This could mean:", fg='bright_black'))
|
|
6484
|
+
click.echo(click.style(" - All ports are closed or filtered", fg='bright_black'))
|
|
6485
|
+
click.echo(click.style(" - Host is behind a firewall", fg='bright_black'))
|
|
6486
|
+
click.echo(click.style(" - Try different scan types (-sS, -sT, -sU)", fg='bright_black'))
|
|
6487
|
+
click.echo(click.style(" - Try scanning more ports (-p-)", fg='bright_black'))
|
|
6488
|
+
click.echo()
|
|
6489
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
6490
|
+
click.echo()
|
|
6491
|
+
|
|
6492
|
+
except Exception:
|
|
6493
|
+
pass
|
|
6494
|
+
|
|
6495
|
+
# Nmap DONE/COMPLETED handler
|
|
6306
6496
|
if not show_raw_logs and job.get('tool') in nmap_based_tools and job.get('status') in ['done', 'completed'] and log_path and os.path.exists(log_path):
|
|
6307
6497
|
try:
|
|
6308
6498
|
from souleyez.parsers.nmap_parser import parse_nmap_output
|
|
@@ -6469,6 +6659,48 @@ def view_job_detail(job_id: int):
|
|
|
6469
6659
|
except Exception as e:
|
|
6470
6660
|
pass
|
|
6471
6661
|
|
|
6662
|
+
# Nuclei ERROR handler
|
|
6663
|
+
if not show_raw_logs and job.get('tool') == 'nuclei' and job.get('status') == 'error' and log_path and os.path.exists(log_path):
|
|
6664
|
+
try:
|
|
6665
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
6666
|
+
log_text = f.read()
|
|
6667
|
+
|
|
6668
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6669
|
+
click.echo(click.style("[ERROR] NUCLEI SCAN FAILED", bold=True, fg='red'))
|
|
6670
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6671
|
+
click.echo()
|
|
6672
|
+
|
|
6673
|
+
# Check for common nuclei errors
|
|
6674
|
+
error_msg = None
|
|
6675
|
+
if 'Could not run nuclei' in log_text or 'not found' in log_text.lower():
|
|
6676
|
+
error_msg = "Nuclei binary not found - check installation"
|
|
6677
|
+
elif 'no templates' in log_text.lower():
|
|
6678
|
+
error_msg = "No templates found - update nuclei templates"
|
|
6679
|
+
elif 'rate limit' in log_text.lower():
|
|
6680
|
+
error_msg = "Rate limited by target - try with -rl flag"
|
|
6681
|
+
elif 'timed out' in log_text.lower() or 'timeout' in log_text.lower():
|
|
6682
|
+
error_msg = "Scan timed out - target may be slow or filtering"
|
|
6683
|
+
elif 'Connection refused' in log_text:
|
|
6684
|
+
error_msg = "Connection refused - target may be down"
|
|
6685
|
+
elif 'could not connect' in log_text.lower():
|
|
6686
|
+
error_msg = "Could not connect to target"
|
|
6687
|
+
elif '[ERR]' in log_text or '[FTL]' in log_text:
|
|
6688
|
+
match = re.search(r'\[(ERR|FTL)\]\s*(.+?)(?:\n|$)', log_text)
|
|
6689
|
+
if match:
|
|
6690
|
+
error_msg = match.group(2).strip()[:100]
|
|
6691
|
+
|
|
6692
|
+
if error_msg:
|
|
6693
|
+
click.echo(f" {error_msg}")
|
|
6694
|
+
else:
|
|
6695
|
+
click.echo(" Scan failed - see raw logs for details (press 'r')")
|
|
6696
|
+
|
|
6697
|
+
click.echo()
|
|
6698
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
6699
|
+
click.echo()
|
|
6700
|
+
|
|
6701
|
+
except Exception:
|
|
6702
|
+
pass
|
|
6703
|
+
|
|
6472
6704
|
# Parse and display Nuclei results if available (only when not showing raw logs)
|
|
6473
6705
|
if not show_raw_logs and job.get('tool') == 'nuclei' and job.get('status') in ['done', 'completed', 'no_results'] and log_path and os.path.exists(log_path):
|
|
6474
6706
|
try:
|
|
@@ -7081,6 +7313,46 @@ def view_job_detail(job_id: int):
|
|
|
7081
7313
|
except Exception as e:
|
|
7082
7314
|
pass
|
|
7083
7315
|
|
|
7316
|
+
# Hydra ERROR handler
|
|
7317
|
+
if not show_raw_logs and job.get('tool') == 'hydra' and job.get('status') == 'error' and log_path and os.path.exists(log_path):
|
|
7318
|
+
try:
|
|
7319
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
7320
|
+
log_text = f.read()
|
|
7321
|
+
|
|
7322
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7323
|
+
click.echo(click.style("[ERROR] HYDRA ATTACK FAILED", bold=True, fg='red'))
|
|
7324
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7325
|
+
click.echo()
|
|
7326
|
+
|
|
7327
|
+
# Check for common hydra errors
|
|
7328
|
+
error_msg = None
|
|
7329
|
+
if 'Connection refused' in log_text:
|
|
7330
|
+
error_msg = "Connection refused - service may be down or port closed"
|
|
7331
|
+
elif 'could not connect' in log_text.lower():
|
|
7332
|
+
error_msg = "Could not connect to target service"
|
|
7333
|
+
elif 'timed out' in log_text.lower() or 'timeout' in log_text.lower():
|
|
7334
|
+
error_msg = "Connection timed out - target may be slow or filtering"
|
|
7335
|
+
elif 'too many connections' in log_text.lower():
|
|
7336
|
+
error_msg = "Too many connections - try reducing threads with -t"
|
|
7337
|
+
elif 'target does not support' in log_text.lower():
|
|
7338
|
+
error_msg = "Target does not support the specified protocol"
|
|
7339
|
+
elif 'ERROR' in log_text:
|
|
7340
|
+
match = re.search(r'\[ERROR\]\s*(.+?)(?:\n|$)', log_text)
|
|
7341
|
+
if match:
|
|
7342
|
+
error_msg = match.group(1).strip()[:100]
|
|
7343
|
+
|
|
7344
|
+
if error_msg:
|
|
7345
|
+
click.echo(f" {error_msg}")
|
|
7346
|
+
else:
|
|
7347
|
+
click.echo(" Attack failed - see raw logs for details (press 'r')")
|
|
7348
|
+
|
|
7349
|
+
click.echo()
|
|
7350
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7351
|
+
click.echo()
|
|
7352
|
+
|
|
7353
|
+
except Exception:
|
|
7354
|
+
pass
|
|
7355
|
+
|
|
7084
7356
|
# Parse and display Hydra results if available (only when not showing raw logs)
|
|
7085
7357
|
if not show_raw_logs and job.get('tool') == 'hydra' and job.get('status') in ['done', 'completed', 'no_results'] and log_path and os.path.exists(log_path):
|
|
7086
7358
|
try:
|
|
@@ -7391,6 +7663,114 @@ def view_job_detail(job_id: int):
|
|
|
7391
7663
|
# Silently fail - not critical
|
|
7392
7664
|
pass
|
|
7393
7665
|
|
|
7666
|
+
# =================================================================
|
|
7667
|
+
# GENERIC STATUS HANDLERS (fallbacks for tools without custom handlers)
|
|
7668
|
+
# =================================================================
|
|
7669
|
+
|
|
7670
|
+
# Tools with custom error handlers (don't show generic for these)
|
|
7671
|
+
tools_with_error_handlers = ['gobuster', 'ffuf', 'nmap', 'ard', 'hydra', 'nuclei', 'sqlmap']
|
|
7672
|
+
|
|
7673
|
+
# Tools with custom warning handlers
|
|
7674
|
+
tools_with_warning_handlers = ['gobuster', 'ffuf']
|
|
7675
|
+
|
|
7676
|
+
# Tools with custom no_results handlers
|
|
7677
|
+
tools_with_no_results_handlers = [
|
|
7678
|
+
'ffuf', 'gobuster', 'sqlmap', 'wpscan', 'dnsrecon', 'nuclei',
|
|
7679
|
+
'theharvester', 'nikto', 'whois', 'crackmapexec', 'smbmap',
|
|
7680
|
+
'enum4linux', 'hydra', 'searchsploit', 'http_fingerprint',
|
|
7681
|
+
'nmap', 'ard'
|
|
7682
|
+
]
|
|
7683
|
+
|
|
7684
|
+
current_tool = job.get('tool', '')
|
|
7685
|
+
current_status = job.get('status', '')
|
|
7686
|
+
|
|
7687
|
+
# Generic ERROR handler
|
|
7688
|
+
if current_status == 'error' and current_tool not in tools_with_error_handlers:
|
|
7689
|
+
tool_name = current_tool.upper().replace('_', ' ') if current_tool else 'UNKNOWN'
|
|
7690
|
+
click.echo()
|
|
7691
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7692
|
+
click.echo(click.style(f"[ERROR] {tool_name} SCAN FAILED", bold=True, fg='red'))
|
|
7693
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7694
|
+
click.echo()
|
|
7695
|
+
|
|
7696
|
+
# Try to extract error message from log
|
|
7697
|
+
error_msg = None
|
|
7698
|
+
if log_path and os.path.exists(log_path):
|
|
7699
|
+
try:
|
|
7700
|
+
with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
7701
|
+
log_text = f.read()
|
|
7702
|
+
|
|
7703
|
+
if 'Connection refused' in log_text:
|
|
7704
|
+
error_msg = "Connection refused - target may be down or port closed"
|
|
7705
|
+
elif 'timed out' in log_text.lower() or 'timeout' in log_text.lower():
|
|
7706
|
+
error_msg = "Command timed out - target may be slow or unresponsive"
|
|
7707
|
+
elif 'Permission denied' in log_text:
|
|
7708
|
+
error_msg = "Permission denied - may need elevated privileges"
|
|
7709
|
+
elif 'not found' in log_text.lower() and 'command' in log_text.lower():
|
|
7710
|
+
error_msg = "Tool not found - check installation"
|
|
7711
|
+
elif 'ERROR:' in log_text:
|
|
7712
|
+
match = re.search(r'ERROR:\s*(.+?)(?:\n|$)', log_text)
|
|
7713
|
+
if match:
|
|
7714
|
+
error_msg = match.group(1).strip()[:100]
|
|
7715
|
+
except:
|
|
7716
|
+
pass
|
|
7717
|
+
|
|
7718
|
+
if error_msg:
|
|
7719
|
+
click.echo(f" {error_msg}")
|
|
7720
|
+
else:
|
|
7721
|
+
click.echo(" Scan failed - see raw logs for details (press 'r')")
|
|
7722
|
+
|
|
7723
|
+
click.echo()
|
|
7724
|
+
click.echo(click.style("=" * 70, fg='red'))
|
|
7725
|
+
click.echo()
|
|
7726
|
+
|
|
7727
|
+
# Generic WARNING handler
|
|
7728
|
+
elif current_status == 'warning' and current_tool not in tools_with_warning_handlers:
|
|
7729
|
+
tool_name = current_tool.upper().replace('_', ' ') if current_tool else 'UNKNOWN'
|
|
7730
|
+
click.echo()
|
|
7731
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
7732
|
+
click.echo(click.style(f"[WARNING] {tool_name} SCAN COMPLETED WITH ISSUES", bold=True, fg='yellow'))
|
|
7733
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
7734
|
+
click.echo()
|
|
7735
|
+
click.echo(" Scan completed but encountered problems.")
|
|
7736
|
+
click.echo(" Press 'r' to view raw logs for details.")
|
|
7737
|
+
click.echo()
|
|
7738
|
+
click.echo(click.style("=" * 70, fg='yellow'))
|
|
7739
|
+
click.echo()
|
|
7740
|
+
|
|
7741
|
+
# Generic KILLED handler (no tools have custom killed handlers)
|
|
7742
|
+
elif current_status == 'killed':
|
|
7743
|
+
tool_name = current_tool.upper().replace('_', ' ') if current_tool else 'UNKNOWN'
|
|
7744
|
+
click.echo()
|
|
7745
|
+
click.echo(click.style("=" * 70, fg='magenta'))
|
|
7746
|
+
click.echo(click.style(f"[KILLED] {tool_name} SCAN TERMINATED", bold=True, fg='magenta'))
|
|
7747
|
+
click.echo(click.style("=" * 70, fg='magenta'))
|
|
7748
|
+
click.echo()
|
|
7749
|
+
click.echo(" Scan was manually stopped by user.")
|
|
7750
|
+
if log_path and os.path.exists(log_path):
|
|
7751
|
+
click.echo(" Partial results may be available in raw logs (press 'r').")
|
|
7752
|
+
click.echo()
|
|
7753
|
+
click.echo(click.style("=" * 70, fg='magenta'))
|
|
7754
|
+
click.echo()
|
|
7755
|
+
|
|
7756
|
+
# Generic NO_RESULTS handler (for tools without custom handlers)
|
|
7757
|
+
elif current_status == 'no_results' and current_tool not in tools_with_no_results_handlers:
|
|
7758
|
+
tool_name = current_tool.upper().replace('_', ' ') if current_tool else 'UNKNOWN'
|
|
7759
|
+
click.echo()
|
|
7760
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
7761
|
+
click.echo(click.style(f"{tool_name} RESULTS", bold=True, fg='cyan'))
|
|
7762
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
7763
|
+
click.echo()
|
|
7764
|
+
click.echo(" No results found.")
|
|
7765
|
+
click.echo()
|
|
7766
|
+
click.echo(click.style(" This could mean:", fg='bright_black'))
|
|
7767
|
+
click.echo(click.style(" - Target is not vulnerable to this check", fg='bright_black'))
|
|
7768
|
+
click.echo(click.style(" - Service/port is not available", fg='bright_black'))
|
|
7769
|
+
click.echo(click.style(" - Different scan options may yield results", fg='bright_black'))
|
|
7770
|
+
click.echo()
|
|
7771
|
+
click.echo(click.style("=" * 70, fg='cyan'))
|
|
7772
|
+
click.echo()
|
|
7773
|
+
|
|
7394
7774
|
click.echo()
|
|
7395
7775
|
|
|
7396
7776
|
# Actions menu
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: souleyez
|
|
3
|
-
Version: 2.43.
|
|
3
|
+
Version: 2.43.26
|
|
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>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
souleyez/__init__.py,sha256=
|
|
1
|
+
souleyez/__init__.py,sha256=W7_ihmKebGDg5wOXze4pirFaaBA2KbGP_fIT3exGUTg,25
|
|
2
2
|
souleyez/config.py,sha256=av357I3GYRWAklv8Dto-9-5Db699Wq5znez7zo7241Q,11595
|
|
3
3
|
souleyez/devtools.py,sha256=rptmUY4a5eVvYjdEc6273MSagL-D9xibPOFgohVqUno,3508
|
|
4
4
|
souleyez/feature_flags.py,sha256=mo6YAq07lc6sR3lEFKmIwTKxXZ2JPxwa5X97uR_mu50,4642
|
|
5
5
|
souleyez/history.py,sha256=gzs5I_j-3OigIP6yfmBChdqxaFmyUIxvTpzWUPe_Q6c,2853
|
|
6
6
|
souleyez/log_config.py,sha256=MMhPAJOqgXDfuE-xm5g0RxAfWndcmbhFHvIEMm1a_Wo,5830
|
|
7
|
-
souleyez/main.py,sha256=
|
|
7
|
+
souleyez/main.py,sha256=ofrfuhN8kGrX6zj9Za9oHKTKaI1fT_DeCY0MIaoNkX4,129101
|
|
8
8
|
souleyez/scanner.py,sha256=U3IWHRrJ5aQ32dSHiVAHB60w1R_z0E0QxfM99msYNlw,3124
|
|
9
9
|
souleyez/security.py,sha256=S84m1QmnKz_6NgH2I6IBIAorMHxRPNYVFSnks5xjihQ,2479
|
|
10
10
|
souleyez/ui.py,sha256=15pfsqoDPnojAqr5S0TZHJE2ZkSHzkHpNVfVvsRj66A,34301
|
|
@@ -104,7 +104,7 @@ souleyez/detection/__init__.py,sha256=QIhvXjFdjrquQ6A0VQ7GZQkK_EXB59t8Dv9PKXhEUe
|
|
|
104
104
|
souleyez/detection/attack_signatures.py,sha256=akgWwiIkh6WYnghCuLhRV0y6FS0SQ0caGF8tZUc49oA,6965
|
|
105
105
|
souleyez/detection/mitre_mappings.py,sha256=xejE80YK-g8kKaeQoo-vBl8P3t8RTTItbfN0NaVZw6s,20558
|
|
106
106
|
souleyez/detection/validator.py,sha256=-AJ7QSJ3-6jFKLnPG_Rc34IXyF4JPyI82BFUgTA9zw0,15641
|
|
107
|
-
souleyez/docs/README.md,sha256=
|
|
107
|
+
souleyez/docs/README.md,sha256=n8Xwj9zC-sjYh3ehIgjZBDCl_k92dhLyjJBMkezu6Aw,7188
|
|
108
108
|
souleyez/docs/api-reference/cli-commands.md,sha256=lTLFnILN3YRVdqCaag7WgsYXfDGglb1TuPexkxDsVdE,12917
|
|
109
109
|
souleyez/docs/api-reference/engagement-api.md,sha256=nd-EvQMtiJrobg2bzFEADp853HP1Uhb9dmgok0_-neE,11672
|
|
110
110
|
souleyez/docs/api-reference/integration-guide.md,sha256=c96uX79ukHyYotLa54wZ20Kx-EUZnrKegTeGkfLD-pw,16285
|
|
@@ -347,7 +347,7 @@ souleyez/ui/export_view.py,sha256=0nQvVsKk7FU4uRzSfJ_qBZh_Lfn8hgGA2rbJ5bNg5-Y,65
|
|
|
347
347
|
souleyez/ui/gap_analysis_view.py,sha256=AytAOEBq010wwo9hne1TE-uJpY_xicjLrFANbvN3r3w,30727
|
|
348
348
|
souleyez/ui/help_system.py,sha256=nKGxLaMi-TKYs6xudTyw_tZqBb1cGFEuYYh6N-MAsJE,16648
|
|
349
349
|
souleyez/ui/intelligence_view.py,sha256=VeAQ-3mANRnLIVpRqocL3JV0HUmJtADdxDeC5lzQhE0,32168
|
|
350
|
-
souleyez/ui/interactive.py,sha256=
|
|
350
|
+
souleyez/ui/interactive.py,sha256=WkxOlN1OyMvI49pZXje_tulORScHfoV5RNvE6PZPi50,1442929
|
|
351
351
|
souleyez/ui/interactive_selector.py,sha256=6A51fgmFRnemBY0aCPHIhK2Rpba16NjSGKLzC0Q5vI8,16407
|
|
352
352
|
souleyez/ui/log_formatter.py,sha256=akhIkYoO_cCaKxS1V5N3iPmIrHzgsU7pmsedx70s9TI,3845
|
|
353
353
|
souleyez/ui/menu_components.py,sha256=N8zq2QXGmfaLJ08l53MMYt1y-5LRWgpZH6r8nXHonj8,3519
|
|
@@ -371,9 +371,9 @@ souleyez/ui/wazuh_vulns_view.py,sha256=3vJJEmrjgS2wD6EDB7ZV7WxgytBHTm-1WqNDjp7lV
|
|
|
371
371
|
souleyez/ui/wordlist_browser.py,sha256=iQ2YYxrVo8FGCfM-Bc0teVBijSAbd2rjbSQ2hOE7eiY,16110
|
|
372
372
|
souleyez/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
373
373
|
souleyez/utils/tool_checker.py,sha256=YzNajZpFyKJA5fp0Kq_gQ0YnKb7J1BaKJSZ8vP-IWj8,30868
|
|
374
|
-
souleyez-2.43.
|
|
375
|
-
souleyez-2.43.
|
|
376
|
-
souleyez-2.43.
|
|
377
|
-
souleyez-2.43.
|
|
378
|
-
souleyez-2.43.
|
|
379
|
-
souleyez-2.43.
|
|
374
|
+
souleyez-2.43.26.dist-info/licenses/LICENSE,sha256=J7vDD5QMF4w2oSDm35eBgosATE70ah1M40u9W4EpTZs,1090
|
|
375
|
+
souleyez-2.43.26.dist-info/METADATA,sha256=lPnWrbGHwqpBwcB6xinsSJ8WYUdpMnBaDCjbCpIit_E,10427
|
|
376
|
+
souleyez-2.43.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
377
|
+
souleyez-2.43.26.dist-info/entry_points.txt,sha256=bN5W1dhjDZJl3TKclMjRpfQvGPmyrJLwwDuCj_X39HE,48
|
|
378
|
+
souleyez-2.43.26.dist-info/top_level.txt,sha256=afAMzS9p4lcdBNxhGo6jl3ipQE9HUvvNIPOdjtPjr_Q,9
|
|
379
|
+
souleyez-2.43.26.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|