secator 0.8.0__py3-none-any.whl → 0.8.2__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 secator might be problematic. Click here for more details.

secator/cli.py CHANGED
@@ -19,7 +19,7 @@ from rich.table import Table
19
19
  from secator.config import CONFIG, ROOT_FOLDER, Config, default_config, config_path
20
20
  from secator.decorators import OrderedGroup, register_runner
21
21
  from secator.definitions import ADDONS_ENABLED, ASCII, DEV_PACKAGE, OPT_NOT_SUPPORTED, VERSION, STATE_COLORS
22
- from secator.installer import ToolInstaller, fmt_health_table_row, get_health_table, get_version_info
22
+ from secator.installer import ToolInstaller, fmt_health_table_row, get_health_table, get_version_info, get_distro_config
23
23
  from secator.output_types import FINDING_TYPES, Info, Error
24
24
  from secator.report import Report
25
25
  from secator.rich import console
@@ -127,7 +127,7 @@ def worker(hostname, concurrency, reload, queue, pool, check, dev, stop, show):
127
127
 
128
128
  # Check Celery addon is installed
129
129
  if not ADDONS_ENABLED['worker']:
130
- console.print('[bold red]Missing worker addon: please run [bold green4]secator install addons worker[/][/].')
130
+ console.print(Error(message='Missing worker addon: please run "secator install addons worker".'))
131
131
  sys.exit(1)
132
132
 
133
133
  # Check broken / backend addon is installed
@@ -135,7 +135,7 @@ def worker(hostname, concurrency, reload, queue, pool, check, dev, stop, show):
135
135
  backend_protocol = CONFIG.celery.result_backend.split('://')[0]
136
136
  if CONFIG.celery.broker_url:
137
137
  if (broker_protocol == 'redis' or backend_protocol == 'redis') and not ADDONS_ENABLED['redis']:
138
- console.print('[bold red]Missing `redis` addon: please run [bold green4]secator install addons redis[/][/].')
138
+ console.print(Error(message='Missing redis addon: please run "secator install addons redis".'))
139
139
  sys.exit(1)
140
140
 
141
141
  # Debug Celery config
@@ -214,7 +214,7 @@ def revshell(name, host, port, interface, listen, force):
214
214
  console.print(Error(message=f'Interface "{interface}" could not be found. Run "ifconfig" to see the list of available interfaces')) # noqa: E501
215
215
  return
216
216
  else:
217
- console.print(Info(message=f'Detected host IP: [bold orange1]{host}[/]'))
217
+ console.print(Info(message=f'Detected host IP: {host}'))
218
218
 
219
219
  # Download reverse shells JSON from repo
220
220
  revshells_json = f'{CONFIG.dirs.revshells}/revshells.json'
@@ -389,84 +389,54 @@ def record(record_name, script, interactive, width, height, output_dir):
389
389
  console.print(Info(message=f'Generated {output_gif_path}'))
390
390
 
391
391
 
392
- @util.group('build')
393
- def build():
394
- """Build secator."""
392
+ @util.command('build')
393
+ @click.option('--version', type=str, help='Override version specified in pyproject.toml')
394
+ def build(version):
395
+ """Build secator PyPI package."""
395
396
  if not DEV_PACKAGE:
396
397
  console.print(Error(message='You MUST use a development version of secator to make builds'))
397
398
  sys.exit(1)
398
- pass
399
-
400
-
401
- @build.command('pypi')
402
- def build_pypi():
403
- """Build secator PyPI package."""
404
399
  if not ADDONS_ENABLED['build']:
405
- console.print(Error(message='Missing build addon: please run [bold green4]secator install addons build[/]'))
400
+ console.print(Error(message='Missing build addon: please run "secator install addons build"'))
406
401
  sys.exit(1)
407
- with console.status('[bold gold3]Building PyPI package...[/]'):
408
- ret = Command.execute(f'{sys.executable} -m hatch build', name='hatch build', cwd=ROOT_FOLDER)
409
- sys.exit(ret.return_code)
410
402
 
403
+ # Update version in pyproject.toml if --version is explicitely passed
404
+ if version:
405
+ pyproject_toml_path = Path.cwd() / 'pyproject.toml'
406
+ if not pyproject_toml_path.exists():
407
+ console.print(Error(message='You must be in the secator root directory to make builds with --version'))
408
+ sys.exit(1)
409
+ console.print(Info(message=f'Updating version in pyproject.toml to {version}'))
410
+ with open(pyproject_toml_path, "r") as file:
411
+ content = file.read()
412
+ updated_content = re.sub(r'^\s*version\s*=\s*".*?"', f'version = "{version}"', content, flags=re.MULTILINE)
413
+ with open(pyproject_toml_path, "w") as file:
414
+ file.write(updated_content)
411
415
 
412
- @build.command('docker')
413
- @click.option('--tag', '-t', type=str, default=None, help='Specific tag')
414
- @click.option('--latest', '-l', is_flag=True, default=False, help='Latest tag')
415
- def build_docker(tag, latest):
416
- """Build secator Docker image."""
417
- if not tag:
418
- tag = VERSION if latest else 'dev'
419
- cmd = f'docker build -t freelabz/secator:{tag}'
420
- if latest:
421
- cmd += ' -t freelabz/secator:latest'
422
- cmd += ' .'
423
- with console.status('[bold gold3]Building Docker image...[/]'):
424
- ret = Command.execute(cmd, name='docker build', cwd=ROOT_FOLDER)
416
+ with console.status('[bold gold3]Building PyPI package...[/]'):
417
+ ret = Command.execute(f'{sys.executable} -m hatch build', name='hatch build', cwd=ROOT_FOLDER)
425
418
  sys.exit(ret.return_code)
426
419
 
427
420
 
428
- @util.group('publish')
421
+ @util.command('publish')
429
422
  def publish():
430
- """Publish secator."""
423
+ """Publish secator PyPI package."""
431
424
  if not DEV_PACKAGE:
432
- console.print('[bold red]You MUST use a development version of secator to publish builds.[/]')
425
+ console.print(Error(message='You MUST use a development version of secator to publish builds.'))
433
426
  sys.exit(1)
434
- pass
435
-
436
-
437
- @publish.command('pypi')
438
- def publish_pypi():
439
- """Publish secator PyPI package."""
440
427
  if not ADDONS_ENABLED['build']:
441
- console.print('[bold red]Missing build addon: please run [bold green4]secator install addons build[/][/]')
428
+ console.print(Error(message='Missing build addon: please run "secator install addons build"'))
442
429
  sys.exit(1)
443
430
  os.environ['HATCH_INDEX_USER'] = '__token__'
444
431
  hatch_token = os.environ.get('HATCH_INDEX_AUTH')
445
432
  if not hatch_token:
446
- console.print('[bold red]Missing PyPI auth token (HATCH_INDEX_AUTH env variable).')
433
+ console.print(Error(message='Missing PyPI auth token (HATCH_INDEX_AUTH env variable).'))
447
434
  sys.exit(1)
448
435
  with console.status('[bold gold3]Publishing PyPI package...[/]'):
449
436
  ret = Command.execute(f'{sys.executable} -m hatch publish', name='hatch publish', cwd=ROOT_FOLDER)
450
437
  sys.exit(ret.return_code)
451
438
 
452
439
 
453
- @publish.command('docker')
454
- @click.option('--tag', '-t', default=None, help='Specific tag')
455
- @click.option('--latest', '-l', is_flag=True, default=False, help='Latest tag')
456
- def publish_docker(tag, latest):
457
- """Publish secator Docker image."""
458
- if not tag:
459
- tag = VERSION if latest else 'dev'
460
- cmd = f'docker push freelabz/secator:{tag}'
461
- cmd2 = 'docker push freelabz/secator:latest'
462
- with console.status(f'[bold gold3]Publishing Docker image {tag}...[/]'):
463
- ret = Command.execute(cmd, name=f'docker push ({tag})', cwd=ROOT_FOLDER)
464
- if latest:
465
- ret2 = Command.execute(cmd2, name='docker push (latest)')
466
- sys.exit(max(ret.return_code, ret2.return_code))
467
- sys.exit(ret.return_code)
468
-
469
-
470
440
  #--------#
471
441
  # CONFIG #
472
442
  #--------#
@@ -503,7 +473,7 @@ def config_set(key, value):
503
473
  return
504
474
  console.print(f'[bold green]:tada: Saved config to [/]{CONFIG._path}')
505
475
  else:
506
- console.print('[bold red]:x: Invalid config, not saving it.')
476
+ console.print(Error(message='Invalid config, not saving it.'))
507
477
 
508
478
 
509
479
  @config.command('edit')
@@ -699,13 +669,13 @@ def report_show(report_query, output, runner_type, time_delta, type, query, work
699
669
  f'\n{path} ([bold blue]{runner_name}[/] [dim]{runner_type}[/]) ([dim]{file_date}[/]):')
700
670
  if report.is_empty():
701
671
  if len(paths) == 1:
702
- console.print('[bold orange4]No results in report.[/]')
672
+ console.print(Warning(message='No results in report.'))
703
673
  else:
704
- console.print('[bold orange4]No new results since previous scan.[/]')
674
+ console.print(Warning(message='No new results since previous scan.'))
705
675
  continue
706
676
  report.send()
707
677
  except json.decoder.JSONDecodeError as e:
708
- console.print(f'[bold red]Could not load {path}: {str(e)}')
678
+ console.print(Error(message=f'Could not load {path}: {str(e)}'))
709
679
 
710
680
  if unified:
711
681
  console.print(f'\n:wrench: [bold gold3]Building report by crunching {len(all_results)} results ...[/]')
@@ -759,12 +729,12 @@ def report_list(workspace, runner_type, time_delta):
759
729
  f"[{status_color}]{data['status']}[/]"
760
730
  )
761
731
  except json.JSONDecodeError as e:
762
- console.print(f'[bold red]Could not load {path}: {str(e)}')
732
+ console.print(Error(message=f'Could not load {path}: {str(e)}'))
763
733
 
764
734
  if len(paths) > 0:
765
735
  console.print(table)
766
736
  else:
767
- console.print('[bold red]No results found.')
737
+ console.print(Error(message='No results found.'))
768
738
 
769
739
 
770
740
  @report.command('export')
@@ -888,7 +858,7 @@ def health(json, debug, strict):
888
858
  error = False
889
859
  for tool, info in status['tools'].items():
890
860
  if not info['installed']:
891
- console.print(Error(message=f'{tool} not installed and strict mode is enabled.[/]'))
861
+ console.print(Error(message=f'{tool} not installed and strict mode is enabled.'))
892
862
  error = True
893
863
  if error:
894
864
  sys.exit(1)
@@ -902,7 +872,7 @@ def health(json, debug, strict):
902
872
 
903
873
  def run_install(title=None, cmd=None, packages=None, next_steps=None):
904
874
  if CONFIG.offline_mode:
905
- console.print('[bold red]Cannot run this command in offline mode.[/]')
875
+ console.print(Error(message='Cannot run this command in offline mode.'))
906
876
  return
907
877
  with console.status(f'[bold yellow] Installing {title}...'):
908
878
  if cmd:
@@ -1089,12 +1059,28 @@ def install_tools(cmds):
1089
1059
  tools = ALL_TASKS
1090
1060
  tools.sort(key=lambda x: x.__name__)
1091
1061
  return_code = 0
1062
+ if not tools:
1063
+ cmd_str = ' '.join(cmds)
1064
+ console.print(Error(message=f'No tools found for {cmd_str}.'))
1065
+ return
1092
1066
  for ix, cls in enumerate(tools):
1093
1067
  with console.status(f'[bold yellow][{ix + 1}/{len(tools)}] Installing {cls.__name__} ...'):
1094
1068
  status = ToolInstaller.install(cls)
1095
1069
  if not status.is_ok():
1096
1070
  return_code = 1
1097
1071
  console.print()
1072
+ distro = get_distro_config()
1073
+ cleanup_cmds = [
1074
+ 'go clean -cache',
1075
+ 'go clean -modcache',
1076
+ 'pip cache purge',
1077
+ 'gem cleanup --user-install',
1078
+ 'gem clean --user-install',
1079
+ ]
1080
+ if distro.pm_finalizer:
1081
+ cleanup_cmds.append(f'sudo {distro.pm_finalizer}')
1082
+ cmd = ' && '.join(cleanup_cmds)
1083
+ Command.execute(cmd, cls_attributes={'shell': True}, quiet=False)
1098
1084
  sys.exit(return_code)
1099
1085
 
1100
1086
 
@@ -1253,7 +1239,7 @@ def test():
1253
1239
  console.print(Error(message='You MUST use a development version of secator to run tests.'))
1254
1240
  sys.exit(1)
1255
1241
  if not ADDONS_ENABLED['dev']:
1256
- console.print(Error(message='Missing dev addon: please run [bold green4]secator install addons dev[/]'))
1242
+ console.print(Error(message='Missing dev addon: please run "secator install addons dev"'))
1257
1243
  sys.exit(1)
1258
1244
  pass
1259
1245
 
secator/installer.py CHANGED
@@ -18,6 +18,7 @@ import requests
18
18
  from rich.table import Table
19
19
 
20
20
  from secator.config import CONFIG
21
+ from secator.celery import IN_CELERY_WORKER_PROCESS
21
22
  from secator.definitions import OPT_NOT_SUPPORTED
22
23
  from secator.output_types import Info, Warning, Error
23
24
  from secator.rich import console
@@ -42,9 +43,10 @@ class InstallerStatus(Enum):
42
43
 
43
44
  @dataclass
44
45
  class Distribution:
45
- pm_install_command: str
46
- pm_name: str
47
46
  name: str
47
+ pm_name: str
48
+ pm_installer: str
49
+ pm_finalizer: str
48
50
 
49
51
 
50
52
  class ToolInstaller:
@@ -119,7 +121,7 @@ class PackageInstaller:
119
121
  """
120
122
  # Init status
121
123
  distribution = get_distro_config()
122
- if distribution.pm_install_command == 'unknown':
124
+ if not distribution.pm_installer:
123
125
  return InstallerStatus.UNKNOWN_DISTRIBUTION
124
126
 
125
127
  console.print(
@@ -133,20 +135,24 @@ class PackageInstaller:
133
135
  break
134
136
 
135
137
  # Installer cmd
136
- cmd = distribution.pm_install_command
138
+ cmd = distribution.pm_installer
139
+ if CONFIG.security.autoinstall_commands and IN_CELERY_WORKER_PROCESS:
140
+ cmd = f'flock /tmp/install.lock {cmd}'
137
141
  if getpass.getuser() != 'root':
138
142
  cmd = f'sudo {cmd}'
139
143
 
140
144
  if pkg_list:
145
+ pkg_str = ''
141
146
  for pkg in pkg_list:
142
147
  if ':' in pkg:
143
148
  pdistro, pkg = pkg.split(':')
144
149
  if pdistro != distribution.name:
145
150
  continue
146
- console.print(Info(message=f'Installing package {pkg}'))
147
- status = SourceInstaller.install(f'{cmd} {pkg}')
148
- if not status.is_ok():
149
- return status
151
+ pkg_str += f'{pkg} '
152
+ console.print(Info(message=f'Installing packages {pkg_str}'))
153
+ status = SourceInstaller.install(f'{cmd} {pkg_str}', install_prereqs=False)
154
+ if not status.is_ok():
155
+ return status
150
156
  return InstallerStatus.SUCCESS
151
157
 
152
158
 
@@ -154,7 +160,7 @@ class SourceInstaller:
154
160
  """Install a tool from source."""
155
161
 
156
162
  @classmethod
157
- def install(cls, config):
163
+ def install(cls, config, install_prereqs=True):
158
164
  """Install from source.
159
165
 
160
166
  Args:
@@ -175,6 +181,23 @@ class SourceInstaller:
175
181
  break
176
182
  if not install_cmd:
177
183
  return InstallerStatus.INSTALL_SKIPPED_OK
184
+
185
+ # Install build dependencies if needed
186
+ if install_prereqs:
187
+ if 'go ' in install_cmd:
188
+ status = PackageInstaller.install({'apt': ['golang-go'], '*': ['go']})
189
+ if not status.is_ok():
190
+ return status
191
+ if 'gem ' in install_cmd:
192
+ status = PackageInstaller.install({'apk': ['ruby', 'ruby-dev'], 'pacman': ['ruby', 'rubygems'], 'apt': ['ruby-full', 'rubygems']}) # noqa: E501
193
+ if not status.is_ok():
194
+ return status
195
+ if 'git ' in install_cmd or 'git+' in install_cmd:
196
+ status = PackageInstaller.install({'*': ['git']})
197
+ if not status.is_ok():
198
+ return status
199
+
200
+ # Run command
178
201
  ret = Command.execute(install_cmd, cls_attributes={'shell': True}, quiet=False)
179
202
  return InstallerStatus.SUCCESS if ret.return_code == 0 else InstallerStatus.INSTALL_FAILED
180
203
 
@@ -312,6 +335,7 @@ class GithubInstaller:
312
335
  temp_dir = os.path.join("/tmp", f'{repo_name}_{date_str}')
313
336
  os.makedirs(temp_dir, exist_ok=True)
314
337
 
338
+ console.print(Info(message=f'Extracting binary to {temp_dir}...'))
315
339
  if url.endswith('.zip'):
316
340
  with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:
317
341
  zip_ref.extractall(temp_dir)
@@ -323,7 +347,9 @@ class GithubInstaller:
323
347
  binary_path = cls._find_binary_in_directory(temp_dir, repo_name)
324
348
  if binary_path:
325
349
  os.chmod(binary_path, 0o755) # Make it executable
326
- shutil.move(binary_path, os.path.join(destination, repo_name)) # Move the binary
350
+ destination = os.path.join(destination, repo_name)
351
+ console.print(Info(message=f'Moving binary to {destination}...'))
352
+ shutil.move(binary_path, destination) # Move the binary
327
353
  return InstallerStatus.SUCCESS
328
354
  else:
329
355
  console.print(Error(message='Binary matching the repository name was not found in the archive.'))
@@ -479,7 +505,8 @@ def get_distro_config():
479
505
  package_manager_variable = os.environ.get('SECATOR_PACKAGE_MANAGER')
480
506
  if package_manager_variable:
481
507
  return package_manager_variable
482
- cmd = "unknown"
508
+ installer = None
509
+ finalizer = None
483
510
  system = platform.system()
484
511
  distrib = system
485
512
 
@@ -487,32 +514,37 @@ def get_distro_config():
487
514
  distrib = distro.id()
488
515
 
489
516
  if distrib in ["ubuntu", "debian", "linuxmint", "popos", "kali"]:
490
- cmd = "apt install -y"
517
+ installer = "apt install -y --no-install-recommends"
518
+ finalizer = "rm -rf /var/lib/apt/lists/*"
491
519
  elif distrib in ["arch", "manjaro", "endeavouros"]:
492
- cmd = "pacman -S --noconfirm"
520
+ installer = "pacman -S --noconfirm --needed"
493
521
  elif distrib in ["alpine"]:
494
- cmd = "apk add"
522
+ installer = "apk add --no-cache"
495
523
  elif distrib in ["fedora"]:
496
- cmd = "dnf install -y"
524
+ installer = "dnf install -y"
525
+ finalizer = "dnf clean all"
497
526
  elif distrib in ["centos", "rhel", "rocky", "alma"]:
498
- cmd = "yum -y"
527
+ installer = "yum -y"
528
+ finalizer = "yum clean all"
499
529
  elif distrib in ["opensuse", "sles"]:
500
- cmd = "zypper -n"
530
+ installer = "zypper -n"
531
+ finalizer = "zypper clean --all"
501
532
 
502
533
  elif system == "Darwin": # macOS
503
- cmd = "brew install"
534
+ installer = "brew install"
504
535
 
505
536
  elif system == "Windows":
506
537
  if shutil.which("winget"):
507
- cmd = "winget install --disable-interactivity"
538
+ installer = "winget install --disable-interactivity"
508
539
  elif shutil.which("choco"):
509
- cmd = "choco install"
540
+ installer = "choco install -y --no-progress"
510
541
  else:
511
- cmd = "scoop" # Alternative package manager for Windows
542
+ installer = "scoop" # Alternative package manager for Windows
512
543
 
513
- manager = cmd.split(' ')[0]
544
+ manager = installer.split(' ')[0]
514
545
  config = Distribution(
515
- pm_install_command=cmd,
546
+ pm_installer=installer,
547
+ pm_finalizer=finalizer,
516
548
  pm_name=manager,
517
549
  name=distrib
518
550
  )
secator/runners/_base.py CHANGED
@@ -630,7 +630,7 @@ class Runner:
630
630
  return
631
631
  remote_str = 'starting' if self.sync else 'sent to Celery worker'
632
632
  runner_name = self.__class__.__name__
633
- info = Info(message=f'{runner_name} [bold magenta]{self.config.name}[/] {remote_str}...', _source=self.unique_name)
633
+ info = Info(message=f'{runner_name} {self.config.name} {remote_str}...', _source=self.unique_name)
634
634
  self._print_item(info)
635
635
 
636
636
  def log_results(self):
@@ -146,6 +146,9 @@ class Command(Runner):
146
146
  validators=validators,
147
147
  context=context)
148
148
 
149
+ # Cmd name
150
+ self.cmd_name = self.__class__.cmd.split(' ')[0]
151
+
149
152
  # Inputs path
150
153
  self.inputs_path = None
151
154
 
@@ -298,7 +301,7 @@ class Command(Runner):
298
301
  proxy = CONFIG.http.socks5_proxy
299
302
  elif self.proxy in ['auto', 'http'] and self.proxy_http and CONFIG.http.http_proxy:
300
303
  proxy = CONFIG.http.http_proxy
301
- elif self.proxy == 'random':
304
+ elif self.proxy == 'random' and self.proxy_http:
302
305
  proxy = FreeProxy(timeout=CONFIG.http.freeproxy_timeout, rand=True, anonym=True).get()
303
306
  elif self.proxy.startswith(('http://', 'socks5://')):
304
307
  proxy = self.proxy
@@ -308,7 +311,7 @@ class Command(Runner):
308
311
 
309
312
  if proxy != 'proxychains' and self.proxy and not proxy:
310
313
  self._print(
311
- f'[bold red]Ignoring proxy "{self.proxy}" for {self.__class__.__name__} (not supported).[/]', rich=True)
314
+ f'[bold red]Ignoring proxy "{self.proxy}" for {self.cmd_name} (not supported).[/]', rich=True)
312
315
 
313
316
  #----------#
314
317
  # Internal #
@@ -373,7 +376,7 @@ class Command(Runner):
373
376
  status = ToolInstaller.install(self.__class__)
374
377
  if not status.is_ok():
375
378
  yield Error(
376
- message=f'Failed installing {self.name}',
379
+ message=f'Failed installing {self.cmd_name}',
377
380
  _source=self.unique_name,
378
381
  _uuid=str(uuid.uuid4())
379
382
  )
@@ -433,7 +436,7 @@ class Command(Runner):
433
436
  Returns:
434
437
  bool: True if the command is installed, False otherwise.
435
438
  """
436
- result = subprocess.Popen(["which", self.cmd.split(' ')[0]], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
439
+ result = subprocess.Popen(["which", self.cmd_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
437
440
  result.communicate()
438
441
  return result.returncode == 0
439
442
 
secator/tasks/bbot.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import shutil
2
2
 
3
+ from secator.config import CONFIG
3
4
  from secator.decorators import task
4
5
  from secator.runners import Command
5
6
  from secator.serializers import RegexSerializer
@@ -217,7 +218,13 @@ class bbot(Command):
217
218
  'message': 'message'
218
219
  }
219
220
  }
221
+ install_pre = {
222
+ '*': ['git', 'openssl', 'unzip', 'tar', 'chromium']
223
+ }
220
224
  install_cmd = 'pipx install bbot && pipx upgrade bbot'
225
+ install_post = {
226
+ '*': f'rm -fr {CONFIG.dirs.share}/pipx/venvs/bbot/lib/python3.12/site-packages/ansible_collections/*'
227
+ }
221
228
 
222
229
  @staticmethod
223
230
  def on_json_loaded(self, item):
@@ -228,7 +235,7 @@ class bbot(Command):
228
235
  return
229
236
 
230
237
  if _type not in BBOT_MAP_TYPES:
231
- self._print(f'[bold orange3]Found unsupported bbot type: {_type}.[/] [bold green]Skipping.[/]')
238
+ self._print(f'[bold orange3]Found unsupported bbot type: {_type}.[/] [bold green]Skipping.[/]', rich=True)
232
239
  return
233
240
 
234
241
  if isinstance(item['data'], str):
@@ -59,6 +59,9 @@ class feroxbuster(HttpFuzzer):
59
59
  WORDS: 'word_count'
60
60
  }
61
61
  }
62
+ install_pre = {
63
+ '*': ['curl', 'bash']
64
+ }
62
65
  install_cmd = (
63
66
  f'cd /tmp && curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | bash -s {CONFIG.dirs.bin}' # noqa: E501
64
67
  )
secator/tasks/gau.py CHANGED
@@ -41,6 +41,9 @@ class gau(HttpCrawler):
41
41
  USER_AGENT: OPT_NOT_SUPPORTED,
42
42
  }
43
43
  item_loaders = [JSONSerializer()]
44
+ install_pre = {
45
+ 'apk': ['libc6-compat']
46
+ }
44
47
  install_cmd = 'go install -v github.com/lc/gau/v2/cmd/gau@latest'
45
48
  install_github_handle = 'lc/gau'
46
49
  proxychains = False
secator/tasks/grype.py CHANGED
@@ -27,6 +27,9 @@ class grype(VulnCode):
27
27
  USER_AGENT: OPT_NOT_SUPPORTED
28
28
  }
29
29
  output_types = [Vulnerability]
30
+ install_pre = {
31
+ '*': ['curl']
32
+ }
30
33
  install_cmd = (
31
34
  f'curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b {CONFIG.dirs.bin}'
32
35
  )
secator/tasks/katana.py CHANGED
@@ -74,6 +74,9 @@ class katana(HttpCrawler):
74
74
  # TAGS: lambda x: x['response'].get('server')
75
75
  }
76
76
  }
77
+ install_pre = {
78
+ 'apk': ['libc6-compat']
79
+ }
77
80
  install_cmd = 'go install -v github.com/projectdiscovery/katana/cmd/katana@latest'
78
81
  install_github_handle = 'projectdiscovery/katana'
79
82
  proxychains = False
secator/tasks/mapcidr.py CHANGED
@@ -13,6 +13,9 @@ class mapcidr(ReconIp):
13
13
  cmd = 'mapcidr -silent'
14
14
  input_flag = '-cidr'
15
15
  file_flag = '-cl'
16
+ install_pre = {
17
+ 'apk': ['libc6-compat']
18
+ }
16
19
  install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@latest'
17
20
  install_github_handle = 'projectdiscovery/mapcidr'
18
21
  input_type = CIDR_RANGE
@@ -44,17 +44,16 @@ class msfconsole(VulnMulti):
44
44
  encoding = 'ansi'
45
45
  ignore_return_code = True
46
46
  install_pre = {
47
- 'apt|apk': ['libpq-dev', 'libpcap-dev', 'libffi-dev'],
48
- 'pacman': ['ruby-erb', 'postgresql-libs'],
49
- 'yum|zypper': ['postgresql-devel'],
47
+ 'apt|apk': ['libpq-dev', 'libpcap-dev', 'libffi-dev', 'g++', 'make'],
48
+ 'pacman': ['ruby-erb', 'postgresql-libs', 'make'],
49
+ 'yum|zypper': ['postgresql-devel', 'make'],
50
50
  }
51
51
  install_cmd = (
52
- f'git clone https://github.com/rapid7/metasploit-framework.git {CONFIG.dirs.share}/metasploit-framework || true && '
52
+ f'git clone --depth 1 --single-branch https://github.com/rapid7/metasploit-framework.git {CONFIG.dirs.share}/metasploit-framework || true && ' # noqa: E501
53
53
  f'cd {CONFIG.dirs.share}/metasploit-framework && '
54
54
  f'gem install bundler --user-install -n {CONFIG.dirs.bin} && '
55
- f'gem install xmlrpc --user-install -n {CONFIG.dirs.bin} && '
56
55
  f'bundle config set --local path "{CONFIG.dirs.share}" && '
57
- 'bundle update --bundler && '
56
+ 'bundle lock --normalize-platforms &&'
58
57
  'bundle install && '
59
58
  f'ln -sf $HOME/.local/share/metasploit-framework/msfconsole {CONFIG.dirs.bin}/msfconsole'
60
59
  )
secator/tasks/naabu.py CHANGED
@@ -49,8 +49,8 @@ class naabu(ReconPort):
49
49
  output_types = [Port]
50
50
  install_cmd = 'go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@latest'
51
51
  install_github_handle = 'projectdiscovery/naabu'
52
- install_pre = {'apt|apk': ['libpcap-dev'], 'pacman|brew': ['libpcap']}
53
- install_post = {'arch|alpine': 'sudo ln -s /usr/lib/libpcap.so /usr/lib/libpcap.so.0.8'}
52
+ install_pre = {'apt': ['libpcap-dev'], 'apk': ['libpcap-dev', 'libc6-compat'], 'pacman|brew': ['libpcap']}
53
+ install_post = {'arch|alpine': 'sudo ln -sf /usr/lib/libpcap.so /usr/lib/libpcap.so.0.8'}
54
54
  proxychains = False
55
55
  proxy_socks5 = True
56
56
  proxy_http = False
secator/tasks/nmap.py CHANGED
@@ -68,7 +68,7 @@ class nmap(VulnMulti):
68
68
  'apk': ['nmap', 'nmap-scripts'],
69
69
  }
70
70
  install_cmd = (
71
- 'sudo git clone https://github.com/scipag/vulscan /opt/scipag_vulscan || true && '
71
+ 'sudo git clone --depth 1 --single-branch https://github.com/scipag/vulscan /opt/scipag_vulscan || true && '
72
72
  'sudo ln -s /opt/scipag_vulscan /usr/share/nmap/scripts/vulscan || true'
73
73
  )
74
74
  proxychains = True
secator/tasks/nuclei.py CHANGED
@@ -74,6 +74,9 @@ class nuclei(VulnMulti):
74
74
  }
75
75
  }
76
76
  ignore_return_code = True
77
+ install_pre = {
78
+ '*': ['git']
79
+ }
77
80
  install_cmd = 'go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest'
78
81
  install_github_handle = 'projectdiscovery/nuclei'
79
82
  install_post = {
@@ -42,7 +42,7 @@ class searchsploit(Command):
42
42
  'apk': ['ncurses']
43
43
  }
44
44
  install_cmd = (
45
- f'git clone https://gitlab.com/exploit-database/exploitdb.git {CONFIG.dirs.share}/exploitdb || true && '
45
+ f'git clone --depth 1 --single-branch https://gitlab.com/exploit-database/exploitdb.git {CONFIG.dirs.share}/exploitdb || true && ' # noqa: E501
46
46
  f'ln -sf $HOME/.local/share/exploitdb/searchsploit {CONFIG.dirs.bin}/searchsploit'
47
47
  )
48
48
  proxychains = False
secator/tasks/wpscan.py CHANGED
@@ -68,8 +68,9 @@ class wpscan(VulnHttp):
68
68
  }
69
69
  output_types = [Vulnerability, Tag]
70
70
  install_pre = {
71
- 'apt': ['kali:libcurl4t64', 'libffi-dev'],
72
- 'pacman': ['ruby-erb'],
71
+ 'apt': ['make', 'kali:libcurl4t64', 'libffi-dev'],
72
+ 'pacman': ['make', 'ruby-erb'],
73
+ '*': ['make']
73
74
  }
74
75
  install_cmd = f'gem install wpscan --user-install -n {CONFIG.dirs.bin}'
75
76
  install_post = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secator
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Summary: The pentester's swiss knife.
5
5
  Project-URL: Homepage, https://github.com/freelabz/secator
6
6
  Project-URL: Issues, https://github.com/freelabz/secator/issues
@@ -2,11 +2,11 @@ secator/.gitignore,sha256=da8MUc3hdb6Mo0WjZu2upn5uZMbXcBGvhdhTQ1L89HI,3093
2
2
  secator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  secator/celery.py,sha256=Ry-JYJzN9F4LFHOn4IXpSFgCzpM99esKiQRJh_TkHp8,9578
4
4
  secator/celery_utils.py,sha256=iIuCn_3YkPXCtpnbaYqpppU2TARzSDyTIYHkrRyt54s,7725
5
- secator/cli.py,sha256=gIob9JjQJLtBhYYBErUpWucNqcd_LMEdMHMCurbITic,44012
5
+ secator/cli.py,sha256=rBExC1Lfzkgepwbhvad3XAlY8L_X5s_2uDw-w0kl1_0,43782
6
6
  secator/config.py,sha256=6wm2EErW1DuhrdKSuIEUvc2b3yBxJWyZKnocr7lIeZw,19267
7
7
  secator/decorators.py,sha256=tjH7WodxJEBIf2CCbegmvOe8H9DKSFh4iPLEhDNGPCA,13784
8
8
  secator/definitions.py,sha256=gFtLT9fjNtX_1qkiCjNfQyCvYq07IhScsQzX4o20_SE,3084
9
- secator/installer.py,sha256=ZK6iEc7cjaYn2lSpbSUkcLWwuu8cpGzhpnlgP-dGYiI,16272
9
+ secator/installer.py,sha256=3Ay9BTxdpOFOBxZud6bv7ozrTJi5ckZra4S0Qv0dLjo,17611
10
10
  secator/report.py,sha256=qJkEdCFttDBXIwUNUzZqFU_sG8l0PvyTSTogZVBv1Rs,3628
11
11
  secator/rich.py,sha256=3ugCkgai7UNylQGUuOVAd7ghYWDSc73aSomrfKgKVxo,3290
12
12
  secator/template.py,sha256=Qy4RjcmlifeSA8CleWUBb9fluxuYHzxgEH0H-8qs8R4,4323
@@ -67,10 +67,10 @@ secator/output_types/user_account.py,sha256=rm10somxyu30JHjj629IkR15Nhahylud_fVO
67
67
  secator/output_types/vulnerability.py,sha256=nF7OT9zGez8sZvLrkhjBOORjVi8hCqfCYUFq3eZ_ywo,2870
68
68
  secator/output_types/warning.py,sha256=47GtmG083GqGPb_R5JDFmARJ9Mqrme58UxwJhgdGPuI,853
69
69
  secator/runners/__init__.py,sha256=EBbOk37vkBy9p8Hhrbi-2VtM_rTwQ3b-0ggTyiD22cE,290
70
- secator/runners/_base.py,sha256=loCWdCiiP9CUUZlNu1hwropTCud7DwSGcnpgoS3drz8,28990
70
+ secator/runners/_base.py,sha256=tcTsL35dAHsIMfgcclTtvDk2kQM4Hhu-8IZTyHJgqTs,28973
71
71
  secator/runners/_helpers.py,sha256=FGogmmdHfCWmIyq7wRprwU1oOSxesOu3Y0N4GyAgiGw,2000
72
72
  secator/runners/celery.py,sha256=bqvDTTdoHiGRCt0FRvlgFHQ_nsjKMP5P0PzGbwfCj_0,425
73
- secator/runners/command.py,sha256=-2rqSfbPz2Q12otzshm3SIb4BVosIDpbvwh2KScoJ_M,24922
73
+ secator/runners/command.py,sha256=YDnPnEe7R_kemjPd13dRPKLYDPWqMiSI27K6l7Ag7ss,24992
74
74
  secator/runners/scan.py,sha256=tuPuqwL6fIS4UbCoy5WPKthYWm_LL-vCPRD2qK58HZE,1232
75
75
  secator/runners/task.py,sha256=JXlwo3DyQnu69RbQ8xvJnXu6y0rDYN-3iT4q4gy39tI,2004
76
76
  secator/runners/workflow.py,sha256=vry_MZFx6dRrorTrdsUqvhMZGOLPCdzpxkvN6fnt62w,3783
@@ -81,35 +81,35 @@ secator/serializers/json.py,sha256=UJwAymRzjF-yBKOgz1MTOyBhQcdQg7fOKRXgmHIu8fo,4
81
81
  secator/serializers/regex.py,sha256=fh-fE0RGvKSGKByFtwmKsWriRpZR9PXZQsY9JybHBWI,489
82
82
  secator/tasks/__init__.py,sha256=yRIZf9E47aS7o6rpgAJLgJUpX2cug1ofZeq8QsxgyjU,192
83
83
  secator/tasks/_categories.py,sha256=IWyBprIUBZxflh7QfvK27Ix18M_bnquzlERqfTZohVs,13821
84
- secator/tasks/bbot.py,sha256=RLI7fh8t16vxD0fwDY5HFDa5oneitrWH9ZkoN107bAQ,6884
84
+ secator/tasks/bbot.py,sha256=EBLOsI79nRxOdqL57OKJUTY9QXKKHOeqWA3gbQsMyWA,7128
85
85
  secator/tasks/bup.py,sha256=4PM123Km3uOkMUwfdLY6J7pyCqIsbwMvOLYx7XYCAZc,3030
86
86
  secator/tasks/cariddi.py,sha256=7S92pp7tvihoz9fAiMpmcfPzEvxEJKMlk-IqAvVDISA,2906
87
87
  secator/tasks/dalfox.py,sha256=hHQgYuZ7AGQCQtcN8hSM9uPnzeq1DSr_cpOxnn7-660,1850
88
88
  secator/tasks/dirsearch.py,sha256=DF-yXHANHb3ARgMOUbqpRuHc8-mE3bteHwTkFpXQtKc,2205
89
89
  secator/tasks/dnsx.py,sha256=nK14_DeyX0QTpAMdIP0LSSEOEu5_tQemyFW0XPjA2f8,2266
90
90
  secator/tasks/dnsxbrute.py,sha256=R2Fkc_OkO7vc-EyyvgRqvPCf9s11lHJE1TPEplsh_Pw,1423
91
- secator/tasks/feroxbuster.py,sha256=B1zbMGhanyziSWk5PonR7jDSP8oLKvJ-_DJFhj08xnM,2730
91
+ secator/tasks/feroxbuster.py,sha256=Hh2iNg-lwcvYQhCZuAiejFiAREYu46ebMfNIlZWcxsE,2774
92
92
  secator/tasks/ffuf.py,sha256=VGrtjFgSX6Q1I8h1wjPO5XwBFCfZXmn0DQsn9gxEUXc,2468
93
93
  secator/tasks/fping.py,sha256=m7eSXFU5yIeDD_kWh-h208ufSZAm4SpQzD34Ko0yCu8,1116
94
- secator/tasks/gau.py,sha256=MzgnImbkRjB_wI-7YPUnTgyMYbyKcderLagTO_20gPw,1602
94
+ secator/tasks/gau.py,sha256=1Qt0I_FqTh-QyJ0YR8I7i_T80HehWSvem_SS-TQKVm0,1648
95
95
  secator/tasks/gf.py,sha256=y8Fc0sRLGqNuwUjTBgLk3HEw3ZOnh09nB_GTufGErNA,962
96
96
  secator/tasks/gospider.py,sha256=KGINm9kxrq546xi1yN8_OwNCNDxSW9vVRYDAlvNajBs,2303
97
- secator/tasks/grype.py,sha256=8iTjI1ZTj-DQgozg-UoBfL-45Lt3Sz4wS4s9jBI-tE0,2411
97
+ secator/tasks/grype.py,sha256=xoOuldnHCrS0O1Y4IzjbSVvoX5eX-fLSZ74THdRC2so,2447
98
98
  secator/tasks/h8mail.py,sha256=wNukV-aB-bXPZNq7WL8n1nFgH5b5tGh6vOF80Yna33I,1934
99
99
  secator/tasks/httpx.py,sha256=5oI8vK7w94nsQlKs9Ve4yZsCmogbsiB5PqGarR3eIIM,5854
100
- secator/tasks/katana.py,sha256=yy07wReBubmjbvpmsx1nmAuKij7M8As8JovQU7_cSrM,5210
100
+ secator/tasks/katana.py,sha256=A0nnjKKT-A34LBtEuG25lWh5Ria4nwgo4Ti31403E-Q,5256
101
101
  secator/tasks/maigret.py,sha256=6anhBzB4lEM90Lk23cAD_ku7I_ghTpj0W0i3h6HARD8,2088
102
- secator/tasks/mapcidr.py,sha256=zYIlbjJadQY_g2X8hS5vK_789O_XfI2mkIH-Cs8y6hk,944
103
- secator/tasks/msfconsole.py,sha256=t3fo_Q47YEQE116j_2MNWqcHsxw4afZxxs_ThinjzGc,6414
104
- secator/tasks/naabu.py,sha256=zbaLY4CHcmCjOmRnB8c5unMv4_wyLLyCbas-vRm44DU,2047
105
- secator/tasks/nmap.py,sha256=r4TsWNF6mDT6Dni94hzDwZ_TPh3s-1VOV61W8NASvVs,12520
106
- secator/tasks/nuclei.py,sha256=8VRl3C7_wTHr3n3zA2E9rDJTMWXFeU6fRM71txiGQHo,4235
107
- secator/tasks/searchsploit.py,sha256=OrODcBdRcbGmA9qSMJjsWTXwAcCt0nwQYXKqEBdcPbY,3280
102
+ secator/tasks/mapcidr.py,sha256=56ocbaDmB5_C_ns-773CgZXGOKOtkI9q9xJs2Rlfqio,990
103
+ secator/tasks/msfconsole.py,sha256=TXVrvzSWw9Ncv2h9QJtaEinTMbps_z0zX1PFirERVho,6430
104
+ secator/tasks/naabu.py,sha256=29qFob5NOmoFC9gedG03Ogi7uc0dAXgl3azmcWlMbcI,2084
105
+ secator/tasks/nmap.py,sha256=Zu24sJHnlOf3NXLj3Ohi07-x7m-5Ajr5ULpNsUF-QT0,12546
106
+ secator/tasks/nuclei.py,sha256=o677F5yv3mfIlYEpKY5_W6CT2Dlt315DuFOsCjHLE5c,4270
107
+ secator/tasks/searchsploit.py,sha256=gvtLZbL2hzAZ07Cf0cSj2Qs0GvWK94XyHvoPFsetXu8,3321
108
108
  secator/tasks/subfinder.py,sha256=C6W5NnXT92OUB1aSS9IYseqdI3wDMAz70TOEl8X-o3U,1213
109
- secator/tasks/wpscan.py,sha256=LGw1DmomP4U83n3V6nyuPhXTd4t99dgrym7oL54JqHE,5495
109
+ secator/tasks/wpscan.py,sha256=dF6_dw-Qezd8DmpftGc9KpgrvIk3zDdVJW4mKUa7fe0,5527
110
110
  secator/workflows/__init__.py,sha256=ivpZHiYYlj4JqlXLRmB9cmAPUGdk8QcUrCRL34hIqEA,665
111
- secator-0.8.0.dist-info/METADATA,sha256=eZbs-L8h3DFG-A0iRlMl9WX2RIBz9u6THDukf0KuRCY,14791
112
- secator-0.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
113
- secator-0.8.0.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
114
- secator-0.8.0.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
115
- secator-0.8.0.dist-info/RECORD,,
111
+ secator-0.8.2.dist-info/METADATA,sha256=aUam1K6ZPF68PNsnFaHWl_uPZroANXRxg2fBWxy5cvQ,14791
112
+ secator-0.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
113
+ secator-0.8.2.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
114
+ secator-0.8.2.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
115
+ secator-0.8.2.dist-info/RECORD,,