souleyez 2.26.0__py3-none-any.whl → 2.27.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.

Potentially problematic release.


This version of souleyez might be problematic. Click here for more details.

@@ -44,6 +44,7 @@ def handle_job_result(job: Dict[str, Any]) -> Optional[Dict[str, Any]]:
44
44
  return None
45
45
 
46
46
  if not log_path or not os.path.exists(log_path):
47
+ logger.error(f"Job {job.get('id')} parse failed: log file missing or does not exist (path={log_path})")
47
48
  return None
48
49
 
49
50
  # Get engagement ID from job or fall back to current engagement
@@ -56,10 +57,12 @@ def handle_job_result(job: Dict[str, Any]) -> Optional[Dict[str, Any]]:
56
57
  engagement = em.get_current()
57
58
 
58
59
  if not engagement:
60
+ logger.error(f"Job {job.get('id')} parse failed: no engagement_id and no current engagement")
59
61
  return None
60
62
 
61
63
  engagement_id = engagement['id']
62
- except Exception:
64
+ except Exception as e:
65
+ logger.error(f"Job {job.get('id')} parse failed: engagement lookup error: {e}")
63
66
  return None
64
67
 
65
68
  # Route to appropriate parser
@@ -110,6 +113,13 @@ def handle_job_result(job: Dict[str, Any]) -> Optional[Dict[str, Any]]:
110
113
  parse_result = parse_dalfox_job(engagement_id, log_path, job)
111
114
  elif tool == 'http_fingerprint':
112
115
  parse_result = parse_http_fingerprint_job(engagement_id, log_path, job)
116
+ elif tool == 'hashcat':
117
+ parse_result = parse_hashcat_job(engagement_id, log_path, job)
118
+ elif tool == 'john':
119
+ parse_result = parse_john_job(engagement_id, log_path, job)
120
+ else:
121
+ # No parser for this tool - log it so we know
122
+ logger.warning(f"Job {job.get('id')} has no parser for tool '{tool}' - results not extracted")
113
123
 
114
124
  # NOTE: Auto-chaining is now handled in background.py after parsing completes
115
125
  # This avoids duplicate job creation and gives better control over timing
@@ -3245,3 +3255,165 @@ def parse_dalfox_job(engagement_id: int, log_path: str, job: Dict[str, Any]) ->
3245
3255
  except Exception as e:
3246
3256
  logger.error(f"Error parsing dalfox job: {e}")
3247
3257
  return {'error': str(e)}
3258
+
3259
+
3260
+ def parse_hashcat_job(engagement_id: int, log_path: str, job: Dict[str, Any]) -> Dict[str, Any]:
3261
+ """Parse hashcat job results and extract cracked passwords."""
3262
+ try:
3263
+ from souleyez.parsers.hashcat_parser import parse_hashcat_output, map_to_credentials
3264
+ from souleyez.storage.credentials import CredentialsManager
3265
+ from souleyez.storage.findings import FindingsManager
3266
+
3267
+ # Read the log file
3268
+ with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
3269
+ log_content = f.read()
3270
+
3271
+ # Parse hashcat output
3272
+ hash_file = job.get('metadata', {}).get('hash_file', '')
3273
+ parsed = parse_hashcat_output(log_content, hash_file)
3274
+
3275
+ # Store credentials
3276
+ cm = CredentialsManager()
3277
+ creds_added = 0
3278
+
3279
+ for cracked in parsed.get('cracked', []):
3280
+ try:
3281
+ cm.add_credential(
3282
+ engagement_id=engagement_id,
3283
+ host_id=None, # Hash cracking typically not tied to a specific host
3284
+ username='', # Hashcat doesn't always know the username
3285
+ password=cracked['password'],
3286
+ service='cracked_hash',
3287
+ credential_type='password',
3288
+ tool='hashcat',
3289
+ status='cracked',
3290
+ notes=f"Cracked from hash: {cracked['hash'][:32]}..."
3291
+ )
3292
+ creds_added += 1
3293
+ except Exception:
3294
+ pass # Skip duplicates
3295
+
3296
+ # Create finding if we cracked passwords
3297
+ fm = FindingsManager()
3298
+ findings_added = 0
3299
+
3300
+ if parsed.get('cracked'):
3301
+ fm.add_finding(
3302
+ engagement_id=engagement_id,
3303
+ title=f"Password Hashes Cracked - {len(parsed['cracked'])} passwords recovered",
3304
+ finding_type='credential',
3305
+ severity='high',
3306
+ description=f"Hashcat successfully cracked {len(parsed['cracked'])} password hash(es).\n\n"
3307
+ f"Status: {parsed['stats'].get('status', 'unknown')}\n"
3308
+ f"Cracked: {parsed['stats'].get('cracked_count', len(parsed['cracked']))}",
3309
+ tool='hashcat'
3310
+ )
3311
+ findings_added += 1
3312
+
3313
+ # Determine status
3314
+ if creds_added > 0:
3315
+ status = STATUS_DONE
3316
+ elif parsed['stats'].get('status') == 'exhausted':
3317
+ status = STATUS_NO_RESULTS # Ran to completion but found nothing
3318
+ else:
3319
+ status = STATUS_NO_RESULTS
3320
+
3321
+ return {
3322
+ 'tool': 'hashcat',
3323
+ 'status': status,
3324
+ 'cracked_count': len(parsed.get('cracked', [])),
3325
+ 'credentials_added': creds_added,
3326
+ 'findings_added': findings_added,
3327
+ 'hashcat_status': parsed['stats'].get('status', 'unknown')
3328
+ }
3329
+
3330
+ except Exception as e:
3331
+ logger.error(f"Error parsing hashcat job: {e}")
3332
+ return {'error': str(e)}
3333
+
3334
+
3335
+ def parse_john_job(engagement_id: int, log_path: str, job: Dict[str, Any]) -> Dict[str, Any]:
3336
+ """Parse John the Ripper job results and extract cracked passwords."""
3337
+ try:
3338
+ from souleyez.parsers.john_parser import parse_john_output
3339
+ from souleyez.storage.credentials import CredentialsManager
3340
+ from souleyez.storage.findings import FindingsManager
3341
+
3342
+ # Read the log file
3343
+ with open(log_path, 'r', encoding='utf-8', errors='replace') as f:
3344
+ log_content = f.read()
3345
+
3346
+ # Get hash file from job metadata if available
3347
+ hash_file = job.get('metadata', {}).get('hash_file', None)
3348
+
3349
+ # Parse john output
3350
+ parsed = parse_john_output(log_content, hash_file)
3351
+
3352
+ # Store credentials
3353
+ cm = CredentialsManager()
3354
+ creds_added = 0
3355
+
3356
+ for cred in parsed.get('cracked', []):
3357
+ username = cred.get('username', '')
3358
+ password = cred.get('password', '')
3359
+
3360
+ if password: # At minimum we need a password
3361
+ try:
3362
+ cm.add_credential(
3363
+ engagement_id=engagement_id,
3364
+ host_id=None, # Hash cracking typically not tied to a specific host
3365
+ username=username if username != 'unknown' else '',
3366
+ password=password,
3367
+ service='cracked_hash',
3368
+ credential_type='password',
3369
+ tool='john',
3370
+ status='cracked',
3371
+ notes=f"Cracked by John the Ripper"
3372
+ )
3373
+ creds_added += 1
3374
+ except Exception:
3375
+ pass # Skip duplicates
3376
+
3377
+ # Create finding if we cracked passwords
3378
+ fm = FindingsManager()
3379
+ findings_added = 0
3380
+
3381
+ if parsed.get('cracked'):
3382
+ usernames = [c.get('username', 'unknown') for c in parsed['cracked'] if c.get('username')]
3383
+ usernames_str = ', '.join(usernames[:10]) # First 10
3384
+ if len(usernames) > 10:
3385
+ usernames_str += f" (+{len(usernames) - 10} more)"
3386
+
3387
+ fm.add_finding(
3388
+ engagement_id=engagement_id,
3389
+ title=f"Password Hashes Cracked - {len(parsed['cracked'])} passwords recovered",
3390
+ finding_type='credential',
3391
+ severity='high',
3392
+ description=f"John the Ripper successfully cracked {len(parsed['cracked'])} password hash(es).\n\n"
3393
+ f"Usernames: {usernames_str}\n"
3394
+ f"Session status: {parsed.get('session_status', 'unknown')}",
3395
+ tool='john'
3396
+ )
3397
+ findings_added += 1
3398
+
3399
+ # Determine status
3400
+ if creds_added > 0:
3401
+ status = STATUS_DONE
3402
+ elif parsed.get('session_status') == 'completed':
3403
+ status = STATUS_NO_RESULTS # Ran to completion but found nothing
3404
+ else:
3405
+ status = STATUS_NO_RESULTS
3406
+
3407
+ return {
3408
+ 'tool': 'john',
3409
+ 'status': status,
3410
+ 'cracked_count': len(parsed.get('cracked', [])),
3411
+ 'credentials_added': creds_added,
3412
+ 'findings_added': findings_added,
3413
+ 'session_status': parsed.get('session_status', 'unknown'),
3414
+ 'total_loaded': parsed.get('total_loaded', 0)
3415
+ }
3416
+
3417
+ except Exception as e:
3418
+ logger.error(f"Error parsing john job: {e}")
3419
+ return {'error': str(e)}
@@ -4,12 +4,13 @@ Worker health check and management utilities
4
4
  """
5
5
  import psutil
6
6
  import time
7
- from typing import Optional, Tuple
7
+ from typing import Optional, Tuple, Dict, Any
8
8
 
9
9
 
10
10
  def is_worker_running() -> Tuple[bool, Optional[int]]:
11
11
  """
12
- Check if background worker is running
12
+ Check if background worker is running.
13
+
13
14
  Returns: (is_running, pid)
14
15
  """
15
16
  for proc in psutil.process_iter(['pid', 'cmdline']):
@@ -29,6 +30,40 @@ def is_worker_running() -> Tuple[bool, Optional[int]]:
29
30
  return False, None
30
31
 
31
32
 
33
+ def is_worker_healthy() -> Tuple[bool, Optional[int], Optional[str]]:
34
+ """
35
+ Check if background worker is running AND healthy (responding).
36
+
37
+ Uses heartbeat file to verify worker is actively processing.
38
+ A worker process may exist but be frozen/hung - heartbeat detects this.
39
+
40
+ Returns: (is_healthy, pid, issue)
41
+ - is_healthy: True if worker is running and heartbeat is fresh
42
+ - pid: Worker PID if found, None otherwise
43
+ - issue: Description of issue if not healthy, None otherwise
44
+ """
45
+ from souleyez.engine.background import (
46
+ get_heartbeat_age, HEARTBEAT_STALE_THRESHOLD
47
+ )
48
+
49
+ is_running, pid = is_worker_running()
50
+
51
+ if not is_running:
52
+ return False, None, "Worker process not found"
53
+
54
+ # Check heartbeat
55
+ heartbeat_age = get_heartbeat_age()
56
+
57
+ if heartbeat_age is None:
58
+ # No heartbeat file - worker may have just started
59
+ return True, pid, "No heartbeat yet (may be starting)"
60
+
61
+ if heartbeat_age > HEARTBEAT_STALE_THRESHOLD:
62
+ return False, pid, f"Heartbeat stale ({int(heartbeat_age)}s old, threshold: {HEARTBEAT_STALE_THRESHOLD}s)"
63
+
64
+ return True, pid, None
65
+
66
+
32
67
  def start_worker_if_needed() -> bool:
33
68
  """
34
69
  Start worker if not running
@@ -107,3 +142,64 @@ def get_worker_status() -> dict:
107
142
  pass
108
143
 
109
144
  return status
145
+
146
+
147
+ def get_worker_health() -> Dict[str, Any]:
148
+ """
149
+ Get detailed worker health status including heartbeat info.
150
+
151
+ Returns dict with:
152
+ - running: Whether worker process exists
153
+ - healthy: Whether worker is running AND responsive
154
+ - pid: Worker PID if running
155
+ - uptime: Seconds since worker started
156
+ - heartbeat_age: Seconds since last heartbeat
157
+ - heartbeat_stale: Whether heartbeat is stale
158
+ - issue: Description of any health issue
159
+ - cpu_percent: CPU usage percentage
160
+ - memory_mb: Memory usage in MB
161
+ """
162
+ from souleyez.engine.background import (
163
+ get_heartbeat_age, HEARTBEAT_STALE_THRESHOLD
164
+ )
165
+
166
+ is_running, pid = is_worker_running()
167
+ heartbeat_age = get_heartbeat_age()
168
+
169
+ health = {
170
+ 'running': is_running,
171
+ 'healthy': False,
172
+ 'pid': pid,
173
+ 'uptime': None,
174
+ 'heartbeat_age': heartbeat_age,
175
+ 'heartbeat_stale': heartbeat_age is None or heartbeat_age > HEARTBEAT_STALE_THRESHOLD,
176
+ 'issue': None,
177
+ 'cpu_percent': None,
178
+ 'memory_mb': None
179
+ }
180
+
181
+ if not is_running:
182
+ health['issue'] = "Worker process not found"
183
+ return health
184
+
185
+ # Get process info
186
+ try:
187
+ proc = psutil.Process(pid)
188
+ health['uptime'] = int(time.time() - proc.create_time())
189
+ health['cpu_percent'] = proc.cpu_percent(interval=0.1)
190
+ health['memory_mb'] = round(proc.memory_info().rss / 1024 / 1024, 1)
191
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
192
+ health['issue'] = "Cannot access worker process"
193
+ return health
194
+
195
+ # Check heartbeat
196
+ if heartbeat_age is None:
197
+ health['issue'] = "No heartbeat yet (worker may be starting)"
198
+ health['healthy'] = True # Give benefit of doubt for new workers
199
+ elif heartbeat_age > HEARTBEAT_STALE_THRESHOLD:
200
+ health['issue'] = f"Worker unresponsive (heartbeat {int(heartbeat_age)}s old)"
201
+ health['healthy'] = False
202
+ else:
203
+ health['healthy'] = True
204
+
205
+ return health
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.26.0')
176
+ @click.version_option(version='2.27.0')
177
177
  def cli():
178
178
  """SoulEyez - AI-Powered Pentesting Platform by CyberSoul Security"""
179
179
  from souleyez.log_config import init_logging
@@ -326,6 +326,12 @@ class HttpFingerprintPlugin(PluginBase):
326
326
  }
327
327
 
328
328
  parsed = urlparse(url)
329
+
330
+ # Security: Only allow http/https schemes (B310 - prevent file:// or custom schemes)
331
+ if parsed.scheme not in ('http', 'https'):
332
+ result['error'] = f"Invalid URL scheme: {parsed.scheme}. Only http/https allowed."
333
+ return result
334
+
329
335
  is_https = parsed.scheme == 'https'
330
336
 
331
337
  # Create request with common browser headers
@@ -362,9 +368,9 @@ class HttpFingerprintPlugin(PluginBase):
362
368
  except Exception:
363
369
  pass # TLS info is optional
364
370
 
365
- response = urllib.request.urlopen(req, timeout=timeout, context=ctx)
371
+ response = urllib.request.urlopen(req, timeout=timeout, context=ctx) # nosec B310 - scheme validated above
366
372
  else:
367
- response = urllib.request.urlopen(req, timeout=timeout)
373
+ response = urllib.request.urlopen(req, timeout=timeout) # nosec B310 - scheme validated above
368
374
 
369
375
  result['status_code'] = response.getcode()
370
376
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: souleyez
3
- Version: 2.26.0
3
+ Version: 2.27.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.26.0
75
+ ## Version: 2.27.0
76
76
 
77
77
  ### What's Included
78
78
 
@@ -310,4 +310,4 @@ Happy hacking! 🛡️
310
310
 
311
311
  ---
312
312
 
313
- **Version**: 2.24.0 | **Release Date**: January 2026 | **Maintainer**: CyberSoul Security
313
+ **Version**: 2.27.0 | **Release Date**: January 2026 | **Maintainer**: CyberSoul Security
@@ -1,10 +1,10 @@
1
- souleyez/__init__.py,sha256=AQLQTfTAunRI82MROjAdq13BluGH3dFd7gjy2F09lHc,23
1
+ souleyez/__init__.py,sha256=TXWDTbV0k4s5q6N3f2OyBp4G8i4-vO4HVgQITP7RmLg,23
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_GQB9cCjAfPAFNtnpKCBK2NXCD8Jfv5aV9Ij-LQcYo,122774
7
+ souleyez/main.py,sha256=78BAKCcgpw3eUx1Uhxn3BlaP9YbigjZOjpbwTZS4zGE,122774
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=CTJNTubBYLySkPqQX3s1LfusFLgwk_dsHto8__cANDc,7183
107
+ souleyez/docs/README.md,sha256=3h0rS8Q7TVK5yYDP0X2MKR0C5j5xeUe55icS4T9eqsI,7183
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
@@ -128,7 +128,7 @@ souleyez/docs/security/threat-model.md,sha256=JcR5AR-l977-7HTe5O2LULBikaxJovcxHE
128
128
  souleyez/docs/user-guide/ai-integration.md,sha256=erC3Svg6XosKhT1BoHRQ98PUp71OdNQ6bkJIh7shN_Y,8859
129
129
  souleyez/docs/user-guide/attack-surface.md,sha256=9QabVuuPkCNNDgAXx_Yerbtmnk61lPkU8Gjl_M6-rG8,12924
130
130
  souleyez/docs/user-guide/auto-chaining.md,sha256=UjQ8J8rBgukQIikIrH3U7XoX0WF8EHO_a9i3qDomsXg,21144
131
- souleyez/docs/user-guide/configuration.md,sha256=7-CKFcJ4MpE_MMBAKI0IsCG65uSzETpVIpbwFkUOQFY,14649
131
+ souleyez/docs/user-guide/configuration.md,sha256=O2ZXyAAV6E41AHZuY2ZglZ20yBh5Gg-crElGFn6Ho6s,14650
132
132
  souleyez/docs/user-guide/deliverables-screenshots.md,sha256=D5ATXKZRhwXu8OsGMEEUzbXW3hJl-qTh4wsUPx8gNUA,15148
133
133
  souleyez/docs/user-guide/dependencies.md,sha256=WOPilg0W0U3KnsdGREkM5_gAG7Rr5P10oco7qDKkJEY,7475
134
134
  souleyez/docs/user-guide/evidence-vault.md,sha256=PNg7cIUlVXr41iMJTi66j4qUV2fkrPATljunx0pD5sI,9454
@@ -145,14 +145,14 @@ souleyez/docs/user-guide/uninstall.md,sha256=gDknetFhjZ0tnYk4JqhLa369NT4bIRb50rm
145
145
  souleyez/docs/user-guide/worker-management.md,sha256=hNu6eSTVb6XM4Zbb0I9Y5aL4AA2EiWOSFI6iGjn17kU,12035
146
146
  souleyez/docs/user-guide/workflows.md,sha256=4EyZKWRyuWf9wrENJwtidWKN25PGis1Pk33HIHk5UHM,22261
147
147
  souleyez/engine/__init__.py,sha256=THI_89hQfAPJDsfzDcur6H9sEGhGAnTxSNim7UOExYc,110
148
- souleyez/engine/background.py,sha256=Wm7dBzwq8qTi1vYvJk7T2TRktkdNzk50YQGZddcI3NU,66278
148
+ souleyez/engine/background.py,sha256=HnzpN8P6TcDNxLW4R2re2cgBbBsEOfCdshiCOfJDx-g,83140
149
149
  souleyez/engine/base.py,sha256=G35U1d-fygUvzmHH8zxLXw-vyQ9JzcfhGaSYOsHJtzQ,728
150
150
  souleyez/engine/job_status.py,sha256=OAEf2rAzapm55m4tc3PSilotdA5ONX15JavUMLre0is,2685
151
151
  souleyez/engine/loader.py,sha256=ke6QQVVWozDnqGNBotajC3RBYOa2_DZmv5DAnDZVgIc,2769
152
152
  souleyez/engine/log_sanitizer.py,sha256=QHF6zSms-wHo6SbL6fHXIh1GG-8G34lE7kl45nbPn70,7130
153
153
  souleyez/engine/manager.py,sha256=aBQMoib-VWNXtIp5Qn34tRj1P1jiLpwAIoo1fexAaLU,3629
154
- souleyez/engine/result_handler.py,sha256=KN2l02mcXW8M69NHouP4se-ZK9CNtEEZsR6lZaSb3xY,129520
155
- souleyez/engine/worker_manager.py,sha256=exepzHnyUc2PpAxVJSdrU7LCrlm-s6JBMgQyivSV46Y,2905
154
+ souleyez/engine/result_handler.py,sha256=IIESU1rGDR3W7yZcZzDyfBTCIVZtHifS8HQv5Ns0eoE,136657
155
+ souleyez/engine/worker_manager.py,sha256=B7b8RbkKTNofmiIyHTNgdikoZCLXpB-iIl1S4-U3q9o,6127
156
156
  souleyez/export/__init__.py,sha256=2kFHftSqqrRUG6PhtfhCyhnkpkjc-8Zb4utGo-Nb6B4,61
157
157
  souleyez/export/evidence_bundle.py,sha256=hqPn_h2CidhL-1VAT0qraZ8r1yfnUTnLZ3RfPPCK5Ds,9966
158
158
  souleyez/feature_flags/__init__.py,sha256=shd9UIGrNh_1jnHhKeGxWpwbBnFxd-UjgVyOZPYE7DE,42
@@ -227,7 +227,7 @@ souleyez/plugins/ffuf.py,sha256=7c1-Q7xXTMmH_2wHXikjmZnSgZL13Hj5E_asBxZ6Y5U,1165
227
227
  souleyez/plugins/firmware_extract.py,sha256=_hZXx6cHb9noM6uVgi3hwrJLw8hE9mDUelTEHwoIdCU,6460
228
228
  souleyez/plugins/gobuster.py,sha256=GMTUyfkVnZ2gp3kh_R-KQ4EIGEBX5fxBIMfHZrwkVFo,29285
229
229
  souleyez/plugins/hashcat.py,sha256=aigfwBu9IorXKgbyEIWx0qOCEdr1wnZaPqdYwh0PITc,10381
230
- souleyez/plugins/http_fingerprint.py,sha256=jC6Awq63zFUBBi7hCzTvthZkOjCB-11-lFST45JSjQM,20857
230
+ souleyez/plugins/http_fingerprint.py,sha256=_D5UVAtDC0f-uy4pQcBI43c4jnsJ5wyvCIvttUiVurw,21202
231
231
  souleyez/plugins/hydra.py,sha256=kfVJwgh3x1DC0wEtA-lkoY7qhQH1qKViYexUECZSPY4,29520
232
232
  souleyez/plugins/impacket_getnpusers.py,sha256=6TBxVTO9NGUbn5ShV-dCxPP11CFqf-Y3lAgt8_oP2Vg,8652
233
233
  souleyez/plugins/impacket_psexec.py,sha256=gU_MDSazDMj1TeWm5V9cD6wrLe3ULwbDv4jhg3Vm2rQ,8813
@@ -365,9 +365,9 @@ souleyez/ui/tutorial_state.py,sha256=Thf7_qCj4VKjG7UqgJqa9kjIqiFUU-7Q7kG4v-u2B4A
365
365
  souleyez/ui/wazuh_vulns_view.py,sha256=3vJJEmrjgS2wD6EDB7ZV7WxgytBHTm-1WqNDjp7lVEI,21830
366
366
  souleyez/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
367
367
  souleyez/utils/tool_checker.py,sha256=kQcXJVY5NiO-orQAUnpHhpQvR5UOBNHJ0PaT0fBxYoQ,30782
368
- souleyez-2.26.0.dist-info/licenses/LICENSE,sha256=J7vDD5QMF4w2oSDm35eBgosATE70ah1M40u9W4EpTZs,1090
369
- souleyez-2.26.0.dist-info/METADATA,sha256=e6ejF-F9IVoFtz4IJNhCTi6OaEKM73_U5X8nkfk0rvk,10691
370
- souleyez-2.26.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
371
- souleyez-2.26.0.dist-info/entry_points.txt,sha256=bN5W1dhjDZJl3TKclMjRpfQvGPmyrJLwwDuCj_X39HE,48
372
- souleyez-2.26.0.dist-info/top_level.txt,sha256=afAMzS9p4lcdBNxhGo6jl3ipQE9HUvvNIPOdjtPjr_Q,9
373
- souleyez-2.26.0.dist-info/RECORD,,
368
+ souleyez-2.27.0.dist-info/licenses/LICENSE,sha256=J7vDD5QMF4w2oSDm35eBgosATE70ah1M40u9W4EpTZs,1090
369
+ souleyez-2.27.0.dist-info/METADATA,sha256=rb4LyNfy5hw_BtcKYyApY8MIKrZ4mdHqJZTbZiF1gCA,10691
370
+ souleyez-2.27.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
371
+ souleyez-2.27.0.dist-info/entry_points.txt,sha256=bN5W1dhjDZJl3TKclMjRpfQvGPmyrJLwwDuCj_X39HE,48
372
+ souleyez-2.27.0.dist-info/top_level.txt,sha256=afAMzS9p4lcdBNxhGo6jl3ipQE9HUvvNIPOdjtPjr_Q,9
373
+ souleyez-2.27.0.dist-info/RECORD,,