secator 0.10.1a12__py3-none-any.whl → 0.15.1__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 (73) hide show
  1. secator/celery.py +10 -5
  2. secator/celery_signals.py +2 -11
  3. secator/cli.py +309 -69
  4. secator/config.py +3 -2
  5. secator/configs/profiles/aggressive.yaml +6 -5
  6. secator/configs/profiles/default.yaml +6 -7
  7. secator/configs/profiles/insane.yaml +8 -0
  8. secator/configs/profiles/paranoid.yaml +8 -0
  9. secator/configs/profiles/polite.yaml +8 -0
  10. secator/configs/profiles/sneaky.yaml +8 -0
  11. secator/configs/profiles/tor.yaml +5 -0
  12. secator/configs/workflows/host_recon.yaml +11 -2
  13. secator/configs/workflows/url_dirsearch.yaml +5 -0
  14. secator/configs/workflows/url_params_fuzz.yaml +25 -0
  15. secator/configs/workflows/wordpress.yaml +4 -1
  16. secator/decorators.py +64 -34
  17. secator/definitions.py +8 -4
  18. secator/installer.py +84 -49
  19. secator/output_types/__init__.py +2 -1
  20. secator/output_types/certificate.py +78 -0
  21. secator/output_types/stat.py +3 -0
  22. secator/output_types/user_account.py +1 -1
  23. secator/report.py +2 -2
  24. secator/rich.py +1 -1
  25. secator/runners/_base.py +50 -11
  26. secator/runners/_helpers.py +15 -3
  27. secator/runners/command.py +85 -21
  28. secator/runners/scan.py +6 -3
  29. secator/runners/task.py +1 -0
  30. secator/runners/workflow.py +22 -4
  31. secator/tasks/_categories.py +25 -17
  32. secator/tasks/arjun.py +92 -0
  33. secator/tasks/bbot.py +33 -4
  34. secator/tasks/bup.py +4 -2
  35. secator/tasks/cariddi.py +17 -4
  36. secator/tasks/dalfox.py +4 -2
  37. secator/tasks/dirsearch.py +4 -2
  38. secator/tasks/dnsx.py +5 -2
  39. secator/tasks/dnsxbrute.py +4 -1
  40. secator/tasks/feroxbuster.py +5 -2
  41. secator/tasks/ffuf.py +7 -3
  42. secator/tasks/fping.py +4 -1
  43. secator/tasks/gau.py +5 -2
  44. secator/tasks/gf.py +4 -2
  45. secator/tasks/gitleaks.py +79 -0
  46. secator/tasks/gospider.py +5 -2
  47. secator/tasks/grype.py +5 -2
  48. secator/tasks/h8mail.py +4 -2
  49. secator/tasks/httpx.py +6 -3
  50. secator/tasks/katana.py +6 -3
  51. secator/tasks/maigret.py +4 -2
  52. secator/tasks/mapcidr.py +5 -3
  53. secator/tasks/msfconsole.py +8 -6
  54. secator/tasks/naabu.py +16 -5
  55. secator/tasks/nmap.py +31 -29
  56. secator/tasks/nuclei.py +18 -10
  57. secator/tasks/searchsploit.py +8 -3
  58. secator/tasks/subfinder.py +6 -3
  59. secator/tasks/testssl.py +276 -0
  60. secator/tasks/trivy.py +98 -0
  61. secator/tasks/wafw00f.py +85 -0
  62. secator/tasks/wpprobe.py +96 -0
  63. secator/tasks/wpscan.py +8 -4
  64. secator/template.py +61 -67
  65. secator/utils.py +31 -18
  66. secator/utils_test.py +34 -10
  67. {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/METADATA +11 -3
  68. secator-0.15.1.dist-info/RECORD +128 -0
  69. secator/configs/profiles/stealth.yaml +0 -7
  70. secator-0.10.1a12.dist-info/RECORD +0 -116
  71. {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/WHEEL +0 -0
  72. {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/entry_points.txt +0 -0
  73. {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/licenses/LICENSE +0 -0
secator/tasks/cariddi.py CHANGED
@@ -13,12 +13,20 @@ from secator.tasks._categories import HttpCrawler
13
13
  @task()
14
14
  class cariddi(HttpCrawler):
15
15
  """Crawl endpoints, secrets, api keys, extensions, tokens..."""
16
- cmd = 'cariddi -info -s -err -e -ext 1'
17
- input_type = URL
16
+ cmd = 'cariddi'
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
21
22
  json_flag = '-json'
23
+ opts = {
24
+ 'info': {'is_flag': True, 'short': 'info', 'help': 'Hunt for useful informations in websites.'},
25
+ 'secrets': {'is_flag': True, 'short': 'secrets', 'help': 'Hunt for secrets.'},
26
+ 'errors': {'is_flag': True, 'short': 'err', 'help': 'Hunt for errors in websites.'},
27
+ 'juicy_extensions': {'type': int, 'short': 'jext', 'help': 'Hunt for juicy file extensions. Integer from 1(juicy) to 7(not juicy)'}, # noqa: E501
28
+ 'juicy_endpoints': {'is_flag': True, 'short': 'jep', 'help': 'Hunt for juicy endpoints.'}
29
+ }
22
30
  opt_key_map = {
23
31
  HEADER: 'headers',
24
32
  DELAY: 'd',
@@ -38,10 +46,15 @@ class cariddi(HttpCrawler):
38
46
  RETRIES: OPT_NOT_SUPPORTED,
39
47
  THREADS: 'c',
40
48
  TIMEOUT: 't',
41
- USER_AGENT: 'ua'
49
+ USER_AGENT: 'ua',
50
+ 'secrets': 's',
51
+ 'errors': 'err',
52
+ 'juicy_endpoints': 'e',
53
+ 'juicy_extensions': 'ext'
42
54
  }
43
55
  item_loaders = [JSONSerializer()]
44
- install_cmd = 'go install -v github.com/edoardottt/cariddi/cmd/cariddi@latest'
56
+ install_version = 'v1.3.6'
57
+ install_cmd = 'go install -v github.com/edoardottt/cariddi/cmd/cariddi@[install_version]'
45
58
  install_github_handle = 'edoardottt/cariddi'
46
59
  encoding = 'ansi'
47
60
  proxychains = False
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
@@ -55,7 +56,8 @@ class dalfox(VulnHttp):
55
56
  SEVERITY: lambda x: x['severity'].lower()
56
57
  }
57
58
  }
58
- install_cmd = 'go install -v github.com/hahwul/dalfox/v2@v2.9.3'
59
+ install_version = 'v2.11.0'
60
+ install_cmd = 'go install -v github.com/hahwul/dalfox/v2@latest'
59
61
  install_github_handle = 'hahwul/dalfox'
60
62
  encoding = 'ansi'
61
63
  proxychains = False
@@ -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'
@@ -52,7 +54,7 @@ class dirsearch(HttpFuzzer):
52
54
  STATUS_CODE: 'status'
53
55
  }
54
56
  }
55
- install_cmd = 'pipx install --force git+https://github.com/maurosoria/dirsearch'
57
+ install_cmd = 'pipx install git+https://github.com/maurosoria/dirsearch.git --force'
56
58
  proxychains = True
57
59
  proxy_socks5 = True
58
60
  proxy_http = True
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 = {
@@ -26,7 +28,8 @@ class dnsx(ReconDns):
26
28
  'wildcard_domain': {'type': str, 'short': 'wd', 'help': 'Domain name for wildcard filtering'},
27
29
  }
28
30
  item_loaders = [JSONSerializer()]
29
- install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest'
31
+ install_version = 'v1.2.2'
32
+ install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
30
33
  install_github_handle = 'projectdiscovery/dnsx'
31
34
  profile = 'io'
32
35
 
@@ -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',
@@ -34,6 +36,7 @@ class dnsxbrute(ReconDns):
34
36
  }
35
37
  }
36
38
  }
37
- install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest'
39
+ install_version = 'v1.2.2'
40
+ install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
38
41
  install_github_handle = 'projectdiscovery/dnsx'
39
42
  profile = 'io'
@@ -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, DEFAULT_FEROXBUSTER_FLAGS)
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
@@ -15,7 +15,9 @@ from secator.tasks._categories import HttpFuzzer
15
15
  @task()
16
16
  class feroxbuster(HttpFuzzer):
17
17
  """Simple, fast, recursive content discovery tool written in Rust"""
18
- cmd = f'feroxbuster {DEFAULT_FEROXBUSTER_FLAGS}'
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
@@ -62,6 +64,7 @@ class feroxbuster(HttpFuzzer):
62
64
  install_pre = {
63
65
  '*': ['curl', 'bash']
64
66
  }
67
+ install_version = 'v2.11.0'
65
68
  install_cmd = (
66
69
  f'cd /tmp && curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | bash -s {CONFIG.dirs.bin}' # noqa: E501
67
70
  )
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
@@ -18,7 +18,9 @@ FFUF_PROGRESS_REGEX = r':: Progress: \[(?P<count>\d+)/(?P<total>\d+)\] :: Job \[
18
18
  @task()
19
19
  class ffuf(HttpFuzzer):
20
20
  """Fast web fuzzer written in Go."""
21
- cmd = 'ffuf -noninteractive -recursion'
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
@@ -30,6 +32,7 @@ class ffuf(HttpFuzzer):
30
32
  ]
31
33
  opts = {
32
34
  AUTO_CALIBRATION: {'is_flag': True, 'short': 'ac', 'help': 'Auto-calibration'},
35
+ 'recursion': {'is_flag': True, 'default': True, 'short': 'recursion', 'help': 'Recursion'},
33
36
  }
34
37
  opt_key_map = {
35
38
  HEADER: 'H',
@@ -70,7 +73,8 @@ class ffuf(HttpFuzzer):
70
73
  },
71
74
  }
72
75
  encoding = 'ansi'
73
- install_cmd = 'go install -v github.com/ffuf/ffuf@latest'
76
+ install_version = 'v2.1.0'
77
+ install_cmd = 'go install -v github.com/ffuf/ffuf/v2@[install_version]'
74
78
  install_github_handle = 'ffuf/ffuf'
75
79
  proxychains = False
76
80
  proxy_socks5 = True
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,9 +28,10 @@ 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']}
34
+ ignore_return_code = True
32
35
 
33
36
  @staticmethod
34
37
  def item_loader(self, line):
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 = '--'
@@ -44,7 +46,8 @@ class gau(HttpCrawler):
44
46
  install_pre = {
45
47
  'apk': ['libc6-compat']
46
48
  }
47
- install_cmd = 'go install -v github.com/lc/gau/v2/cmd/gau@latest'
49
+ install_version = 'v2.2.4'
50
+ install_cmd = 'go install -v github.com/lc/gau/v2/cmd/gau@[install_version]'
48
51
  install_github_handle = 'lc/gau'
49
52
  proxychains = False
50
53
  proxy_socks5 = True
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'
@@ -30,5 +31,6 @@ class gf(Tagger):
30
31
 
31
32
  @staticmethod
32
33
  def on_item(self, item):
33
- item.extra_data = {'source': 'url'}
34
+ if isinstance(item, Tag):
35
+ item.extra_data = {'source': 'url'}
34
36
  return item
@@ -0,0 +1,79 @@
1
+ import click
2
+ import os
3
+ import yaml
4
+
5
+ from secator.config import CONFIG
6
+ from secator.decorators import task
7
+ from secator.runners import Command
8
+ from secator.definitions import (OUTPUT_PATH, PATH, GIT_REPOSITORY)
9
+ from secator.utils import caml_to_snake
10
+ from secator.output_types import Tag, Info, Error
11
+
12
+
13
+ @task()
14
+ class gitleaks(Command):
15
+ """Tool for detecting secrets like passwords, API keys, and tokens in git repos, files, and stdin."""
16
+ cmd = 'gitleaks'
17
+ tags = ['secret', 'scan']
18
+ input_types = [PATH, GIT_REPOSITORY]
19
+ input_flag = None
20
+ json_flag = '-f json'
21
+ opt_prefix = '--'
22
+ opts = {
23
+ 'ignore_path': {'type': str, 'help': 'Path to .gitleaksignore file or folder containing one'},
24
+ 'mode': {'type': click.Choice(['git', 'dir']), 'default': 'dir', 'help': 'Gitleaks mode', 'internal': True, 'display': True}, # noqa: E501
25
+ 'config': {'type': str, 'short': 'config', 'help': 'Gitleaks config file path'}
26
+ }
27
+ opt_key_map = {
28
+ "ignore_path": "gitleaks-ignore-path"
29
+ }
30
+ input_type = "folder"
31
+ output_types = [Tag]
32
+ output_map = {
33
+ Tag: {
34
+ 'name': 'RuleID',
35
+ 'match': lambda x: f'{x["File"]}:{x["StartLine"]}:{x["StartColumn"]}',
36
+ 'extra_data': lambda x: {caml_to_snake(k): v for k, v in x.items() if k not in ['RuleID', 'File']}
37
+ }
38
+ }
39
+ install_pre = {'*': ['git', 'make']}
40
+ install_version = 'v8.24.3'
41
+ install_cmd = (
42
+ f'git clone https://github.com/gitleaks/gitleaks.git {CONFIG.dirs.share}/gitleaks_[install_version] || true &&'
43
+ f'cd {CONFIG.dirs.share}/gitleaks_[install_version] && make build &&'
44
+ f'mv {CONFIG.dirs.share}/gitleaks_[install_version]/gitleaks {CONFIG.dirs.bin}'
45
+ )
46
+ install_github_handle = 'gitleaks/gitleaks'
47
+
48
+ @staticmethod
49
+ def on_cmd(self):
50
+ # replace fake -mode opt by subcommand
51
+ mode = self.get_opt_value('mode')
52
+ self.cmd = self.cmd.replace(f'{gitleaks.cmd} ', f'{gitleaks.cmd} {mode} ')
53
+
54
+ # add output path
55
+ output_path = self.get_opt_value(OUTPUT_PATH)
56
+ if not output_path:
57
+ output_path = f'{self.reports_folder}/.outputs/{self.unique_name}.json'
58
+ self.output_path = output_path
59
+ self.cmd += f' -r {self.output_path}'
60
+ self.cmd += ' --exit-code 0'
61
+
62
+ @staticmethod
63
+ def on_cmd_done(self):
64
+ if not os.path.exists(self.output_path):
65
+ yield Error(message=f'Could not find JSON results in {self.output_path}')
66
+ return
67
+
68
+ yield Info(message=f'JSON results saved to {self.output_path}')
69
+ with open(self.output_path, 'r') as f:
70
+ results = yaml.safe_load(f.read())
71
+ for result in results:
72
+ yield Tag(
73
+ name=result['RuleID'],
74
+ match='{File}:{StartLine}:{StartColumn}'.format(**result),
75
+ extra_data={
76
+ caml_to_snake(k): v for k, v in result.items()
77
+ if k not in ['RuleID', 'File']
78
+ }
79
+ )
secator/tasks/gospider.py CHANGED
@@ -15,9 +15,11 @@ from secator.tasks._categories import HttpCrawler
15
15
  @task()
16
16
  class gospider(HttpCrawler):
17
17
  """Fast web spider written in Go."""
18
- cmd = 'gospider --js'
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 = {
@@ -53,7 +55,8 @@ class gospider(HttpCrawler):
53
55
  CONTENT_LENGTH: 'length',
54
56
  }
55
57
  }
56
- install_cmd = 'go install -v github.com/jaeles-project/gospider@latest'
58
+ install_version = 'v1.1.6'
59
+ install_cmd = 'go install -v github.com/jaeles-project/gospider@[install_version]'
57
60
  install_github_handle = 'jaeles-project/gospider'
58
61
  proxychains = False
59
62
  proxy_socks5 = True # with leaks... https://github.com/jaeles-project/gospider/issues/61
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
@@ -30,6 +32,7 @@ class grype(VulnCode):
30
32
  install_pre = {
31
33
  '*': ['curl']
32
34
  }
35
+ install_version = 'v0.91.2'
33
36
  install_cmd = (
34
37
  f'curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b {CONFIG.dirs.bin}'
35
38
  )
@@ -66,7 +69,7 @@ class grype(VulnCode):
66
69
  if vuln_id.startswith('GHSA'):
67
70
  data['provider'] = 'github.com'
68
71
  data['references'] = [f'https://github.com/advisories/{vuln_id}']
69
- vuln = VulnCode.lookup_ghsa(vuln_id)
72
+ vuln = VulnCode.lookup_cve_from_ghsa(vuln_id)
70
73
  if vuln:
71
74
  data.update(vuln)
72
75
  data['severity'] = data['severity'] or severity.lower()
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 = '--'
@@ -21,7 +22,8 @@ class h8mail(OSInt):
21
22
  'config': {'type': str, 'help': 'Configuration file for API keys'},
22
23
  'local_breach': {'type': str, 'short': 'lb', 'help': 'Local breach file'}
23
24
  }
24
- install_cmd = 'pipx install h8mail && pipx upgrade h8mail'
25
+ install_version = '2.5.6'
26
+ install_cmd = 'pipx install h8mail==[install_version] --force'
25
27
 
26
28
  @staticmethod
27
29
  def on_start(self):
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'},
@@ -33,7 +35,7 @@ class httpx(Http):
33
35
  'system_chrome': {'is_flag': True, 'default': False, 'help': 'Use local installed Chrome for screenshot'},
34
36
  'headless_options': {'is_flag': False, 'short': 'ho', 'default': None, 'help': 'Headless Chrome additional options'},
35
37
  'follow_host_redirects': {'is_flag': True, 'short': 'fhr', 'default': None, 'help': 'Follow redirects on the same host'}, # noqa: E501
36
- 'tech_detect': {'is_flag': True, 'short': 'td', 'default': True, 'help': 'Tech detection'},
38
+ 'tech_detect': {'is_flag': True, 'short': 'td', 'default': False, 'help': 'Tech detection'},
37
39
  'tls_grab': {'is_flag': True, 'short': 'tlsg', 'default': False, 'help': 'Grab some informations from the tls certificate'}, # noqa: E501
38
40
  'rstr': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to read (bytes)'},
39
41
  'rsts': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to save (bytes)'}
@@ -68,7 +70,8 @@ class httpx(Http):
68
70
  install_pre = {
69
71
  'apk': ['chromium']
70
72
  }
71
- install_cmd = 'go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest'
73
+ install_version = 'v1.7.0'
74
+ install_cmd = 'go install -v github.com/projectdiscovery/httpx/cmd/httpx@[install_version]'
72
75
  install_github_handle = 'projectdiscovery/httpx'
73
76
  proxychains = False
74
77
  proxy_socks5 = True
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'},
@@ -26,8 +28,8 @@ class katana(HttpCrawler):
26
28
  'form_extraction': {'is_flag': True, 'short': 'fx', 'help': 'Detect forms'},
27
29
  'store_responses': {'is_flag': True, 'short': 'sr', 'default': CONFIG.http.store_responses, 'help': 'Store responses'}, # noqa: E501
28
30
  'form_fill': {'is_flag': True, 'short': 'ff', 'help': 'Enable form filling'},
29
- 'js_crawl': {'is_flag': True, 'short': 'jc', 'default': True, 'help': 'Enable endpoint parsing / crawling in javascript file'}, # noqa: E501
30
- 'jsluice': {'is_flag': True, 'short': 'jsl', 'default': True, 'help': 'Enable jsluice parsing in javascript file (memory intensive)'}, # noqa: E501
31
+ 'js_crawl': {'is_flag': True, 'short': 'jc', 'default': False, 'help': 'Enable endpoint parsing / crawling in javascript file'}, # noqa: E501
32
+ 'jsluice': {'is_flag': True, 'short': 'jsl', 'default': False, 'help': 'Enable jsluice parsing in javascript file (memory intensive)'}, # noqa: E501
31
33
  'known_files': {'type': str, 'short': 'kf', 'default': 'all', 'help': 'Enable crawling of known files (all, robotstxt, sitemapxml)'}, # noqa: E501
32
34
  'omit_raw': {'is_flag': True, 'short': 'or', 'default': True, 'help': 'Omit raw requests/responses from jsonl output'}, # noqa: E501
33
35
  'omit_body': {'is_flag': True, 'short': 'ob', 'default': True, 'help': 'Omit response body from jsonl output'},
@@ -78,7 +80,8 @@ class katana(HttpCrawler):
78
80
  install_pre = {
79
81
  'apk': ['libc6-compat']
80
82
  }
81
- install_cmd = 'go install -v github.com/projectdiscovery/katana/cmd/katana@latest'
83
+ install_version = 'v1.1.3'
84
+ install_cmd = 'go install -v github.com/projectdiscovery/katana/cmd/katana@[install_version]'
82
85
  install_github_handle = 'projectdiscovery/katana'
83
86
  proxychains = False
84
87
  proxy_socks5 = True
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: {
@@ -41,7 +43,7 @@ class maigret(ReconUser):
41
43
  EXTRA_DATA: lambda x: x['status'].get('ids', {})
42
44
  }
43
45
  }
44
- install_cmd = 'pipx install git+https://github.com/soxoj/maigret'
46
+ install_cmd = 'pipx install git+https://github.com/soxoj/maigret --force'
45
47
  socks5_proxy = True
46
48
  profile = 'io'
47
49
 
secator/tasks/mapcidr.py CHANGED
@@ -10,15 +10,17 @@ from secator.tasks._categories import ReconIp
10
10
  @task()
11
11
  class mapcidr(ReconIp):
12
12
  """Utility program to perform multiple operations for a given subnet/cidr ranges."""
13
- cmd = 'mapcidr -silent'
13
+ cmd = 'mapcidr'
14
+ tags = ['ip', 'recon']
14
15
  input_flag = '-cidr'
15
16
  file_flag = '-cl'
16
17
  install_pre = {
17
18
  'apk': ['libc6-compat']
18
19
  }
19
- install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@latest'
20
+ install_version = 'v1.1.34'
21
+ install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@[install_version]'
20
22
  install_github_handle = 'projectdiscovery/mapcidr'
21
- input_type = CIDR_RANGE
23
+ input_types = [CIDR_RANGE]
22
24
  output_types = [Ip]
23
25
  opt_key_map = {
24
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 = '--'
@@ -48,14 +49,15 @@ class msfconsole(VulnMulti):
48
49
  'pacman': ['ruby-erb', 'postgresql-libs', 'make'],
49
50
  'yum|zypper': ['postgresql-devel', 'make'],
50
51
  }
52
+ install_version = '6.4.59'
51
53
  install_cmd = (
52
- f'git clone --depth 1 --single-branch https://github.com/rapid7/metasploit-framework.git {CONFIG.dirs.share}/metasploit-framework || true && ' # noqa: E501
53
- f'cd {CONFIG.dirs.share}/metasploit-framework && '
54
+ f'git clone --depth 1 --single-branch -b [install_version] https://github.com/rapid7/metasploit-framework.git {CONFIG.dirs.share}/metasploit-framework_[install_version] || true && ' # noqa: E501
55
+ f'cd {CONFIG.dirs.share}/metasploit-framework_[install_version] && '
54
56
  f'gem install bundler --user-install -n {CONFIG.dirs.bin} && '
55
57
  f'bundle config set --local path "{CONFIG.dirs.share}" && '
56
58
  'bundle lock --normalize-platforms &&'
57
59
  'bundle install && '
58
- f'ln -sf $HOME/.local/share/metasploit-framework/msfconsole {CONFIG.dirs.bin}/msfconsole'
60
+ f'ln -sf $HOME/.local/share/metasploit-framework_[install_version]/msfconsole {CONFIG.dirs.bin}/msfconsole'
59
61
  )
60
62
 
61
63
  @staticmethod