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

Files changed (47) hide show
  1. secator/cli.py +2 -2
  2. secator/decorators.py +16 -10
  3. secator/definitions.py +5 -0
  4. secator/installer.py +10 -3
  5. secator/output_types/stat.py +3 -0
  6. secator/runners/_base.py +2 -2
  7. secator/runners/command.py +2 -0
  8. secator/tasks/_categories.py +11 -11
  9. secator/tasks/arjun.py +2 -1
  10. secator/tasks/bbot.py +3 -0
  11. secator/tasks/bup.py +2 -1
  12. secator/tasks/cariddi.py +2 -1
  13. secator/tasks/dalfox.py +2 -1
  14. secator/tasks/dirsearch.py +3 -1
  15. secator/tasks/dnsx.py +3 -1
  16. secator/tasks/dnsxbrute.py +2 -0
  17. secator/tasks/feroxbuster.py +3 -1
  18. secator/tasks/ffuf.py +3 -1
  19. secator/tasks/fping.py +3 -1
  20. secator/tasks/gau.py +3 -1
  21. secator/tasks/gf.py +2 -1
  22. secator/tasks/gitleaks.py +3 -1
  23. secator/tasks/gospider.py +2 -0
  24. secator/tasks/grype.py +3 -1
  25. secator/tasks/h8mail.py +2 -1
  26. secator/tasks/httpx.py +3 -1
  27. secator/tasks/katana.py +2 -0
  28. secator/tasks/maigret.py +3 -1
  29. secator/tasks/mapcidr.py +2 -1
  30. secator/tasks/msfconsole.py +4 -3
  31. secator/tasks/naabu.py +3 -1
  32. secator/tasks/nmap.py +2 -0
  33. secator/tasks/nuclei.py +3 -1
  34. secator/tasks/searchsploit.py +3 -1
  35. secator/tasks/subfinder.py +3 -1
  36. secator/tasks/testssl.py +2 -1
  37. secator/tasks/trivy.py +4 -1
  38. secator/tasks/wafw00f.py +2 -1
  39. secator/tasks/wpprobe.py +2 -1
  40. secator/tasks/wpscan.py +2 -1
  41. secator/utils.py +15 -11
  42. secator/utils_test.py +9 -3
  43. {secator-0.14.0.dist-info → secator-0.15.0.dist-info}/METADATA +10 -3
  44. {secator-0.14.0.dist-info → secator-0.15.0.dist-info}/RECORD +47 -47
  45. {secator-0.14.0.dist-info → secator-0.15.0.dist-info}/WHEEL +0 -0
  46. {secator-0.14.0.dist-info → secator-0.15.0.dist-info}/entry_points.txt +0 -0
  47. {secator-0.14.0.dist-info → secator-0.15.0.dist-info}/licenses/LICENSE +0 -0
secator/cli.py CHANGED
@@ -783,7 +783,7 @@ def report_list(workspace, runner_type, time_delta):
783
783
  @report.command('export')
784
784
  @click.argument('json_path', type=str)
785
785
  @click.option('--output-folder', '-of', type=str)
786
- @click.option('-output', '-o', type=str)
786
+ @click.option('-output', '-o', type=str, required=True)
787
787
  def report_export(json_path, output_folder, output):
788
788
  with open(json_path, 'r') as f:
789
789
  data = loads_dataclass(f.read())
@@ -1502,7 +1502,7 @@ def task(name, verbose, check):
1502
1502
  errors
1503
1503
  )
1504
1504
  check_test(
1505
- task.input_type,
1505
+ task.input_types,
1506
1506
  'Check task input type is set (cls.input_type)',
1507
1507
  'Task has no input_type attribute.',
1508
1508
  warnings,
secator/decorators.py CHANGED
@@ -271,7 +271,6 @@ def generate_cli_subcommand(cli_endpoint, func, **opts):
271
271
  def register_runner(cli_endpoint, config):
272
272
  name = config.name
273
273
  input_required = True
274
- input_type = 'targets'
275
274
  command_opts = {
276
275
  'no_args_is_help': True,
277
276
  'context_settings': {
@@ -282,37 +281,44 @@ def register_runner(cli_endpoint, config):
282
281
 
283
282
  if cli_endpoint.name == 'scan':
284
283
  runner_cls = Scan
284
+ input_required = False # allow targets from stdin
285
285
  short_help = config.description or ''
286
286
  short_help += f' [dim]alias: {config.alias}' if config.alias else ''
287
287
  command_opts.update({
288
288
  'name': name,
289
- 'short_help': short_help
289
+ 'short_help': short_help,
290
+ 'no_args_is_help': False
290
291
  })
292
+ input_types = config.input_types
291
293
 
292
294
  elif cli_endpoint.name == 'workflow':
293
295
  runner_cls = Workflow
296
+ input_required = False # allow targets from stdin
294
297
  short_help = config.description or ''
295
298
  short_help = f'{short_help:<55} [dim](alias)[/][bold cyan] {config.alias}' if config.alias else ''
296
299
  command_opts.update({
297
300
  'name': name,
298
- 'short_help': short_help
301
+ 'short_help': short_help,
302
+ 'no_args_is_help': False
299
303
  })
304
+ input_types = config.input_types
300
305
 
301
306
  elif cli_endpoint.name == 'task':
302
307
  runner_cls = Task
303
308
  input_required = False # allow targets from stdin
304
309
  task_cls = Task.get_task_class(config.name)
305
310
  task_category = get_command_category(task_cls)
306
- input_type = task_cls.input_type or 'targets'
307
- short_help = f'[magenta]{task_category:<15}[/]{task_cls.__doc__}'
311
+ short_help = f'[magenta]{task_category:<25}[/] {task_cls.__doc__}'
308
312
  command_opts.update({
309
313
  'name': name,
310
314
  'short_help': short_help,
311
315
  'no_args_is_help': False
312
316
  })
317
+ input_types = task_cls.input_types
313
318
 
314
319
  else:
315
320
  raise ValueError(f"Unrecognized runner endpoint name {cli_endpoint.name}")
321
+ input_types_str = '|'.join(input_types) if input_types else 'targets'
316
322
  options = get_command_options(config)
317
323
 
318
324
  # TODO: maybe allow this in the future
@@ -324,7 +330,7 @@ def register_runner(cli_endpoint, config):
324
330
  # for i in range(0, len(ctx.args), 2)
325
331
  # }
326
332
 
327
- @click.argument(input_type, required=input_required)
333
+ @click.argument(input_types_str, required=input_required)
328
334
  @decorate_command_options(options)
329
335
  @click.pass_context
330
336
  def func(ctx, **opts):
@@ -353,7 +359,7 @@ def register_runner(cli_endpoint, config):
353
359
  # opts.update(unknown_opts)
354
360
 
355
361
  # Expand input
356
- inputs = opts.pop(input_type)
362
+ inputs = opts.pop(input_types_str)
357
363
  inputs = expand_input(inputs, ctx)
358
364
 
359
365
  # Build hooks from driver name
@@ -420,10 +426,10 @@ def register_runner(cli_endpoint, config):
420
426
  runner.run()
421
427
 
422
428
  generate_cli_subcommand(cli_endpoint, func, **command_opts)
423
- generate_rich_click_opt_groups(cli_endpoint, name, input_type, options)
429
+ generate_rich_click_opt_groups(cli_endpoint, name, input_types, options)
424
430
 
425
431
 
426
- def generate_rich_click_opt_groups(cli_endpoint, name, input_type, options):
432
+ def generate_rich_click_opt_groups(cli_endpoint, name, input_types, options):
427
433
  sortorder = {
428
434
  'Execution': 0,
429
435
  'Output': 1,
@@ -434,7 +440,7 @@ def generate_rich_click_opt_groups(cli_endpoint, name, input_type, options):
434
440
  opt_group = [
435
441
  {
436
442
  'name': 'Targets',
437
- 'options': [input_type],
443
+ 'options': input_types,
438
444
  },
439
445
  ]
440
446
  for prefix in prefixes:
secator/definitions.py CHANGED
@@ -40,6 +40,9 @@ AUTO_CALIBRATION = 'auto_calibration'
40
40
  CONTENT_TYPE = 'content_type'
41
41
  CONTENT_LENGTH = 'content_length'
42
42
  CIDR_RANGE = 'cidr_range'
43
+ DOCKER_IMAGE = 'docker_image'
44
+ FILENAME = 'filename'
45
+ GIT_REPOSITORY = 'git_repository'
43
46
  CPES = 'cpes'
44
47
  CVES = 'cves'
45
48
  DELAY = 'delay'
@@ -62,6 +65,7 @@ MATCH_CODES = 'match_codes'
62
65
  MATCH_REGEX = 'match_regex'
63
66
  MATCH_SIZE = 'match_size'
64
67
  MATCH_WORDS = 'match_words'
68
+ ORG_NAME = 'org_name'
65
69
  OUTPUT_PATH = 'output_path'
66
70
  PATH = 'path'
67
71
  PERCENT = 'percent'
@@ -100,6 +104,7 @@ REFERENCE = 'reference'
100
104
  REFERENCES = 'references'
101
105
  SEVERITY = 'severity'
102
106
  TAGS = 'tags'
107
+ TECHNOLOGY = 'technology'
103
108
  WEBSERVER = 'webserver'
104
109
  WORDLIST = 'wordlist'
105
110
  WORDS = 'words'
secator/installer.py CHANGED
@@ -47,6 +47,7 @@ class InstallerStatus(Enum):
47
47
  @dataclass
48
48
  class Distribution:
49
49
  name: str
50
+ system: str
50
51
  pm_name: str
51
52
  pm_installer: str
52
53
  pm_finalizer: str
@@ -186,6 +187,8 @@ class SourceInstaller:
186
187
  install_cmd = config
187
188
  else:
188
189
  distribution = get_distro_config()
190
+ if not distribution.pm_installer:
191
+ return InstallerStatus.UNKNOWN_DISTRIBUTION
189
192
  for distros, command in config.items():
190
193
  if distribution.name in distros.split("|") or distros == '*':
191
194
  install_cmd = command
@@ -543,7 +546,7 @@ def get_distro_config():
543
546
  distrib = system
544
547
 
545
548
  if system == "Linux":
546
- distrib = distro.id() or distro.like()
549
+ distrib = distro.like() or distro.id()
547
550
 
548
551
  if distrib in ["ubuntu", "debian", "linuxmint", "popos", "kali"]:
549
552
  installer = "apt install -y --no-install-recommends"
@@ -573,12 +576,16 @@ def get_distro_config():
573
576
  else:
574
577
  installer = "scoop" # Alternative package manager for Windows
575
578
 
576
- manager = installer.split(' ')[0]
579
+ if not installer:
580
+ console.print(Error(message=f'Could not find installer for your distribution (system: {system}, distrib: {distrib})')) # noqa: E501
581
+
582
+ manager = installer.split(' ')[0] if installer else ''
577
583
  config = Distribution(
578
584
  pm_installer=installer,
579
585
  pm_finalizer=finalizer,
580
586
  pm_name=manager,
581
- name=distrib
587
+ name=distrib,
588
+ system=system
582
589
  )
583
590
  return config
584
591
 
@@ -25,6 +25,9 @@ class Stat(OutputType):
25
25
  _table_fields = ['name', 'pid', 'cpu', 'memory']
26
26
  _sort_by = ('name', 'pid')
27
27
 
28
+ def __str__(self) -> str:
29
+ return f'{self.name} [pid={self.pid}] [cpu={self.cpu:.2f}%] [memory={self.memory:.2f}%]'
30
+
28
31
  def __repr__(self) -> str:
29
32
  s = rf'[dim yellow3]📊 {self.name} \[pid={self.pid}] \[cpu={self.cpu:.2f}%] \[memory={self.memory:.2f}%]'
30
33
  if self.net_conns:
secator/runners/_base.py CHANGED
@@ -53,7 +53,7 @@ class Runner:
53
53
  """
54
54
 
55
55
  # Input field (mostly for tests and CLI)
56
- input_type = None
56
+ input_types = []
57
57
 
58
58
  # Output types
59
59
  output_types = []
@@ -831,7 +831,7 @@ class Runner:
831
831
  if isinstance(data, (OutputType, dict)):
832
832
  if getattr(data, 'toDict', None):
833
833
  data = data.toDict()
834
- data = json.dumps(data)
834
+ data = json.dumps(data, default=str)
835
835
  print(data, file=out)
836
836
 
837
837
  def _get_findings_count(self):
@@ -30,6 +30,8 @@ class Command(Runner):
30
30
  # Base cmd
31
31
  cmd = None
32
32
 
33
+ # Tags
34
+ tags = []
33
35
  # Meta options
34
36
  meta_opts = {}
35
37
 
@@ -73,19 +73,19 @@ OPTS_VULN = [
73
73
 
74
74
  class Http(Command):
75
75
  meta_opts = {k: OPTS[k] for k in OPTS_HTTP_CRAWLERS}
76
- input_type = URL
76
+ input_types = [URL]
77
77
  output_types = [Url]
78
78
 
79
79
 
80
80
  class HttpCrawler(Command):
81
81
  meta_opts = {k: OPTS[k] for k in OPTS_HTTP_CRAWLERS}
82
- input_type = URL
82
+ input_types = [URL]
83
83
  output_types = [Url]
84
84
 
85
85
 
86
86
  class HttpFuzzer(Command):
87
87
  meta_opts = {k: OPTS[k] for k in OPTS_HTTP_FUZZERS}
88
- input_type = URL
88
+ input_types = [URL]
89
89
  output_types = [Url]
90
90
 
91
91
 
@@ -99,22 +99,22 @@ class Recon(Command):
99
99
 
100
100
 
101
101
  class ReconDns(Recon):
102
- input_type = HOST
102
+ input_types = [HOST]
103
103
  output_types = [Subdomain]
104
104
 
105
105
 
106
106
  class ReconUser(Recon):
107
- input_type = USERNAME
107
+ input_types = [USERNAME]
108
108
  output_types = [UserAccount]
109
109
 
110
110
 
111
111
  class ReconIp(Recon):
112
- input_type = CIDR_RANGE
112
+ input_types = [CIDR_RANGE]
113
113
  output_types = [Ip]
114
114
 
115
115
 
116
116
  class ReconPort(Recon):
117
- input_type = IP
117
+ input_types = [IP]
118
118
  output_types = [Port]
119
119
 
120
120
 
@@ -434,15 +434,15 @@ class Vuln(Command):
434
434
 
435
435
 
436
436
  class VulnHttp(Vuln):
437
- input_type = HOST
437
+ input_types = [HOST]
438
438
 
439
439
 
440
440
  class VulnCode(Vuln):
441
- input_type = PATH
441
+ input_types = [PATH]
442
442
 
443
443
 
444
444
  class VulnMulti(Vuln):
445
- input_type = HOST
445
+ input_types = [HOST]
446
446
  output_types = [Vulnerability]
447
447
 
448
448
 
@@ -451,7 +451,7 @@ class VulnMulti(Vuln):
451
451
  #--------------#
452
452
 
453
453
  class Tagger(Command):
454
- input_type = URL
454
+ input_types = [URL]
455
455
  output_types = [Tag]
456
456
 
457
457
  #----------------#
secator/tasks/arjun.py CHANGED
@@ -14,8 +14,9 @@ from secator.utils import process_wordlist
14
14
  class arjun(Command):
15
15
  """HTTP Parameter Discovery Suite."""
16
16
  cmd = 'arjun'
17
+ tags = ['url', 'fuzz', 'params']
17
18
  input_flag = '-u'
18
- input_type = URL
19
+ input_types = [URL]
19
20
  version_flag = ' '
20
21
  opts = {
21
22
  'chunk_size': {'type': int, 'help': 'Control query/chunk size'},
secator/tasks/bbot.py CHANGED
@@ -2,6 +2,7 @@ import shutil
2
2
 
3
3
  from secator.config import CONFIG
4
4
  from secator.decorators import task
5
+ from secator.definitions import FILENAME, HOST, IP, ORG_NAME, PORT, URL, USERNAME
5
6
  from secator.runners import Command
6
7
  from secator.serializers import RegexSerializer
7
8
  from secator.output_types import Vulnerability, Port, Url, Record, Ip, Tag, Info, Error
@@ -177,8 +178,10 @@ def output_discriminator(self, item):
177
178
  class bbot(Command):
178
179
  """Multipurpose scanner."""
179
180
  cmd = 'bbot -y --allow-deadly --force'
181
+ tags = ['vuln', 'scan']
180
182
  json_flag = '--json'
181
183
  input_flag = '-t'
184
+ input_types = [HOST, IP, URL, PORT, ORG_NAME, USERNAME, FILENAME]
182
185
  file_flag = None
183
186
  version_flag = '--help'
184
187
  opts = {
secator/tasks/bup.py CHANGED
@@ -16,8 +16,9 @@ from secator.tasks._categories import Http
16
16
  class bup(Http):
17
17
  """40X bypasser."""
18
18
  cmd = 'bup'
19
+ tags = ['url', 'bypass']
19
20
  input_flag = '-u'
20
- input_type = URL
21
+ input_types = [URL]
21
22
  json_flag = '--jsonl'
22
23
  opt_prefix = '--'
23
24
  opts = {
secator/tasks/cariddi.py CHANGED
@@ -14,7 +14,8 @@ from secator.tasks._categories import HttpCrawler
14
14
  class cariddi(HttpCrawler):
15
15
  """Crawl endpoints, secrets, api keys, extensions, tokens..."""
16
16
  cmd = 'cariddi'
17
- input_type = URL
17
+ tags = ['url', 'crawl']
18
+ input_types = [URL]
18
19
  input_flag = OPT_PIPE_INPUT
19
20
  output_types = [Url, Tag]
20
21
  file_flag = OPT_PIPE_INPUT
secator/tasks/dalfox.py CHANGED
@@ -21,7 +21,8 @@ DALFOX_TYPE_MAP = {
21
21
  class dalfox(VulnHttp):
22
22
  """Powerful open source XSS scanning tool."""
23
23
  cmd = 'dalfox'
24
- input_type = URL
24
+ tags = ['url', 'fuzz']
25
+ input_types = [URL]
25
26
  input_flag = 'url'
26
27
  file_flag = 'file'
27
28
  # input_chunk_size = 1
@@ -9,7 +9,7 @@ from secator.definitions import (CONTENT_LENGTH, CONTENT_TYPE, DELAY, DEPTH,
9
9
  MATCH_CODES, MATCH_REGEX, MATCH_SIZE,
10
10
  MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED, OUTPUT_PATH, PROXY,
11
11
  RATE_LIMIT, RETRIES, STATUS_CODE,
12
- THREADS, TIMEOUT, USER_AGENT, WORDLIST)
12
+ THREADS, TIMEOUT, USER_AGENT, WORDLIST, URL)
13
13
  from secator.output_types import Url, Info, Error
14
14
  from secator.tasks._categories import HttpFuzzer
15
15
 
@@ -18,6 +18,8 @@ from secator.tasks._categories import HttpFuzzer
18
18
  class dirsearch(HttpFuzzer):
19
19
  """Advanced web path brute-forcer."""
20
20
  cmd = 'dirsearch'
21
+ tags = ['url', 'fuzz']
22
+ input_types = [URL]
21
23
  input_flag = '-u'
22
24
  file_flag = '-l'
23
25
  json_flag = '-O json'
secator/tasks/dnsx.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from secator.decorators import task
2
- from secator.definitions import (OPT_PIPE_INPUT, RATE_LIMIT, RETRIES, THREADS)
2
+ from secator.definitions import (HOST, OPT_PIPE_INPUT, RATE_LIMIT, RETRIES, THREADS)
3
3
  from secator.output_types import Record, Ip, Subdomain
4
4
  from secator.output_types.ip import IpProtocol
5
5
  from secator.tasks._categories import ReconDns
@@ -11,8 +11,10 @@ from secator.utils import extract_domain_info
11
11
  class dnsx(ReconDns):
12
12
  """dnsx is a fast and multi-purpose DNS toolkit designed for running various retryabledns library."""
13
13
  cmd = 'dnsx -resp -recon'
14
+ tags = ['dns', 'fuzz']
14
15
  json_flag = '-json'
15
16
  input_flag = OPT_PIPE_INPUT
17
+ input_types = [HOST]
16
18
  file_flag = OPT_PIPE_INPUT
17
19
  output_types = [Record, Ip, Subdomain]
18
20
  opt_key_map = {
@@ -11,8 +11,10 @@ from secator.utils import process_wordlist
11
11
  class dnsxbrute(ReconDns):
12
12
  """dnsx is a fast and multi-purpose DNS toolkit designed for running various library."""
13
13
  cmd = 'dnsx'
14
+ tags = ['dns', 'fuzz']
14
15
  json_flag = '-json'
15
16
  input_flag = '-domain'
17
+ input_types = [HOST]
16
18
  file_flag = '-domain'
17
19
  opt_key_map = {
18
20
  RATE_LIMIT: 'rate-limit',
@@ -6,7 +6,7 @@ from secator.definitions import (CONTENT_TYPE, DELAY, DEPTH, FILTER_CODES,
6
6
  MATCH_REGEX, MATCH_SIZE, MATCH_WORDS, METHOD,
7
7
  OPT_NOT_SUPPORTED, OPT_PIPE_INPUT, PROXY,
8
8
  RATE_LIMIT, RETRIES, STATUS_CODE,
9
- THREADS, TIMEOUT, USER_AGENT, WORDLIST, WORDS)
9
+ THREADS, TIMEOUT, USER_AGENT, WORDLIST, WORDS, URL)
10
10
  from secator.output_types import Url
11
11
  from secator.serializers import JSONSerializer
12
12
  from secator.tasks._categories import HttpFuzzer
@@ -16,6 +16,8 @@ from secator.tasks._categories import HttpFuzzer
16
16
  class feroxbuster(HttpFuzzer):
17
17
  """Simple, fast, recursive content discovery tool written in Rust"""
18
18
  cmd = 'feroxbuster --auto-bail --no-state'
19
+ tags = ['url', 'fuzz']
20
+ input_types = [URL]
19
21
  input_flag = '--url'
20
22
  input_chunk_size = 1
21
23
  file_flag = OPT_PIPE_INPUT
secator/tasks/ffuf.py CHANGED
@@ -7,7 +7,7 @@ from secator.definitions import (AUTO_CALIBRATION, CONTENT_LENGTH,
7
7
  MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
8
8
  PERCENT, PROXY, RATE_LIMIT, RETRIES,
9
9
  STATUS_CODE, THREADS, TIME, TIMEOUT,
10
- USER_AGENT, WORDLIST)
10
+ USER_AGENT, WORDLIST, URL)
11
11
  from secator.output_types import Progress, Url
12
12
  from secator.serializers import JSONSerializer, RegexSerializer
13
13
  from secator.tasks._categories import HttpFuzzer
@@ -19,6 +19,8 @@ FFUF_PROGRESS_REGEX = r':: Progress: \[(?P<count>\d+)/(?P<total>\d+)\] :: Job \[
19
19
  class ffuf(HttpFuzzer):
20
20
  """Fast web fuzzer written in Go."""
21
21
  cmd = 'ffuf -noninteractive'
22
+ tags = ['url', 'fuzz']
23
+ input_types = [URL]
22
24
  input_flag = '-u'
23
25
  input_chunk_size = 1
24
26
  file_flag = None
secator/tasks/fping.py CHANGED
@@ -11,8 +11,10 @@ from secator.tasks._categories import ReconIp
11
11
  class fping(ReconIp):
12
12
  """Send ICMP echo probes to network hosts, similar to ping, but much better."""
13
13
  cmd = 'fping -a'
14
+ tags = ['ip', 'recon']
14
15
  file_flag = '-f'
15
16
  input_flag = None
17
+ input_types = [IP]
16
18
  opt_prefix = '--'
17
19
  opt_key_map = {
18
20
  DELAY: 'period',
@@ -26,7 +28,7 @@ class fping(ReconIp):
26
28
  DELAY: lambda x: x * 1000, # convert s to ms
27
29
  TIMEOUT: lambda x: x * 1000 # convert s to ms
28
30
  }
29
- input_type = IP
31
+ input_types = [IP]
30
32
  output_types = [Ip]
31
33
  install_pre = {'*': ['fping']}
32
34
  ignore_return_code = True
secator/tasks/gau.py CHANGED
@@ -4,7 +4,7 @@ from secator.definitions import (DELAY, DEPTH, FILTER_CODES, FILTER_REGEX,
4
4
  HEADER, MATCH_CODES, MATCH_REGEX, MATCH_SIZE,
5
5
  MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
6
6
  OPT_PIPE_INPUT, PROXY, RATE_LIMIT, RETRIES,
7
- THREADS, TIMEOUT, USER_AGENT)
7
+ THREADS, TIMEOUT, USER_AGENT, URL)
8
8
  from secator.serializers import JSONSerializer
9
9
  from secator.tasks._categories import HttpCrawler
10
10
 
@@ -13,6 +13,8 @@ from secator.tasks._categories import HttpCrawler
13
13
  class gau(HttpCrawler):
14
14
  """Fetch known URLs from AlienVault's Open Threat Exchange, the Wayback Machine, Common Crawl, and URLScan."""
15
15
  cmd = 'gau'
16
+ tags = ['pattern', 'scan']
17
+ input_types = [URL]
16
18
  file_flag = OPT_PIPE_INPUT
17
19
  json_flag = '--json'
18
20
  opt_prefix = '--'
secator/tasks/gf.py CHANGED
@@ -8,6 +8,7 @@ from secator.tasks._categories import Tagger
8
8
  class gf(Tagger):
9
9
  """Wrapper around grep, to help you grep for things."""
10
10
  cmd = 'gf'
11
+ tags = ['pattern', 'scan']
11
12
  file_flag = OPT_PIPE_INPUT
12
13
  input_flag = OPT_PIPE_INPUT
13
14
  version_flag = OPT_NOT_SUPPORTED
@@ -17,7 +18,7 @@ class gf(Tagger):
17
18
  opt_key_map = {
18
19
  'pattern': ''
19
20
  }
20
- input_type = URL
21
+ input_types = [URL]
21
22
  install_cmd = (
22
23
  'go install -v github.com/tomnomnom/gf@latest && '
23
24
  'git clone https://github.com/1ndianl33t/Gf-Patterns $HOME/.gf || true'
secator/tasks/gitleaks.py CHANGED
@@ -5,7 +5,7 @@ import yaml
5
5
  from secator.config import CONFIG
6
6
  from secator.decorators import task
7
7
  from secator.runners import Command
8
- from secator.definitions import (OUTPUT_PATH)
8
+ from secator.definitions import (OUTPUT_PATH, PATH, GIT_REPOSITORY)
9
9
  from secator.utils import caml_to_snake
10
10
  from secator.output_types import Tag, Info, Error
11
11
 
@@ -14,6 +14,8 @@ from secator.output_types import Tag, Info, Error
14
14
  class gitleaks(Command):
15
15
  """Tool for detecting secrets like passwords, API keys, and tokens in git repos, files, and stdin."""
16
16
  cmd = 'gitleaks'
17
+ tags = ['secret', 'scan']
18
+ input_types = [PATH, GIT_REPOSITORY]
17
19
  input_flag = None
18
20
  json_flag = '-f json'
19
21
  opt_prefix = '--'
secator/tasks/gospider.py CHANGED
@@ -16,8 +16,10 @@ from secator.tasks._categories import HttpCrawler
16
16
  class gospider(HttpCrawler):
17
17
  """Fast web spider written in Go."""
18
18
  cmd = 'gospider'
19
+ tags = ['url', 'crawl']
19
20
  file_flag = '-S'
20
21
  input_flag = '-s'
22
+ input_types = [URL]
21
23
  json_flag = '--json'
22
24
  opt_prefix = '--'
23
25
  opt_key_map = {
secator/tasks/grype.py CHANGED
@@ -2,7 +2,7 @@ from secator.config import CONFIG
2
2
  from secator.decorators import task
3
3
  from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER,
4
4
  OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT, RETRIES,
5
- THREADS, TIMEOUT, USER_AGENT)
5
+ THREADS, TIMEOUT, USER_AGENT, PATH, DOCKER_IMAGE)
6
6
  from secator.output_types import Vulnerability
7
7
  from secator.tasks._categories import VulnCode
8
8
 
@@ -11,6 +11,8 @@ from secator.tasks._categories import VulnCode
11
11
  class grype(VulnCode):
12
12
  """Vulnerability scanner for container images and filesystems."""
13
13
  cmd = 'grype --quiet'
14
+ tags = ['vuln', 'scan']
15
+ input_types = [PATH, DOCKER_IMAGE]
14
16
  input_flag = ''
15
17
  file_flag = OPT_NOT_SUPPORTED
16
18
  json_flag = None
secator/tasks/h8mail.py CHANGED
@@ -11,9 +11,10 @@ from secator.output_types import UserAccount, Info, Error
11
11
  class h8mail(OSInt):
12
12
  """Email information and password lookup tool."""
13
13
  cmd = 'h8mail'
14
+ tags = ['user', 'recon', 'email']
14
15
  json_flag = '--json '
15
16
  input_flag = '--targets'
16
- input_type = EMAIL
17
+ input_types = [EMAIL]
17
18
  file_flag = '-domain'
18
19
  version_flag = '--help'
19
20
  opt_prefix = '--'
secator/tasks/httpx.py CHANGED
@@ -3,7 +3,7 @@ import os
3
3
  from secator.decorators import task
4
4
  from secator.definitions import (DELAY, DEPTH, FILTER_CODES, FILTER_REGEX, FILTER_SIZE, FILTER_WORDS, FOLLOW_REDIRECT,
5
5
  HEADER, MATCH_CODES, MATCH_REGEX, MATCH_SIZE, MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
6
- PROXY, RATE_LIMIT, RETRIES, THREADS, TIMEOUT, URL, USER_AGENT)
6
+ PROXY, RATE_LIMIT, RETRIES, THREADS, TIMEOUT, URL, USER_AGENT, HOST, IP)
7
7
  from secator.config import CONFIG
8
8
  from secator.output_types import Url, Subdomain
9
9
  from secator.serializers import JSONSerializer
@@ -15,8 +15,10 @@ from secator.utils import (sanitize_url, extract_domain_info, extract_subdomains
15
15
  class httpx(Http):
16
16
  """Fast and multi-purpose HTTP toolkit."""
17
17
  cmd = 'httpx'
18
+ tags = ['url', 'probe']
18
19
  file_flag = '-l'
19
20
  input_flag = '-u'
21
+ input_types = [HOST, IP, URL]
20
22
  json_flag = '-json'
21
23
  opts = {
22
24
  # 'silent': {'is_flag': True, 'default': False, 'help': 'Silent mode'},
secator/tasks/katana.py CHANGED
@@ -17,8 +17,10 @@ from secator.tasks._categories import HttpCrawler
17
17
  class katana(HttpCrawler):
18
18
  """Next-generation crawling and spidering framework."""
19
19
  cmd = 'katana'
20
+ tags = ['url', 'crawl']
20
21
  file_flag = '-list'
21
22
  input_flag = '-u'
23
+ input_types = [URL]
22
24
  json_flag = '-jsonl'
23
25
  opts = {
24
26
  'headless': {'is_flag': True, 'short': 'hl', 'help': 'Headless mode'},
secator/tasks/maigret.py CHANGED
@@ -17,8 +17,10 @@ logger = logging.getLogger(__name__)
17
17
  class maigret(ReconUser):
18
18
  """Collect a dossier on a person by username."""
19
19
  cmd = 'maigret'
20
+ tags = ['user', 'recon', 'username']
20
21
  file_flag = None
21
22
  input_flag = None
23
+ input_types = [USERNAME]
22
24
  json_flag = '--json ndjson'
23
25
  opt_prefix = '--'
24
26
  opts = {
@@ -32,7 +34,7 @@ class maigret(ReconUser):
32
34
  TIMEOUT: 'timeout',
33
35
  THREADS: OPT_NOT_SUPPORTED
34
36
  }
35
- input_type = USERNAME
37
+ input_types = [USERNAME]
36
38
  output_types = [UserAccount]
37
39
  output_map = {
38
40
  UserAccount: {
secator/tasks/mapcidr.py CHANGED
@@ -11,6 +11,7 @@ from secator.tasks._categories import ReconIp
11
11
  class mapcidr(ReconIp):
12
12
  """Utility program to perform multiple operations for a given subnet/cidr ranges."""
13
13
  cmd = 'mapcidr'
14
+ tags = ['ip', 'recon']
14
15
  input_flag = '-cidr'
15
16
  file_flag = '-cl'
16
17
  install_pre = {
@@ -19,7 +20,7 @@ class mapcidr(ReconIp):
19
20
  install_version = 'v1.1.34'
20
21
  install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@[install_version]'
21
22
  install_github_handle = 'projectdiscovery/mapcidr'
22
- input_type = CIDR_RANGE
23
+ input_types = [CIDR_RANGE]
23
24
  output_types = [Ip]
24
25
  opt_key_map = {
25
26
  THREADS: OPT_NOT_SUPPORTED,
@@ -6,8 +6,8 @@ from rich.panel import Panel
6
6
 
7
7
  from secator.config import CONFIG
8
8
  from secator.decorators import task
9
- from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER, HOST, OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT, RETRIES,
10
- THREADS, TIMEOUT, USER_AGENT)
9
+ from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER, HOST, IP, OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT,
10
+ RETRIES, THREADS, TIMEOUT, USER_AGENT, URL)
11
11
  from secator.tasks._categories import VulnMulti
12
12
  from secator.utils import get_file_timestamp
13
13
 
@@ -18,8 +18,9 @@ logger = logging.getLogger(__name__)
18
18
  class msfconsole(VulnMulti):
19
19
  """CLI to access and work with the Metasploit Framework."""
20
20
  cmd = 'msfconsole --quiet'
21
+ tags = ['exploit', 'attack']
21
22
  version_flag = OPT_NOT_SUPPORTED
22
- input_type = HOST
23
+ input_types = [HOST, IP, URL]
23
24
  input_chunk_size = 1
24
25
  output_types = []
25
26
  opt_prefix = '--'
secator/tasks/naabu.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from secator.decorators import task
2
- from secator.definitions import (DELAY, HOST, OPT_NOT_SUPPORTED, PORT, PORTS,
2
+ from secator.definitions import (DELAY, HOST, IP, OPT_NOT_SUPPORTED, PORT, PORTS,
3
3
  PROXY, RATE_LIMIT, RETRIES, STATE, THREADS,
4
4
  TIMEOUT, TOP_PORTS)
5
5
  from secator.output_types import Port
@@ -11,7 +11,9 @@ from secator.tasks._categories import ReconPort
11
11
  class naabu(ReconPort):
12
12
  """Port scanning tool written in Go."""
13
13
  cmd = 'naabu'
14
+ tags = ['port', 'scan']
14
15
  input_flag = '-host'
16
+ input_types = [HOST, IP]
15
17
  file_flag = '-list'
16
18
  json_flag = '-json'
17
19
  opts = {
secator/tasks/nmap.py CHANGED
@@ -24,7 +24,9 @@ logger = logging.getLogger(__name__)
24
24
  class nmap(VulnMulti):
25
25
  """Network Mapper is a free and open source utility for network discovery and security auditing."""
26
26
  cmd = 'nmap'
27
+ tags = ['port', 'scan']
27
28
  input_flag = None
29
+ input_types = [HOST, IP]
28
30
  input_chunk_size = 1
29
31
  file_flag = '-iL'
30
32
  opt_prefix = '--'
secator/tasks/nuclei.py CHANGED
@@ -4,7 +4,7 @@ from secator.definitions import (CONFIDENCE, CVSS_SCORE, DELAY, DESCRIPTION,
4
4
  MATCHED_AT, NAME, OPT_NOT_SUPPORTED, PERCENT,
5
5
  PROVIDER, PROXY, RATE_LIMIT, REFERENCES,
6
6
  RETRIES, SEVERITY, TAGS, THREADS, TIMEOUT,
7
- USER_AGENT)
7
+ USER_AGENT, HOST, URL)
8
8
  from secator.output_types import Progress, Vulnerability
9
9
  from secator.serializers import JSONSerializer
10
10
  from secator.tasks._categories import VulnMulti
@@ -14,6 +14,8 @@ from secator.tasks._categories import VulnMulti
14
14
  class nuclei(VulnMulti):
15
15
  """Fast and customisable vulnerability scanner based on simple YAML based DSL."""
16
16
  cmd = 'nuclei'
17
+ tags = ['vuln', 'scan']
18
+ input_types = [HOST, IP, URL]
17
19
  file_flag = '-l'
18
20
  input_flag = '-u'
19
21
  json_flag = '-jsonl'
@@ -3,7 +3,7 @@ import re
3
3
  from secator.config import CONFIG
4
4
  from secator.decorators import task
5
5
  from secator.definitions import (CVES, EXTRA_DATA, ID, MATCHED_AT, NAME,
6
- PROVIDER, REFERENCE, TAGS, OPT_NOT_SUPPORTED)
6
+ PROVIDER, REFERENCE, TAGS, TECHNOLOGY, OPT_NOT_SUPPORTED)
7
7
  from secator.output_types import Exploit
8
8
  from secator.runners import Command
9
9
  from secator.serializers import JSONSerializer
@@ -16,7 +16,9 @@ SEARCHSPLOIT_TITLE_REGEX = re.compile(r'^((?:[a-zA-Z\-_!\.()]+\d?\s?)+)\.?\s*(.*
16
16
  class searchsploit(Command):
17
17
  """Exploit searcher based on ExploitDB."""
18
18
  cmd = 'searchsploit'
19
+ tags = ['exploit', 'recon']
19
20
  input_flag = None
21
+ input_types = [TECHNOLOGY]
20
22
  json_flag = '--json'
21
23
  version_flag = OPT_NOT_SUPPORTED
22
24
  opts = {
@@ -1,5 +1,5 @@
1
1
  from secator.decorators import task
2
- from secator.definitions import (DELAY, DOMAIN, OPT_NOT_SUPPORTED, PROXY,
2
+ from secator.definitions import (DELAY, DOMAIN, HOST, OPT_NOT_SUPPORTED, PROXY,
3
3
  RATE_LIMIT, RETRIES, THREADS, TIMEOUT)
4
4
  from secator.output_types import Subdomain
5
5
  from secator.serializers import JSONSerializer
@@ -10,6 +10,8 @@ from secator.tasks._categories import ReconDns
10
10
  class subfinder(ReconDns):
11
11
  """Fast passive subdomain enumeration tool."""
12
12
  cmd = 'subfinder -cs'
13
+ tags = ['dns', 'recon']
14
+ input_types = [HOST]
13
15
  file_flag = '-dL'
14
16
  input_flag = '-d'
15
17
  json_flag = '-json'
secator/tasks/testssl.py CHANGED
@@ -15,7 +15,8 @@ from secator.tasks._categories import Command, OPTS
15
15
  class testssl(Command):
16
16
  """SSL/TLS security scanner, including ciphers, protocols and cryptographic flaws."""
17
17
  cmd = 'testssl.sh'
18
- input_type = HOST
18
+ tags = ['dns', 'recon', 'tls']
19
+ input_types = [HOST]
19
20
  input_flag = None
20
21
  file_flag = '-iL'
21
22
  file_eof_newline = True
secator/tasks/trivy.py CHANGED
@@ -5,7 +5,8 @@ import yaml
5
5
  from secator.config import CONFIG
6
6
  from secator.decorators import task
7
7
  from secator.definitions import (THREADS, OUTPUT_PATH, OPT_NOT_SUPPORTED, HEADER, DELAY, FOLLOW_REDIRECT,
8
- PROXY, RATE_LIMIT, RETRIES, TIMEOUT, USER_AGENT)
8
+ DOCKER_IMAGE, PATH, GIT_REPOSITORY, PROXY, RATE_LIMIT, RETRIES, TIMEOUT,
9
+ USER_AGENT)
9
10
  from secator.tasks._categories import Vuln
10
11
  from secator.output_types import Vulnerability, Tag, Info, Error
11
12
 
@@ -14,7 +15,9 @@ from secator.output_types import Vulnerability, Tag, Info, Error
14
15
  class trivy(Vuln):
15
16
  """Comprehensive and versatile security scanner."""
16
17
  cmd = 'trivy'
18
+ tags = ['vuln', 'scan']
17
19
  input_flag = None
20
+ input_types = [DOCKER_IMAGE, PATH, GIT_REPOSITORY]
18
21
  json_flag = '-f json'
19
22
  opts = {
20
23
  "mode": {"type": click.Choice(['image', 'fs', 'repo']), 'default': 'image', 'help': 'Trivy mode', 'required': True} # noqa: E501
secator/tasks/wafw00f.py CHANGED
@@ -12,7 +12,8 @@ from secator.tasks._categories import OPTS
12
12
  class wafw00f(Command):
13
13
  """Web Application Firewall Fingerprinting tool."""
14
14
  cmd = 'wafw00f'
15
- input_type = URL
15
+ tags = ['waf', 'scan']
16
+ input_types = [URL]
16
17
  input_flag = None
17
18
  file_flag = '-i'
18
19
  json_flag = '-f json'
secator/tasks/wpprobe.py CHANGED
@@ -12,9 +12,10 @@ from secator.tasks._categories import OPTS
12
12
  class wpprobe(Command):
13
13
  """Fast wordpress plugin enumeration tool."""
14
14
  cmd = 'wpprobe'
15
+ tags = ['vuln', 'scan', 'wordpress']
15
16
  file_flag = '-f'
16
17
  input_flag = '-u'
17
- input_type = URL
18
+ input_types = [URL]
18
19
  opt_prefix = '-'
19
20
  opts = {
20
21
  'mode': {'type': click.Choice(['scan', 'update', 'update-db']), 'default': 'scan', 'help': 'WPProbe mode', 'required': True, 'internal': True}, # noqa: E501
secator/tasks/wpscan.py CHANGED
@@ -17,9 +17,10 @@ from secator.tasks._categories import VulnHttp
17
17
  class wpscan(VulnHttp):
18
18
  """Wordpress security scanner."""
19
19
  cmd = 'wpscan --force --verbose'
20
+ tags = ['vuln', 'scan', 'wordpress']
20
21
  file_flag = None
21
22
  input_flag = '--url'
22
- input_type = URL
23
+ input_types = [URL]
23
24
  json_flag = '-f json'
24
25
  opt_prefix = '--'
25
26
  opts = {
secator/utils.py CHANGED
@@ -164,7 +164,8 @@ def discover_internal_tasks():
164
164
  # Sort task_classes by category
165
165
  task_classes = sorted(
166
166
  task_classes,
167
- key=lambda x: (get_command_category(x), x.__name__))
167
+ # key=lambda x: (get_command_category(x), x.__name__)
168
+ key=lambda x: x.__name__)
168
169
 
169
170
  return task_classes
170
171
 
@@ -262,9 +263,9 @@ def get_command_category(command):
262
263
  Returns:
263
264
  str: Command category.
264
265
  """
265
- base_cls = command.__bases__[0].__name__.replace('Command', '').replace('Runner', 'misc')
266
- category = re.sub(r'(?<!^)(?=[A-Z])', '/', base_cls).lower()
267
- return category
266
+ if not command.tags:
267
+ return 'misc'
268
+ return '/'.join(command.tags)
268
269
 
269
270
 
270
271
  def merge_opts(*options):
@@ -309,6 +310,8 @@ def pluralize(word):
309
310
  """
310
311
  if word.endswith('y'):
311
312
  return word.rstrip('y') + 'ies'
313
+ elif word.endswith('s'):
314
+ return word + 'es'
312
315
  return f'{word}s'
313
316
 
314
317
 
@@ -418,15 +421,16 @@ def format_object(obj, obj_breaklines=False):
418
421
 
419
422
  def debug(msg, sub='', id='', obj=None, lazy=None, obj_after=True, obj_breaklines=False, verbose=False):
420
423
  """Print debug log if DEBUG >= level."""
421
- if not DEBUG_COMPONENT or DEBUG_COMPONENT == [""]:
422
- return
423
-
424
- if sub:
425
- if verbose and sub not in DEBUG_COMPONENT:
426
- sub = f'debug.{sub}'
427
- if not any(sub.startswith(s) for s in DEBUG_COMPONENT):
424
+ if not DEBUG_COMPONENT == ['all']:
425
+ if not DEBUG_COMPONENT or DEBUG_COMPONENT == [""]:
428
426
  return
429
427
 
428
+ if sub:
429
+ if verbose and sub not in DEBUG_COMPONENT:
430
+ sub = f'debug.{sub}'
431
+ if not any(sub.startswith(s) for s in DEBUG_COMPONENT):
432
+ return
433
+
430
434
  if lazy:
431
435
  msg = lazy(msg)
432
436
 
secator/utils_test.py CHANGED
@@ -9,7 +9,8 @@ from fp.fp import FreeProxy
9
9
  from secator.definitions import (CIDR_RANGE, DELAY, DEPTH, EMAIL,
10
10
  FOLLOW_REDIRECT, HEADER, HOST, IP, MATCH_CODES,
11
11
  METHOD, PROXY, RATE_LIMIT, RETRIES,
12
- THREADS, TIMEOUT, URL, USER_AGENT, USERNAME)
12
+ THREADS, TIMEOUT, URL, USER_AGENT, USERNAME, PATH,
13
+ DOCKER_IMAGE, GIT_REPOSITORY)
13
14
  from secator.cli import ALL_WORKFLOWS, ALL_TASKS, ALL_SCANS
14
15
  from secator.output_types import EXECUTION_TYPES, STAT_TYPES
15
16
  from secator.runners import Command
@@ -61,7 +62,9 @@ INPUTS_TASKS = {
61
62
  IP: '192.168.1.23',
62
63
  CIDR_RANGE: '192.168.1.0/24',
63
64
  EMAIL: 'fake@fake.com',
64
- 'folder': '.'
65
+ PATH: '.',
66
+ DOCKER_IMAGE: 'redis:latest',
67
+ GIT_REPOSITORY: 'https://github.com/freelabz/secator',
65
68
  }
66
69
 
67
70
  #---------------------#
@@ -165,7 +168,7 @@ class CommandOutputTester: # Mixin for unittest.TestCase
165
168
  expected_status='SUCCESS',
166
169
  empty_results_allowed=False):
167
170
 
168
- console.print(f'[dim]Testing {runner.config.type} {runner.name} ...[/]', end='')
171
+ console.print(f'\t[dim]Testing {runner.config.type} {runner.name} ...[/]', end='')
169
172
  debug('', sub='unittest')
170
173
 
171
174
  if not runner.inputs:
@@ -176,6 +179,8 @@ class CommandOutputTester: # Mixin for unittest.TestCase
176
179
  console.print('[dim gold3] (no outputs defined).[/]', end='')
177
180
 
178
181
  try:
182
+ debug(f'{runner.name} starting command: {runner.cmd}', sub='unittest') if isinstance(runner, Command) else None
183
+
179
184
  # Run runner
180
185
  results = runner.run()
181
186
  for result in results:
@@ -202,6 +207,7 @@ class CommandOutputTester: # Mixin for unittest.TestCase
202
207
  # Check results
203
208
  for item in results:
204
209
  debug(f'{runner.name} yielded {repr(item)}', sub='unittest')
210
+ debug(f'{runner.name} yielded (JSON): {json.dumps(item.toDict(), default=str)}', sub='unittest.dict', verbose=True)
205
211
 
206
212
  if expected_output_types:
207
213
  debug(f'{runner.name} item should have an output type in {[_._type for _ in expected_output_types]}', sub='unittest') # noqa: E501
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secator
3
- Version: 0.14.0
3
+ Version: 0.15.0
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
@@ -82,7 +82,7 @@ Description-Content-Type: text/markdown
82
82
  <a href="https://pypi.org/project/secator/"><img src="https://img.shields.io/pypi/dm/secator"></a>
83
83
  <a href="https://twitter.com/freelabz"><img src="https://img.shields.io/twitter/follow/freelabz.svg?logo=twitter"></a>
84
84
  <a href="https://youtube.com/@FreeLabz"><img src="https://img.shields.io/youtube/channel/subscribers/UCu-F6SpU0h2NP18zBBP04cw?style=social&label=Subscribe%20%40FreeLabz"></a>
85
- <!-- <a href="https://discord.gg/freelabz"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a> -->
85
+ <a href="https://discord.gg/nyHjC2aTrq"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
86
86
  </p>
87
87
 
88
88
 
@@ -91,7 +91,8 @@ Description-Content-Type: text/markdown
91
91
  <a href="#supported-commands">Supported commands</a> •
92
92
  <a href="#install-secator">Installation</a> •
93
93
  <a href="#usage">Usage</a> •
94
- <a href="https://docs.freelabz.com">Documentation</a>
94
+ <a href="https://docs.freelabz.com">Documentation</a>
95
+ <a href="https://discord.gg/nyHjC2aTrq">Join us on Discord !</a>
95
96
  </p>
96
97
 
97
98
  `secator` is a task and workflow runner used for security assessments. It supports dozens of well-known security tools
@@ -122,6 +123,11 @@ and it is designed to improve productivity for pentesters and security researche
122
123
 
123
124
  | Name | Description | Category |
124
125
  |---------------------------------------------------------------|--------------------------------------------------------------------------------|-----------------|
126
+ | [arjun](https://github.com/s0md3v/Arjun) | HTTP Parameter Discovery Suite. | |
127
+ | [gitleaks](https://github.com/gitleaks/gitleaks) | Tool for detecting secrets like passwords, API keys, tokens, etc. | |
128
+ | [testssl](https://github.com/testssl/testssl.sh) | SSL/TLS security scanner, including ciphers, protocols and cryptographic flaws.| |
129
+ | [wafw00f](https://github.com/EnableSecurity/wafw00f) | Web Application Firewall Fingerprinting tool. | |
130
+ | [wpprobe](https://github.com/Chocapikk/wpprobe) | Fast wordpress plugin enumeration tool. | |
125
131
  | [httpx](https://github.com/projectdiscovery/httpx) | Fast HTTP prober. | `http` |
126
132
  | [cariddi](https://github.com/edoardottt/cariddi) | Fast crawler and endpoint secrets / api keys / tokens matcher. | `http/crawler` |
127
133
  | [gau](https://github.com/lc/gau) | Offline URL crawler (Alien Vault, The Wayback Machine, Common Crawl, URLScan). | `http/crawler` |
@@ -139,6 +145,7 @@ and it is designed to improve productivity for pentesters and security researche
139
145
  | [naabu](https://github.com/projectdiscovery/naabu) | Fast port discovery tool. | `recon/port` |
140
146
  | [maigret](https://github.com/soxoj/maigret) | Hunt for user accounts across many websites. | `recon/user` |
141
147
  | [gf](https://github.com/tomnomnom/gf) | A wrapper around grep to avoid typing common patterns. | `tagger` |
148
+ | [trivy](https://github.com/aquasecurity/trivy) | Comprehensive and versatile security scanner. | `vuln` |
142
149
  | [grype](https://github.com/anchore/grype) | A vulnerability scanner for container images and filesystems. | `vuln/code` |
143
150
  | [dalfox](https://github.com/hahwul/dalfox) | Powerful XSS scanning tool and parameter analyzer. | `vuln/http` |
144
151
  | [msfconsole](https://docs.rapid7.com/metasploit/msf-overview) | CLI to access and work with the Metasploit Framework. | `vuln/http` |
@@ -3,17 +3,17 @@ secator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  secator/celery.py,sha256=Xg8e0zpQu4_-jlsZeC65NZtkopHGsGIyQ3SiW5fyH4E,9771
4
4
  secator/celery_signals.py,sha256=hG62Gr34xKJYZTgZFn_wZcsAlMgKuTazQhx55FC5cDA,4259
5
5
  secator/celery_utils.py,sha256=_wcUC42VPUotPhh9YYqbuq0dkARI8_RoCklDlhQL9Jg,8903
6
- secator/cli.py,sha256=76DSAyg0wZ4AraKwiEr7beoPNvQZjPgtz4IMEEP8UPs,51465
6
+ secator/cli.py,sha256=OYdEZtJA3ocdCzIlbAyyDo-5v_mj1Otz5FoJwO6brpE,51481
7
7
  secator/config.py,sha256=t3RJhfVKIoEcfDWBsYlFzz29BM3dsvJtGFzwTYL0Cfc,19727
8
- secator/decorators.py,sha256=tTDXNNkEQrOF4jx1UgiOD_pxMnk0LX0R41ALALOx3jk,14668
9
- secator/definitions.py,sha256=qE_ZjzGcfrdASL7wjrc_0zoszUovL00KP--kGjDr93w,2986
10
- secator/installer.py,sha256=UBlQdcTvYXjmCiTui_fk9DOOxJ4Vs8i70m0ZCVFV78Q,19633
8
+ secator/decorators.py,sha256=AFuAQKBDkdPtBIrFvYqYgIkJqAXJHYnDgB6r8o-SHzI,14950
9
+ secator/definitions.py,sha256=MEQUx8lSVszfJ5lNcEYyLGj-G4ZHyGWTBtVnK4Fgb9Y,3120
10
+ secator/installer.py,sha256=pho7XsBq8wkr6A9Nq4grARCUaUakcfjjKksZvNP4Zbc,19924
11
11
  secator/report.py,sha256=eWD8KgkXXZY_2cpu3xJY-ZuIkU60_UB62C79S69nDJM,3617
12
12
  secator/rich.py,sha256=0P6TECNePsfivc5h1JsJoAqKmpFnME5m8k29ZJjvbwM,3277
13
13
  secator/template.py,sha256=o2igSFcNRWqptg8Rg00m8tvMmVAvbpnnvooWynk1LVI,4567
14
14
  secator/thread.py,sha256=rgRgEtcMgs2wyfLWVlCTUCLWeg6jsMo5iKpyyrON5rY,655
15
- secator/utils.py,sha256=kaBqWgBmUZohlvn6nFY805tG26viIu_LdJysNfZWMY4,22055
16
- secator/utils_test.py,sha256=jiCvgL4JMhIC1-ZGe6j9umNRZreSDp6nlkMgEJhf5ho,7996
15
+ secator/utils.py,sha256=fiW9EcU7Kn4hQsgESYF_MnlwvoZk21e_9kUQ8TlnEDU,22073
16
+ secator/utils_test.py,sha256=EiGi29K4jT9xitCJRn0Ud5KbU1PKLdqAnO7YROK9Ll0,8364
17
17
  secator/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  secator/configs/profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  secator/configs/profiles/aggressive.yaml,sha256=CXsCD76zrS93Iy47H-SUeEm3Ofl58H12dOr6rhm5sUg,159
@@ -64,7 +64,7 @@ secator/output_types/ip.py,sha256=CyE3qkp55Kmj5YRl0CZGS4XrHX8N5apWrLN3OMzaK0U,11
64
64
  secator/output_types/port.py,sha256=JdqXnEF8XuwaWFMT8Vghj7fKLwtsImuUdRfMmITgmWM,1879
65
65
  secator/output_types/progress.py,sha256=MIbmnrLHNodLL42UgiaqLHL0OG5-w6mtUrhn0ZhksjA,1343
66
66
  secator/output_types/record.py,sha256=HnsKxlIhkgswA_Yjz7BZ1vDjP53l6OJ0BCOtCSDwCSY,1250
67
- secator/output_types/stat.py,sha256=90oN2Ghc4k0B0FOdp6MOWiNgmXMmLHYknjunDeEKKRE,1129
67
+ secator/output_types/stat.py,sha256=7ZNWgfrJWONKeJx931eEFngEV4WhJaHs38AUUxxhZC8,1248
68
68
  secator/output_types/state.py,sha256=-kQs_P-v_d_J8mgMRJA9Pa0SaOVHN__Fq_ateDc0tiA,1038
69
69
  secator/output_types/subdomain.py,sha256=ivJ_2kmrJ8hdB8wmvRJYlKV1BcE3Cds_vAI_5wL7ES4,1344
70
70
  secator/output_types/tag.py,sha256=_XEqWAvAvmi7nd2ldfEE71zQx97jTSph2iDHkeqGTyk,1470
@@ -74,10 +74,10 @@ secator/output_types/user_account.py,sha256=EvF3Ebg9eXS_-iDguU1dSHZ9wAsJimEJznDv
74
74
  secator/output_types/vulnerability.py,sha256=nF7OT9zGez8sZvLrkhjBOORjVi8hCqfCYUFq3eZ_ywo,2870
75
75
  secator/output_types/warning.py,sha256=47GtmG083GqGPb_R5JDFmARJ9Mqrme58UxwJhgdGPuI,853
76
76
  secator/runners/__init__.py,sha256=EBbOk37vkBy9p8Hhrbi-2VtM_rTwQ3b-0ggTyiD22cE,290
77
- secator/runners/_base.py,sha256=XeH48AJvBKn3Z5qxbBmnL81jASWvIihBxPojw9Tyk-U,32629
77
+ secator/runners/_base.py,sha256=M9IL8S_U4rcp6j_C_aFEjMpmAzVWQ9mjSMQbHAo_7Y8,32641
78
78
  secator/runners/_helpers.py,sha256=FoawlexiNl1-QMBfwBx0p4Hi7rGZxHe_RAMahqZuJ0Y,2883
79
79
  secator/runners/celery.py,sha256=bqvDTTdoHiGRCt0FRvlgFHQ_nsjKMP5P0PzGbwfCj_0,425
80
- secator/runners/command.py,sha256=aAM_VZB9ZDtSYhg52PUlBJIkiqUcNb895Xuef6lIkF8,26900
80
+ secator/runners/command.py,sha256=JVnk5yLgOSsnmqyQgVG_A_S3GHV56jpKrcQhC2ftGVg,26919
81
81
  secator/runners/scan.py,sha256=jDPT9lnb2bGShvTClQ9u9SVRcHzZnXU1v308H7Fc-RE,1656
82
82
  secator/runners/task.py,sha256=3wudRz8TdvkonnllaeLYLFztNlyXrMQ3E31t5lCRPkk,2066
83
83
  secator/runners/workflow.py,sha256=sO3B9GcndQLgGPnDz-A6XKnBmYO_ABAU_UXpW-q1K1A,3890
@@ -87,42 +87,42 @@ secator/serializers/dataclass.py,sha256=RqICpfsYWGjHAACAA2h2jZ_69CFHim4VZwcBqowG
87
87
  secator/serializers/json.py,sha256=UJwAymRzjF-yBKOgz1MTOyBhQcdQg7fOKRXgmHIu8fo,411
88
88
  secator/serializers/regex.py,sha256=fh-fE0RGvKSGKByFtwmKsWriRpZR9PXZQsY9JybHBWI,489
89
89
  secator/tasks/__init__.py,sha256=yRIZf9E47aS7o6rpgAJLgJUpX2cug1ofZeq8QsxgyjU,192
90
- secator/tasks/_categories.py,sha256=VWbBCksIYOxlrIKIHYtQpzYlvLh019w4S_nKbgC53Ko,14358
91
- secator/tasks/arjun.py,sha256=SwTLILvjx8rOKrsgyEKVzYdYTRX7CvgjVatMPBsC2bM,2900
92
- secator/tasks/bbot.py,sha256=NoJYxxy4l_xP-ZMAOxAK7nPxHFH5raGBo82y3SfWppM,7939
93
- secator/tasks/bup.py,sha256=Gl6W3UAJKGJcQ62ACN88v0_6jDA4gZgJXEk6TgiDmQE,3050
94
- secator/tasks/cariddi.py,sha256=1LoMmqNPNyI-v0MCt5TIQQoTuNoGpK_x6uoAV2x8GiE,3534
95
- secator/tasks/dalfox.py,sha256=gPsLI4esyvzHpNW0UlRH-W5-sUOldJjdA0Ffq59QmP4,1879
96
- secator/tasks/dirsearch.py,sha256=Mq_4kqNK5a5KfrvPnf081qI8YAxMAQ571zz5MIPCgG0,2209
97
- secator/tasks/dnsx.py,sha256=SDf3zudkO69qZmOASDjA82XyEo0pbWUaC0ADLcn24m0,2305
98
- secator/tasks/dnsxbrute.py,sha256=6NJDVrXU4yirL5qMZXi0ccwHIAGil__kgteES_Oc6qg,1464
99
- secator/tasks/feroxbuster.py,sha256=9rQYL_AZNSmzOdeHpWTva6Y6cwAedKWrs3UWNW8ErCE,2769
100
- secator/tasks/ffuf.py,sha256=5yRkZFZtOdQkJQNE-wy_QuqlhAuM6HCpWJEY6BJ3JeM,2593
101
- secator/tasks/fping.py,sha256=OFF_uR3YzXhQJcb-ObdY178cHHjnJBPXtjMjdzVSlGI,1116
102
- secator/tasks/gau.py,sha256=lfS9j49AXADK_Syeuo078-QS0acCj51JKRO9YnfpldA,1687
103
- secator/tasks/gf.py,sha256=y8Fc0sRLGqNuwUjTBgLk3HEw3ZOnh09nB_GTufGErNA,962
104
- secator/tasks/gitleaks.py,sha256=Md9l4KfS40Enoz6WVdGe_Hf1MOXxbSWFLFmC_D1Ta7c,2583
105
- secator/tasks/gospider.py,sha256=4awtr0SlJPEQQD-Oap9gHWhY1qktW89wgXwOgi5X7Us,2309
106
- secator/tasks/grype.py,sha256=t1pOXLOrhcbHjTCNlaf7mEcKXyzkOSXwX1XSz0u95Mw,2485
107
- secator/tasks/h8mail.py,sha256=dvj9B-2VxhTfv4Ijwia2RWnje2rwsMNzWn5hRQvpWqk,1965
108
- secator/tasks/httpx.py,sha256=qf8MqMVui-UWV4jHsvreDMKjpHIPlkbYzZUihPw6m24,5935
109
- secator/tasks/katana.py,sha256=hXUN5VxwYPQLGB4WW6x46vowNlvQ583IvLQ3CCtTrK8,5396
110
- secator/tasks/maigret.py,sha256=s_UOa_K72edN0HEdo0VeYu_Rff7mER611-Y_08_OXBY,2096
111
- secator/tasks/mapcidr.py,sha256=jCJb_3kQomcoWNl8o3D-oZqUzTJeg1d_vKLF1oLTlGk,1022
112
- secator/tasks/msfconsole.py,sha256=XSW3WRx6LyCNlCD7JebgDQroNAnY4yFQQQHPxPa1J4Y,6533
113
- secator/tasks/naabu.py,sha256=DpnQHpgOh-Ob0EKQ3Q6n6tgqauc2UmlyS6Ges0itApU,2357
114
- secator/tasks/nmap.py,sha256=ZQJnlratjEqASHXb05QYknX2J1gWaZAN3-O4Y1Dw3UA,16970
115
- secator/tasks/nuclei.py,sha256=jdb8VVYpccUdzbEPfK0K7lYmLggusNe8HWRq8wKSftE,4965
116
- secator/tasks/searchsploit.py,sha256=gw5Wh6T20txSGoBrOs60xtRRfDS6c_oecMcU-vKnZWQ,3410
117
- secator/tasks/subfinder.py,sha256=lnizwljCX_FZ04wi69TEwbBf8kZccddx3rA6UKGQDWA,1244
118
- secator/tasks/testssl.py,sha256=Bi8qmlvGvXh8idQpPBE8BOvkWS5hClA2-wVVnz9rypY,11601
119
- secator/tasks/trivy.py,sha256=qGhNT3296aJvvaQx82L2K9oPdPVbNLZ5DCY4T8nrdaE,3197
120
- secator/tasks/wafw00f.py,sha256=XeYl6ppS_YA-SmhBNdNcFmgUWYmiCnzU7TTLfxUTcRo,2747
121
- secator/tasks/wpprobe.py,sha256=Dx-HcGYjWyyeIsHwkstlcxPKJ5GR6jP9TMTHeV6SXPo,4025
122
- secator/tasks/wpscan.py,sha256=QrEO6ZrkmC3TDtD91Aeqip8qrcsrK7filHKpRdcteJU,5755
90
+ secator/tasks/_categories.py,sha256=VveGn1ecX1LacFXdCQktMgVLwX6DGvse1jbW-FZR3cs,14391
91
+ secator/tasks/arjun.py,sha256=2bU-gSAH3447qs80IOgGmn1ogwo2sDeh6HgOO8UZHg8,2937
92
+ secator/tasks/bbot.py,sha256=iPxfK1X0CiYBl_fuv1JOGE2y6uubryeWfnkYL1eo2hc,8113
93
+ secator/tasks/bup.py,sha256=FpB7unh1hVrfeDEw7HlXTPO7Iypi9Wh-QjiPaMQOmSQ,3079
94
+ secator/tasks/cariddi.py,sha256=FmJ1zPjaZYm5rw0uNzmiSXhEVLBPXKSzGnYTKDX__D8,3562
95
+ secator/tasks/dalfox.py,sha256=Ifph-NNBVnS0byCYxJTXD2ggSUedbfJ50rXQV-STlkk,1906
96
+ secator/tasks/dirsearch.py,sha256=41rUvkc3bhoGEnsKmVJPVlCVpKYCkOMAy8Y3uuMfxOc,2259
97
+ secator/tasks/dnsx.py,sha256=YTVzu7br9o9VTRI9LM89QxoxyqtBwTm1ADA76UvETI0,2357
98
+ secator/tasks/dnsxbrute.py,sha256=KeQ20ZW2LnlnAfTkpnLecSWNWsIIH2LQFJc5PLLE2t8,1516
99
+ secator/tasks/feroxbuster.py,sha256=djIHmJcYzZq-rcvufWmowT7XjjckM365WqzEAFBgJwI,2819
100
+ secator/tasks/ffuf.py,sha256=1bFzkb1GpLZPqp8yxIVk1JAMiM-FQEIdp86k69_fXZY,2643
101
+ secator/tasks/fping.py,sha256=w4_GaeCjkZ5Cdp-GP02faKgXmO7tf4U_lj4q0bg532Y,1163
102
+ secator/tasks/gau.py,sha256=aiD3gBn9oyWocSFcLhLyGaS7Rek2QNnWx-rf-1wxkeU,1741
103
+ secator/tasks/gf.py,sha256=4hhWT2HYJFP4jEaeeg9xen9pvfuvMQCsUwDGzFT41vM,993
104
+ secator/tasks/gitleaks.py,sha256=Mbg6eBwI4nm9GVSaYb6IN1eKtScbITweMVd7mMLDP-Q,2670
105
+ secator/tasks/gospider.py,sha256=z6ulHgTIc5hzt5DCS7IUIBhRW8PCoBl569rUO00HsF4,2355
106
+ secator/tasks/grype.py,sha256=D1MJldP0X7ffL8XGPWyQN82ljfhOgdWAMhHIveoz-V8,2566
107
+ secator/tasks/h8mail.py,sha256=aWT7pYbBZTtWAu2KhXsqeEqYLFfPEiwcoe2PfRbj5rQ,2003
108
+ secator/tasks/httpx.py,sha256=Ysty22oGte3KMiMSaJvERwZCqvsj9Y5DEjGWkaMD8NM,6001
109
+ secator/tasks/katana.py,sha256=0eDauUZW4cBLJ_S1J1SHx4LSC0fNOsRtngOplecG8So,5442
110
+ secator/tasks/maigret.py,sha256=31OiuVYDw0FTtaTWqttzAZv9I8LTw7rNofnQ6Xi3wOA,2163
111
+ secator/tasks/mapcidr.py,sha256=DnVOe8qtoQ14TB-Dgk8XSStQNq0myxujIS_QH2m2Wjc,1049
112
+ secator/tasks/msfconsole.py,sha256=1GRpXJv1fRVpDyR9Nu4LDX-Iv1aov4BfAhcjHgyCkik,6584
113
+ secator/tasks/naabu.py,sha256=aZR8CNg7uQqzsbr1Hbw7fqnIVwhiIKhAxj4DxxY8gIE,2412
114
+ secator/tasks/nmap.py,sha256=M2NeKT7JPD3UXaYdEfMAntnWuTYBEKv9IS10YB7iaX0,17021
115
+ secator/tasks/nuclei.py,sha256=zawUyNvpdBO-Q5r3vXxcJ3Md6JEP45td7O8BZqi8bXw,5032
116
+ secator/tasks/searchsploit.py,sha256=wKGQqVyOX8FqdcmQj3ULDmw0MzX1zL00kMugc0rcYZs,3479
117
+ secator/tasks/subfinder.py,sha256=heW9vE92GFXdFF1qipvAr4VMXFhgOk7D7c204CTbkZY,1297
118
+ secator/tasks/testssl.py,sha256=BIhy0iEG3CsEWu0MFe8bpXZWziw5GW8pPrXUDC0SU6I,11639
119
+ secator/tasks/trivy.py,sha256=P1qAfLmRzndEBMvGWXCDjB_4cRNP89pBR3HNK2801fE,3318
120
+ secator/tasks/wafw00f.py,sha256=YSV796pQmfWVy4VjOOljX2YqSh1Jn6d474xypcPxz8o,2774
121
+ secator/tasks/wpprobe.py,sha256=VpLzTLIlW-tTx7tJJU7aEUDQFr30li7oO3BLHQ77NMs,4069
122
+ secator/tasks/wpscan.py,sha256=eiTvHQqVJArX1qRAwjmB9T3GxXQlT7_HSUYuTi0VS8s,5796
123
123
  secator/workflows/__init__.py,sha256=R_TTyjg9f2Ph2_LYiF0lL07IjTrfRE_zqJzy-N7_WCk,675
124
- secator-0.14.0.dist-info/METADATA,sha256=_jYPgntzztbYS1ucHWOSSIq9d6J1MfEAikWHGr3DGpg,14724
125
- secator-0.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
126
- secator-0.14.0.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
127
- secator-0.14.0.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
128
- secator-0.14.0.dist-info/RECORD,,
124
+ secator-0.15.0.dist-info/METADATA,sha256=f_wo6Vt38MV5WD2Wwf_I9obDL-bhpeTOd0hJsZhxQQ4,15779
125
+ secator-0.15.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
126
+ secator-0.15.0.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
127
+ secator-0.15.0.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
128
+ secator-0.15.0.dist-info/RECORD,,