secator 0.22.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.
- secator/.gitignore +162 -0
- secator/__init__.py +0 -0
- secator/celery.py +453 -0
- secator/celery_signals.py +138 -0
- secator/celery_utils.py +320 -0
- secator/cli.py +2035 -0
- secator/cli_helper.py +395 -0
- secator/click.py +87 -0
- secator/config.py +670 -0
- secator/configs/__init__.py +0 -0
- secator/configs/profiles/__init__.py +0 -0
- secator/configs/profiles/aggressive.yaml +8 -0
- secator/configs/profiles/all_ports.yaml +7 -0
- secator/configs/profiles/full.yaml +31 -0
- secator/configs/profiles/http_headless.yaml +7 -0
- secator/configs/profiles/http_record.yaml +8 -0
- secator/configs/profiles/insane.yaml +8 -0
- secator/configs/profiles/paranoid.yaml +8 -0
- secator/configs/profiles/passive.yaml +11 -0
- secator/configs/profiles/polite.yaml +8 -0
- secator/configs/profiles/sneaky.yaml +8 -0
- secator/configs/profiles/tor.yaml +5 -0
- secator/configs/scans/__init__.py +0 -0
- secator/configs/scans/domain.yaml +31 -0
- secator/configs/scans/host.yaml +23 -0
- secator/configs/scans/network.yaml +30 -0
- secator/configs/scans/subdomain.yaml +27 -0
- secator/configs/scans/url.yaml +19 -0
- secator/configs/workflows/__init__.py +0 -0
- secator/configs/workflows/cidr_recon.yaml +48 -0
- secator/configs/workflows/code_scan.yaml +29 -0
- secator/configs/workflows/domain_recon.yaml +46 -0
- secator/configs/workflows/host_recon.yaml +95 -0
- secator/configs/workflows/subdomain_recon.yaml +120 -0
- secator/configs/workflows/url_bypass.yaml +15 -0
- secator/configs/workflows/url_crawl.yaml +98 -0
- secator/configs/workflows/url_dirsearch.yaml +62 -0
- secator/configs/workflows/url_fuzz.yaml +68 -0
- secator/configs/workflows/url_params_fuzz.yaml +66 -0
- secator/configs/workflows/url_secrets_hunt.yaml +23 -0
- secator/configs/workflows/url_vuln.yaml +91 -0
- secator/configs/workflows/user_hunt.yaml +29 -0
- secator/configs/workflows/wordpress.yaml +38 -0
- secator/cve.py +718 -0
- secator/decorators.py +7 -0
- secator/definitions.py +168 -0
- secator/exporters/__init__.py +14 -0
- secator/exporters/_base.py +3 -0
- secator/exporters/console.py +10 -0
- secator/exporters/csv.py +37 -0
- secator/exporters/gdrive.py +123 -0
- secator/exporters/json.py +16 -0
- secator/exporters/table.py +36 -0
- secator/exporters/txt.py +28 -0
- secator/hooks/__init__.py +0 -0
- secator/hooks/gcs.py +80 -0
- secator/hooks/mongodb.py +281 -0
- secator/installer.py +694 -0
- secator/loader.py +128 -0
- secator/output_types/__init__.py +49 -0
- secator/output_types/_base.py +108 -0
- secator/output_types/certificate.py +78 -0
- secator/output_types/domain.py +50 -0
- secator/output_types/error.py +42 -0
- secator/output_types/exploit.py +58 -0
- secator/output_types/info.py +24 -0
- secator/output_types/ip.py +47 -0
- secator/output_types/port.py +55 -0
- secator/output_types/progress.py +36 -0
- secator/output_types/record.py +36 -0
- secator/output_types/stat.py +41 -0
- secator/output_types/state.py +29 -0
- secator/output_types/subdomain.py +45 -0
- secator/output_types/tag.py +69 -0
- secator/output_types/target.py +38 -0
- secator/output_types/url.py +112 -0
- secator/output_types/user_account.py +41 -0
- secator/output_types/vulnerability.py +101 -0
- secator/output_types/warning.py +30 -0
- secator/report.py +140 -0
- secator/rich.py +130 -0
- secator/runners/__init__.py +14 -0
- secator/runners/_base.py +1240 -0
- secator/runners/_helpers.py +218 -0
- secator/runners/celery.py +18 -0
- secator/runners/command.py +1178 -0
- secator/runners/python.py +126 -0
- secator/runners/scan.py +87 -0
- secator/runners/task.py +81 -0
- secator/runners/workflow.py +168 -0
- secator/scans/__init__.py +29 -0
- secator/serializers/__init__.py +8 -0
- secator/serializers/dataclass.py +39 -0
- secator/serializers/json.py +45 -0
- secator/serializers/regex.py +25 -0
- secator/tasks/__init__.py +8 -0
- secator/tasks/_categories.py +487 -0
- secator/tasks/arjun.py +113 -0
- secator/tasks/arp.py +53 -0
- secator/tasks/arpscan.py +70 -0
- secator/tasks/bbot.py +372 -0
- secator/tasks/bup.py +118 -0
- secator/tasks/cariddi.py +193 -0
- secator/tasks/dalfox.py +87 -0
- secator/tasks/dirsearch.py +84 -0
- secator/tasks/dnsx.py +186 -0
- secator/tasks/feroxbuster.py +93 -0
- secator/tasks/ffuf.py +135 -0
- secator/tasks/fping.py +85 -0
- secator/tasks/gau.py +102 -0
- secator/tasks/getasn.py +60 -0
- secator/tasks/gf.py +36 -0
- secator/tasks/gitleaks.py +96 -0
- secator/tasks/gospider.py +84 -0
- secator/tasks/grype.py +109 -0
- secator/tasks/h8mail.py +75 -0
- secator/tasks/httpx.py +167 -0
- secator/tasks/jswhois.py +36 -0
- secator/tasks/katana.py +203 -0
- secator/tasks/maigret.py +87 -0
- secator/tasks/mapcidr.py +42 -0
- secator/tasks/msfconsole.py +179 -0
- secator/tasks/naabu.py +85 -0
- secator/tasks/nmap.py +487 -0
- secator/tasks/nuclei.py +151 -0
- secator/tasks/search_vulns.py +225 -0
- secator/tasks/searchsploit.py +109 -0
- secator/tasks/sshaudit.py +299 -0
- secator/tasks/subfinder.py +48 -0
- secator/tasks/testssl.py +283 -0
- secator/tasks/trivy.py +130 -0
- secator/tasks/trufflehog.py +240 -0
- secator/tasks/urlfinder.py +100 -0
- secator/tasks/wafw00f.py +106 -0
- secator/tasks/whois.py +34 -0
- secator/tasks/wpprobe.py +116 -0
- secator/tasks/wpscan.py +202 -0
- secator/tasks/x8.py +94 -0
- secator/tasks/xurlfind3r.py +83 -0
- secator/template.py +294 -0
- secator/thread.py +24 -0
- secator/tree.py +196 -0
- secator/utils.py +922 -0
- secator/utils_test.py +297 -0
- secator/workflows/__init__.py +29 -0
- secator-0.22.0.dist-info/METADATA +447 -0
- secator-0.22.0.dist-info/RECORD +150 -0
- secator-0.22.0.dist-info/WHEEL +4 -0
- secator-0.22.0.dist-info/entry_points.txt +2 -0
- secator-0.22.0.dist-info/licenses/LICENSE +60 -0
secator/rich.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.table import Table
|
|
7
|
+
|
|
8
|
+
console = Console(stderr=True, record=True)
|
|
9
|
+
console_stdout = Console(record=True)
|
|
10
|
+
# handler = RichHandler(rich_tracebacks=True) # TODO: add logging handler
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def criticity_to_color(value):
|
|
14
|
+
if value == 'critical':
|
|
15
|
+
value = f'[bold red3]{value.upper()}[/]'
|
|
16
|
+
elif value == 'high':
|
|
17
|
+
value = f'[bold orange_red1]{value.upper()}[/]'
|
|
18
|
+
elif value == 'medium':
|
|
19
|
+
value = f'[bold dark_orange]{value.upper()}[/]'
|
|
20
|
+
elif value == 'low':
|
|
21
|
+
value = f'[bold yellow1]{value.upper()}[/]'
|
|
22
|
+
elif value == 'info':
|
|
23
|
+
value = f'[bold green]{value.upper()}[/]'
|
|
24
|
+
return value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def status_to_color(value):
|
|
28
|
+
value = int(value) if value else None
|
|
29
|
+
if value is None:
|
|
30
|
+
return value
|
|
31
|
+
if value < 400:
|
|
32
|
+
value = f'[bold green]{value}[/]'
|
|
33
|
+
elif value in [400, 499]:
|
|
34
|
+
value = f'[bold dark_orange]{value}[/]'
|
|
35
|
+
elif value >= 500:
|
|
36
|
+
value = f'[bold red3]{value}[/]'
|
|
37
|
+
return value
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
FORMATTERS = {
|
|
41
|
+
'confidence': lambda x: f'[dim]{x.upper()}[/]',
|
|
42
|
+
'severity': criticity_to_color,
|
|
43
|
+
'cvss_score': lambda score: '' if score == -1 else f'[bold cyan]{score}[/]',
|
|
44
|
+
'port': lambda port: f'[bold cyan]{port}[/]',
|
|
45
|
+
'url': lambda host: f'[bold underline blue link={host}]{host}[/]',
|
|
46
|
+
'stored_response_path': lambda path: f'[link=file://{path}]:pencil:[/]' if path and Path(path).exists() else '',
|
|
47
|
+
'screenshot_path': lambda path: f'[link=file://{path}]:camera:[/]' if path and Path(path).exists() else '',
|
|
48
|
+
'ip': lambda ip: f'[bold yellow]{ip}[/]',
|
|
49
|
+
'status_code': status_to_color,
|
|
50
|
+
'reference': lambda reference: f'[link={reference}]{reference}[/]' if reference else '',
|
|
51
|
+
'matched_at': lambda matched_at: f'[link={matched_at}]{matched_at}[/]' if matched_at and matched_at.startswith('http') else '', # noqa: E501
|
|
52
|
+
'match': lambda match: f'[link={match}]{match}[/]' if match else '',
|
|
53
|
+
'_source': lambda source: f'[bold gold3]{source}[/]'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def build_table(items, output_fields=[], exclude_fields=[], sort_by=None):
|
|
58
|
+
"""Build rich table.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
items (list): List of items.
|
|
62
|
+
output_fields (list, Optional): List of fields to add.
|
|
63
|
+
exclude_fields (list, Optional): List of fields to exclude.
|
|
64
|
+
sort_by (tuple, Optional): Tuple of sort_by keys.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
rich.table.Table: rich table.
|
|
68
|
+
"""
|
|
69
|
+
# Sort items by one or multiple fields
|
|
70
|
+
if sort_by and all(sort_by):
|
|
71
|
+
items = sorted(items, key=operator.attrgetter(*sort_by))
|
|
72
|
+
|
|
73
|
+
# Create rich table
|
|
74
|
+
table = Table(show_lines=True)
|
|
75
|
+
|
|
76
|
+
# Get table schema if any, default to first item keys
|
|
77
|
+
keys = []
|
|
78
|
+
if output_fields:
|
|
79
|
+
keys = [k for k in output_fields if k not in exclude_fields]
|
|
80
|
+
# Remove meta fields not needed in output
|
|
81
|
+
if '_cls' in keys:
|
|
82
|
+
keys.remove('_cls')
|
|
83
|
+
if '_type' in keys:
|
|
84
|
+
keys.remove('_type')
|
|
85
|
+
if '_uuid' in keys:
|
|
86
|
+
keys.remove('_uuid')
|
|
87
|
+
|
|
88
|
+
# Add _source field
|
|
89
|
+
if '_source' not in keys:
|
|
90
|
+
keys.append('_source')
|
|
91
|
+
|
|
92
|
+
# Create table columns
|
|
93
|
+
for key in keys:
|
|
94
|
+
key_str = key
|
|
95
|
+
if not key.startswith('_'):
|
|
96
|
+
key_str = ' '.join(key.split('_')).title()
|
|
97
|
+
# TODO: remove this as it's not needed anymore
|
|
98
|
+
# no_wrap = key in ['url', 'reference', 'references', 'matched_at']
|
|
99
|
+
# overflow = None if no_wrap else 'fold'
|
|
100
|
+
# print('key: ', key_str, 'overflow: ', overflow, 'no_wrap: ', no_wrap)
|
|
101
|
+
# table.add_column(
|
|
102
|
+
# key_str,
|
|
103
|
+
# overflow=overflow,
|
|
104
|
+
# min_width=10,
|
|
105
|
+
# no_wrap=no_wrap)
|
|
106
|
+
table.add_column(key_str)
|
|
107
|
+
|
|
108
|
+
if not keys:
|
|
109
|
+
table.add_column(
|
|
110
|
+
'Extracted values',
|
|
111
|
+
overflow=False,
|
|
112
|
+
min_width=10,
|
|
113
|
+
no_wrap=False)
|
|
114
|
+
|
|
115
|
+
# Create table rows
|
|
116
|
+
for item in items:
|
|
117
|
+
values = []
|
|
118
|
+
if keys:
|
|
119
|
+
for key in keys:
|
|
120
|
+
value = getattr(item, key) if keys else item
|
|
121
|
+
value = FORMATTERS.get(key, lambda x: x)(value) if keys else item
|
|
122
|
+
if isinstance(value, dict) or isinstance(value, list):
|
|
123
|
+
value = yaml.dump(value)
|
|
124
|
+
elif isinstance(value, int) or isinstance(value, float):
|
|
125
|
+
value = str(value)
|
|
126
|
+
values.append(value)
|
|
127
|
+
else:
|
|
128
|
+
values = [item]
|
|
129
|
+
table.add_row(*values)
|
|
130
|
+
return table
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
'Runner',
|
|
3
|
+
'Command',
|
|
4
|
+
'Task',
|
|
5
|
+
'Workflow',
|
|
6
|
+
'Scan',
|
|
7
|
+
'PythonRunner',
|
|
8
|
+
]
|
|
9
|
+
from secator.runners._base import Runner
|
|
10
|
+
from secator.runners.command import Command
|
|
11
|
+
from secator.runners.task import Task
|
|
12
|
+
from secator.runners.scan import Scan
|
|
13
|
+
from secator.runners.workflow import Workflow
|
|
14
|
+
from secator.runners.python import PythonRunner
|