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.
- secator/celery.py +40 -24
- secator/celery_signals.py +71 -68
- secator/celery_utils.py +43 -27
- secator/cli.py +520 -280
- secator/cli_helper.py +394 -0
- secator/click.py +87 -0
- secator/config.py +67 -39
- secator/configs/profiles/http_headless.yaml +6 -0
- secator/configs/profiles/http_record.yaml +6 -0
- secator/configs/profiles/tor.yaml +1 -1
- secator/configs/scans/domain.yaml +4 -2
- secator/configs/scans/host.yaml +1 -1
- secator/configs/scans/network.yaml +1 -4
- secator/configs/scans/subdomain.yaml +13 -1
- secator/configs/scans/url.yaml +1 -2
- secator/configs/workflows/cidr_recon.yaml +6 -4
- secator/configs/workflows/code_scan.yaml +1 -1
- secator/configs/workflows/host_recon.yaml +29 -3
- secator/configs/workflows/subdomain_recon.yaml +67 -16
- secator/configs/workflows/url_crawl.yaml +44 -15
- secator/configs/workflows/url_dirsearch.yaml +4 -4
- secator/configs/workflows/url_fuzz.yaml +25 -17
- secator/configs/workflows/url_params_fuzz.yaml +7 -0
- secator/configs/workflows/url_vuln.yaml +33 -8
- secator/configs/workflows/user_hunt.yaml +2 -1
- secator/configs/workflows/wordpress.yaml +5 -3
- secator/cve.py +718 -0
- secator/decorators.py +0 -454
- secator/definitions.py +49 -30
- secator/exporters/_base.py +2 -2
- secator/exporters/console.py +2 -2
- secator/exporters/table.py +4 -3
- secator/exporters/txt.py +1 -1
- secator/hooks/mongodb.py +2 -4
- secator/installer.py +77 -49
- secator/loader.py +116 -0
- secator/output_types/_base.py +3 -0
- secator/output_types/certificate.py +63 -63
- secator/output_types/error.py +4 -5
- secator/output_types/info.py +2 -2
- secator/output_types/ip.py +3 -1
- secator/output_types/progress.py +5 -9
- secator/output_types/state.py +17 -17
- secator/output_types/tag.py +3 -0
- secator/output_types/target.py +10 -2
- secator/output_types/url.py +19 -7
- secator/output_types/vulnerability.py +11 -7
- secator/output_types/warning.py +2 -2
- secator/report.py +27 -15
- secator/rich.py +18 -10
- secator/runners/_base.py +447 -234
- secator/runners/_helpers.py +133 -24
- secator/runners/command.py +182 -102
- secator/runners/scan.py +33 -5
- secator/runners/task.py +13 -7
- secator/runners/workflow.py +105 -72
- secator/scans/__init__.py +2 -2
- secator/serializers/dataclass.py +20 -20
- secator/tasks/__init__.py +4 -4
- secator/tasks/_categories.py +39 -27
- secator/tasks/arjun.py +9 -5
- secator/tasks/bbot.py +53 -21
- secator/tasks/bup.py +19 -5
- secator/tasks/cariddi.py +24 -3
- secator/tasks/dalfox.py +26 -7
- secator/tasks/dirsearch.py +10 -4
- secator/tasks/dnsx.py +70 -25
- secator/tasks/feroxbuster.py +11 -3
- secator/tasks/ffuf.py +42 -6
- secator/tasks/fping.py +20 -8
- secator/tasks/gau.py +3 -1
- secator/tasks/gf.py +5 -4
- secator/tasks/gitleaks.py +2 -2
- secator/tasks/gospider.py +7 -1
- secator/tasks/grype.py +5 -4
- secator/tasks/h8mail.py +2 -1
- secator/tasks/httpx.py +18 -5
- secator/tasks/katana.py +35 -15
- secator/tasks/maigret.py +4 -4
- secator/tasks/mapcidr.py +3 -3
- secator/tasks/msfconsole.py +4 -4
- secator/tasks/naabu.py +5 -4
- secator/tasks/nmap.py +12 -14
- secator/tasks/nuclei.py +3 -3
- secator/tasks/searchsploit.py +6 -5
- secator/tasks/subfinder.py +2 -2
- secator/tasks/testssl.py +264 -263
- secator/tasks/trivy.py +5 -5
- secator/tasks/wafw00f.py +21 -3
- secator/tasks/wpprobe.py +90 -83
- secator/tasks/wpscan.py +6 -5
- secator/template.py +218 -104
- secator/thread.py +15 -15
- secator/tree.py +196 -0
- secator/utils.py +131 -123
- secator/utils_test.py +60 -19
- secator/workflows/__init__.py +2 -2
- {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/METADATA +37 -36
- secator-0.16.0.dist-info/RECORD +132 -0
- secator/configs/profiles/default.yaml +0 -8
- secator/configs/workflows/url_nuclei.yaml +0 -11
- secator/tasks/dnsxbrute.py +0 -42
- secator-0.15.0.dist-info/RECORD +0 -128
- {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/WHEEL +0 -0
- {secator-0.15.0.dist-info → secator-0.16.0.dist-info}/entry_points.txt +0 -0
- {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
|
-
|
|
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: [
|
|
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 ['
|
|
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 = {
|
secator/tasks/searchsploit.py
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
secator/tasks/subfinder.py
CHANGED
|
@@ -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'
|