secator 0.15.0__py3-none-any.whl → 0.16.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 (106) hide show
  1. secator/celery.py +40 -24
  2. secator/celery_signals.py +71 -68
  3. secator/celery_utils.py +43 -27
  4. secator/cli.py +520 -280
  5. secator/cli_helper.py +394 -0
  6. secator/click.py +87 -0
  7. secator/config.py +67 -39
  8. secator/configs/profiles/http_headless.yaml +6 -0
  9. secator/configs/profiles/http_record.yaml +6 -0
  10. secator/configs/profiles/tor.yaml +1 -1
  11. secator/configs/scans/domain.yaml +4 -2
  12. secator/configs/scans/host.yaml +1 -1
  13. secator/configs/scans/network.yaml +1 -4
  14. secator/configs/scans/subdomain.yaml +13 -1
  15. secator/configs/scans/url.yaml +1 -2
  16. secator/configs/workflows/cidr_recon.yaml +6 -4
  17. secator/configs/workflows/code_scan.yaml +1 -1
  18. secator/configs/workflows/host_recon.yaml +29 -3
  19. secator/configs/workflows/subdomain_recon.yaml +67 -16
  20. secator/configs/workflows/url_crawl.yaml +44 -15
  21. secator/configs/workflows/url_dirsearch.yaml +4 -4
  22. secator/configs/workflows/url_fuzz.yaml +25 -17
  23. secator/configs/workflows/url_params_fuzz.yaml +7 -0
  24. secator/configs/workflows/url_vuln.yaml +33 -8
  25. secator/configs/workflows/user_hunt.yaml +2 -1
  26. secator/configs/workflows/wordpress.yaml +5 -3
  27. secator/cve.py +718 -0
  28. secator/decorators.py +0 -454
  29. secator/definitions.py +49 -30
  30. secator/exporters/_base.py +2 -2
  31. secator/exporters/console.py +2 -2
  32. secator/exporters/table.py +4 -3
  33. secator/exporters/txt.py +1 -1
  34. secator/hooks/mongodb.py +2 -4
  35. secator/installer.py +77 -49
  36. secator/loader.py +116 -0
  37. secator/output_types/_base.py +3 -0
  38. secator/output_types/certificate.py +63 -63
  39. secator/output_types/error.py +4 -5
  40. secator/output_types/info.py +2 -2
  41. secator/output_types/ip.py +3 -1
  42. secator/output_types/progress.py +5 -9
  43. secator/output_types/state.py +17 -17
  44. secator/output_types/tag.py +3 -0
  45. secator/output_types/target.py +10 -2
  46. secator/output_types/url.py +19 -7
  47. secator/output_types/vulnerability.py +11 -7
  48. secator/output_types/warning.py +2 -2
  49. secator/report.py +27 -15
  50. secator/rich.py +18 -10
  51. secator/runners/_base.py +447 -234
  52. secator/runners/_helpers.py +133 -24
  53. secator/runners/command.py +182 -102
  54. secator/runners/scan.py +33 -5
  55. secator/runners/task.py +13 -7
  56. secator/runners/workflow.py +105 -72
  57. secator/scans/__init__.py +2 -2
  58. secator/serializers/dataclass.py +20 -20
  59. secator/tasks/__init__.py +4 -4
  60. secator/tasks/_categories.py +39 -27
  61. secator/tasks/arjun.py +9 -5
  62. secator/tasks/bbot.py +53 -21
  63. secator/tasks/bup.py +19 -5
  64. secator/tasks/cariddi.py +24 -3
  65. secator/tasks/dalfox.py +26 -7
  66. secator/tasks/dirsearch.py +10 -4
  67. secator/tasks/dnsx.py +70 -25
  68. secator/tasks/feroxbuster.py +11 -3
  69. secator/tasks/ffuf.py +42 -6
  70. secator/tasks/fping.py +20 -8
  71. secator/tasks/gau.py +3 -1
  72. secator/tasks/gf.py +5 -4
  73. secator/tasks/gitleaks.py +2 -2
  74. secator/tasks/gospider.py +7 -1
  75. secator/tasks/grype.py +5 -4
  76. secator/tasks/h8mail.py +2 -1
  77. secator/tasks/httpx.py +18 -5
  78. secator/tasks/katana.py +35 -15
  79. secator/tasks/maigret.py +4 -4
  80. secator/tasks/mapcidr.py +3 -3
  81. secator/tasks/msfconsole.py +4 -4
  82. secator/tasks/naabu.py +5 -4
  83. secator/tasks/nmap.py +12 -14
  84. secator/tasks/nuclei.py +3 -3
  85. secator/tasks/searchsploit.py +6 -5
  86. secator/tasks/subfinder.py +2 -2
  87. secator/tasks/testssl.py +264 -263
  88. secator/tasks/trivy.py +5 -5
  89. secator/tasks/wafw00f.py +21 -3
  90. secator/tasks/wpprobe.py +90 -83
  91. secator/tasks/wpscan.py +6 -5
  92. secator/template.py +218 -104
  93. secator/thread.py +15 -15
  94. secator/tree.py +196 -0
  95. secator/utils.py +131 -123
  96. secator/utils_test.py +60 -19
  97. secator/workflows/__init__.py +2 -2
  98. {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/METADATA +37 -36
  99. secator-0.16.0.dist-info/RECORD +132 -0
  100. secator/configs/profiles/default.yaml +0 -8
  101. secator/configs/workflows/url_nuclei.yaml +0 -11
  102. secator/tasks/dnsxbrute.py +0 -42
  103. secator-0.15.0.dist-info/RECORD +0 -128
  104. {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/WHEEL +0 -0
  105. {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/entry_points.txt +0 -0
  106. {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/licenses/LICENSE +0 -0
secator/tasks/nmap.py CHANGED
@@ -10,9 +10,8 @@ from secator.definitions import (CONFIDENCE, CVSS_SCORE, DELAY,
10
10
  DESCRIPTION, EXTRA_DATA, FOLLOW_REDIRECT,
11
11
  HEADER, HOST, ID, IP, PROTOCOL, MATCHED_AT, NAME,
12
12
  OPT_NOT_SUPPORTED, OUTPUT_PATH, PORT, PORTS, PROVIDER,
13
- PROXY, RATE_LIMIT, REFERENCE, REFERENCES,
14
- RETRIES, SCRIPT, SERVICE_NAME, SEVERITY, STATE, TAGS,
15
- THREADS, TIMEOUT, TOP_PORTS, USER_AGENT)
13
+ PROXY, RATE_LIMIT, REFERENCE, REFERENCES, RETRIES, SCRIPT, SERVICE_NAME,
14
+ SEVERITY, STATE, TAGS, THREADS, TIMEOUT, TOP_PORTS, USER_AGENT)
16
15
  from secator.output_types import Exploit, Port, Vulnerability, Info, Error
17
16
  from secator.tasks._categories import VulnMulti
18
17
  from secator.utils import debug, traceback_as_string
@@ -24,13 +23,12 @@ logger = logging.getLogger(__name__)
24
23
  class nmap(VulnMulti):
25
24
  """Network Mapper is a free and open source utility for network discovery and security auditing."""
26
25
  cmd = 'nmap'
27
- tags = ['port', 'scan']
28
- input_flag = None
29
26
  input_types = [HOST, IP]
27
+ output_types = [Port, Vulnerability, Exploit]
28
+ tags = ['port', 'scan']
30
29
  input_chunk_size = 1
31
30
  file_flag = '-iL'
32
31
  opt_prefix = '--'
33
- output_types = [Port, Vulnerability, Exploit]
34
32
  opts = {
35
33
  # Port specification and scan order
36
34
  PORTS: {'type': str, 'short': 'p', 'help': 'Ports to scan (- to scan all)'},
@@ -248,7 +246,7 @@ class nmapData(dict):
248
246
  EXTRA_DATA: extra_data,
249
247
  }
250
248
  if not func:
251
- debug(f'Script output parser for "{script_id}" is not supported YET.', sub='cve')
249
+ debug(f'Script output parser for "{script_id}" is not supported YET.', sub='cve.nmap')
252
250
  continue
253
251
  for data in func(output, cpes=cpes):
254
252
  data.update(metadata)
@@ -257,7 +255,7 @@ class nmapData(dict):
257
255
  confidence = 'high' if version_exact else 'medium'
258
256
  data[CONFIDENCE] = confidence
259
257
  if (CONFIG.runners.skip_cve_low_confidence and data[CONFIDENCE] == 'low'):
260
- debug(f'{data[ID]}: ignored (low confidence).', sub='cve')
258
+ debug(f'{data[ID]}: ignored (low confidence).', sub='cve.nmap')
261
259
  continue
262
260
  if data in datas:
263
261
  continue
@@ -349,7 +347,7 @@ class nmapData(dict):
349
347
  if not isinstance(cpes, list):
350
348
  cpes = [cpes]
351
349
  extra_data['cpe'] = cpes
352
- debug(f'Found CPEs: {",".join(cpes)}', sub='cve')
350
+ debug(f'Found CPEs: {",".join(cpes)}', sub='cve.nmap')
353
351
 
354
352
  # Grab confidence
355
353
  conf = int(extra_data.get('conf', 0))
@@ -368,7 +366,7 @@ class nmapData(dict):
368
366
  cpe = VulnMulti.create_cpe_string(product, version_cpe)
369
367
  if cpe not in cpes:
370
368
  cpes.append(cpe)
371
- debug(f'Added new CPE from identified product and version: {cpe}', sub='cve')
369
+ debug(f'Added new CPE from identified product and version: {cpe}', sub='cve.nmap')
372
370
 
373
371
  return extra_data
374
372
 
@@ -412,7 +410,7 @@ class nmapData(dict):
412
410
  NAME: vuln_id,
413
411
  DESCRIPTION: vuln_title,
414
412
  PROVIDER: provider_name,
415
- TAGS: [vuln_id, provider_name]
413
+ TAGS: [provider_name]
416
414
  }
417
415
  if provider_name == 'MITRE CVE':
418
416
  data = VulnMulti.lookup_cve(vuln['id'], *cpes)
@@ -436,7 +434,6 @@ class nmapData(dict):
436
434
  elems = tuple(line.split('\t'))
437
435
 
438
436
  if len(elems) == 4: # exploit
439
- # TODO: Implement exploit processing
440
437
  exploit_id, cvss_score, reference_url, _ = elems
441
438
  name = exploit_id
442
439
  # edb_id = name.split(':')[-1] if 'EDB-ID' in name else None
@@ -460,6 +457,7 @@ class nmapData(dict):
460
457
  exploit[TAGS].extend(vuln[TAGS])
461
458
  exploit[CONFIDENCE] = vuln[CONFIDENCE]
462
459
  yield exploit
460
+ continue
463
461
 
464
462
  elif len(elems) == 3: # vuln
465
463
  vuln = {}
@@ -483,6 +481,6 @@ class nmapData(dict):
483
481
  vuln.update(data)
484
482
  yield vuln
485
483
  else:
486
- debug(f'Vulners parser for "{vuln_type}" is not implemented YET.', sub='cve')
484
+ debug(f'Vulners parser for "{vuln_type}" is not implemented YET.', sub='cve.nmap')
487
485
  else:
488
- debug(f'Unrecognized vulners output: {elems}', sub='cve')
486
+ debug(f'Unrecognized vulners output: {elems}', sub='cve.nmap')
secator/tasks/nuclei.py CHANGED
@@ -14,8 +14,9 @@ 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
17
  input_types = [HOST, IP, URL]
18
+ output_types = [Vulnerability, Progress]
19
+ tags = ['vuln', 'scan']
19
20
  file_flag = '-l'
20
21
  input_flag = '-u'
21
22
  json_flag = '-jsonl'
@@ -59,7 +60,6 @@ class nuclei(VulnMulti):
59
60
  'exclude_tags': lambda x: ','.join(x) if isinstance(x, list) else x,
60
61
  }
61
62
  item_loaders = [JSONSerializer()]
62
- output_types = [Vulnerability, Progress]
63
63
  output_map = {
64
64
  Vulnerability: {
65
65
  ID: lambda x: nuclei.id_extractor(x),
@@ -77,7 +77,7 @@ class nuclei(VulnMulti):
77
77
  },
78
78
  Progress: {
79
79
  PERCENT: lambda x: int(x['percent']),
80
- EXTRA_DATA: lambda x: {k: v for k, v in x.items() if k not in ['duration', 'errors', 'percent']}
80
+ EXTRA_DATA: lambda x: {k: v for k, v in x.items() if k not in ['percent']}
81
81
  }
82
82
  }
83
83
  install_pre = {
@@ -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, TECHNOLOGY, OPT_NOT_SUPPORTED)
6
+ PROVIDER, REFERENCE, TAGS, OPT_NOT_SUPPORTED, STRING)
7
7
  from secator.output_types import Exploit
8
8
  from secator.runners import Command
9
9
  from secator.serializers import JSONSerializer
@@ -16,9 +16,10 @@ 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
+ input_types = [STRING]
20
+ output_types = [Exploit]
19
21
  tags = ['exploit', 'recon']
20
- input_flag = None
21
- input_types = [TECHNOLOGY]
22
+ input_chunk_size = 1
22
23
  json_flag = '--json'
23
24
  version_flag = OPT_NOT_SUPPORTED
24
25
  opts = {
@@ -26,7 +27,6 @@ class searchsploit(Command):
26
27
  }
27
28
  opt_key_map = {}
28
29
  item_loaders = [JSONSerializer()]
29
- output_types = [Exploit]
30
30
  output_map = {
31
31
  Exploit: {
32
32
  NAME: 'Title',
@@ -51,7 +51,6 @@ class searchsploit(Command):
51
51
  proxychains = False
52
52
  proxy_socks5 = False
53
53
  proxy_http = False
54
- input_chunk_size = 1
55
54
  profile = 'io'
56
55
 
57
56
  @staticmethod
@@ -86,6 +85,8 @@ class searchsploit(Command):
86
85
 
87
86
  @staticmethod
88
87
  def on_item(self, item):
88
+ if not isinstance(item, Exploit):
89
+ return item
89
90
  match = SEARCHSPLOIT_TITLE_REGEX.match(item.name)
90
91
  # if not match:
91
92
  # self._print(f'[bold red]{item.name} ({item.reference}) did not match SEARCHSPLOIT_TITLE_REGEX. Please report this issue.[/]') # noqa: E501
@@ -10,8 +10,9 @@ 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
13
  input_types = [HOST]
14
+ output_types = [Subdomain]
15
+ tags = ['dns', 'recon']
15
16
  file_flag = '-dL'
16
17
  input_flag = '-d'
17
18
  json_flag = '-json'
@@ -32,7 +33,6 @@ class subfinder(ReconDns):
32
33
  DOMAIN: 'input',
33
34
  }
34
35
  }
35
- output_types = [Subdomain]
36
36
  install_version = 'v2.7.0'
37
37
  install_cmd = 'go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@[install_version]'
38
38
  install_github_handle = 'projectdiscovery/subfinder'