secator 0.1.0__py2.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/.gitignore +162 -0
- secator/__init__.py +0 -0
- secator/celery.py +421 -0
- secator/cli.py +927 -0
- secator/config.py +137 -0
- secator/configs/__init__.py +0 -0
- secator/configs/profiles/__init__.py +0 -0
- secator/configs/profiles/aggressive.yaml +7 -0
- secator/configs/profiles/default.yaml +9 -0
- secator/configs/profiles/stealth.yaml +7 -0
- secator/configs/scans/__init__.py +0 -0
- secator/configs/scans/domain.yaml +18 -0
- secator/configs/scans/host.yaml +14 -0
- secator/configs/scans/network.yaml +17 -0
- secator/configs/scans/subdomain.yaml +8 -0
- secator/configs/scans/url.yaml +12 -0
- secator/configs/workflows/__init__.py +0 -0
- secator/configs/workflows/cidr_recon.yaml +28 -0
- secator/configs/workflows/code_scan.yaml +11 -0
- secator/configs/workflows/host_recon.yaml +41 -0
- secator/configs/workflows/port_scan.yaml +34 -0
- secator/configs/workflows/subdomain_recon.yaml +33 -0
- secator/configs/workflows/url_crawl.yaml +29 -0
- secator/configs/workflows/url_dirsearch.yaml +29 -0
- secator/configs/workflows/url_fuzz.yaml +35 -0
- secator/configs/workflows/url_nuclei.yaml +11 -0
- secator/configs/workflows/url_vuln.yaml +55 -0
- secator/configs/workflows/user_hunt.yaml +10 -0
- secator/configs/workflows/wordpress.yaml +14 -0
- secator/decorators.py +346 -0
- secator/definitions.py +183 -0
- secator/exporters/__init__.py +12 -0
- secator/exporters/_base.py +3 -0
- secator/exporters/csv.py +29 -0
- secator/exporters/gdrive.py +118 -0
- secator/exporters/json.py +14 -0
- secator/exporters/table.py +7 -0
- secator/exporters/txt.py +24 -0
- secator/hooks/__init__.py +0 -0
- secator/hooks/mongodb.py +212 -0
- secator/output_types/__init__.py +24 -0
- secator/output_types/_base.py +95 -0
- secator/output_types/exploit.py +50 -0
- secator/output_types/ip.py +33 -0
- secator/output_types/port.py +45 -0
- secator/output_types/progress.py +35 -0
- secator/output_types/record.py +34 -0
- secator/output_types/subdomain.py +42 -0
- secator/output_types/tag.py +46 -0
- secator/output_types/target.py +30 -0
- secator/output_types/url.py +76 -0
- secator/output_types/user_account.py +41 -0
- secator/output_types/vulnerability.py +97 -0
- secator/report.py +95 -0
- secator/rich.py +123 -0
- secator/runners/__init__.py +12 -0
- secator/runners/_base.py +873 -0
- secator/runners/_helpers.py +154 -0
- secator/runners/command.py +674 -0
- secator/runners/scan.py +67 -0
- secator/runners/task.py +107 -0
- secator/runners/workflow.py +137 -0
- secator/serializers/__init__.py +8 -0
- secator/serializers/dataclass.py +33 -0
- secator/serializers/json.py +15 -0
- secator/serializers/regex.py +17 -0
- secator/tasks/__init__.py +10 -0
- secator/tasks/_categories.py +304 -0
- secator/tasks/cariddi.py +102 -0
- secator/tasks/dalfox.py +66 -0
- secator/tasks/dirsearch.py +88 -0
- secator/tasks/dnsx.py +56 -0
- secator/tasks/dnsxbrute.py +34 -0
- secator/tasks/feroxbuster.py +89 -0
- secator/tasks/ffuf.py +85 -0
- secator/tasks/fping.py +44 -0
- secator/tasks/gau.py +43 -0
- secator/tasks/gf.py +34 -0
- secator/tasks/gospider.py +71 -0
- secator/tasks/grype.py +78 -0
- secator/tasks/h8mail.py +80 -0
- secator/tasks/httpx.py +104 -0
- secator/tasks/katana.py +128 -0
- secator/tasks/maigret.py +78 -0
- secator/tasks/mapcidr.py +32 -0
- secator/tasks/msfconsole.py +176 -0
- secator/tasks/naabu.py +52 -0
- secator/tasks/nmap.py +341 -0
- secator/tasks/nuclei.py +97 -0
- secator/tasks/searchsploit.py +53 -0
- secator/tasks/subfinder.py +40 -0
- secator/tasks/wpscan.py +177 -0
- secator/utils.py +404 -0
- secator/utils_test.py +183 -0
- secator-0.1.0.dist-info/METADATA +379 -0
- secator-0.1.0.dist-info/RECORD +99 -0
- secator-0.1.0.dist-info/WHEEL +5 -0
- secator-0.1.0.dist-info/entry_points.txt +2 -0
- secator-0.1.0.dist-info/licenses/LICENSE +60 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from secator.utils import deduplicate
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def run_extractors(results, opts, targets=[]):
|
|
7
|
+
"""Run extractors and merge extracted values with option dict.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
results (list): List of results.
|
|
11
|
+
opts (dict): Options.
|
|
12
|
+
targets (list): Original targets.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
tuple: targets, options.
|
|
16
|
+
"""
|
|
17
|
+
extractors = {k: v for k, v in opts.items() if k.endswith('_')}
|
|
18
|
+
for key, val in extractors.items():
|
|
19
|
+
key = key.rstrip('_')
|
|
20
|
+
values = extract_from_results(results, val)
|
|
21
|
+
if key == 'targets':
|
|
22
|
+
targets = deduplicate(values)
|
|
23
|
+
else:
|
|
24
|
+
opts[key] = deduplicate(values)
|
|
25
|
+
return targets, opts
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def extract_from_results(results, extractors):
|
|
29
|
+
"""Extract sub extractors from list of results dict.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
results (list): List of dict.
|
|
33
|
+
extractors (list): List of extractors to extract from.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
list: List of extracted results (flat).
|
|
37
|
+
"""
|
|
38
|
+
extracted = []
|
|
39
|
+
if not isinstance(extractors, list):
|
|
40
|
+
extractors = [extractors]
|
|
41
|
+
for extractor in extractors:
|
|
42
|
+
extracted.extend(process_extractor(results, extractor))
|
|
43
|
+
return extracted
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def process_extractor(results, extractor, ctx={}):
|
|
47
|
+
"""Process extractor.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
results (list): List of results.
|
|
51
|
+
extractor (dict / str): extractor definition.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
list: List of extracted results.
|
|
55
|
+
"""
|
|
56
|
+
if isinstance(extractor, dict):
|
|
57
|
+
_type = extractor['type']
|
|
58
|
+
_field = extractor.get('field')
|
|
59
|
+
_condition = extractor.get('condition', 'True')
|
|
60
|
+
else:
|
|
61
|
+
_type, _field = tuple(extractor.split('.'))
|
|
62
|
+
_condition = 'True'
|
|
63
|
+
items = [
|
|
64
|
+
item for item in results if item._type == _type and eval(_condition)
|
|
65
|
+
]
|
|
66
|
+
if _field:
|
|
67
|
+
_field = '{' + _field + '}' if not _field.startswith('{') else _field
|
|
68
|
+
items = [_field.format(**item.toDict()) for item in items]
|
|
69
|
+
return items
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_task_ids(result, ids=[]):
|
|
73
|
+
"""Get all Celery task ids recursively.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
result (Union[AsyncResult, GroupResult]): Celery result object.
|
|
77
|
+
ids (list): List of ids.
|
|
78
|
+
"""
|
|
79
|
+
from celery.result import AsyncResult, GroupResult
|
|
80
|
+
if result is None:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if isinstance(result, GroupResult):
|
|
84
|
+
get_task_ids(result.parent, ids=ids)
|
|
85
|
+
|
|
86
|
+
elif isinstance(result, AsyncResult):
|
|
87
|
+
if result.id not in ids:
|
|
88
|
+
ids.append(result.id)
|
|
89
|
+
|
|
90
|
+
if hasattr(result, 'children') and result.children:
|
|
91
|
+
for child in result.children:
|
|
92
|
+
get_task_ids(child, ids=ids)
|
|
93
|
+
|
|
94
|
+
# Browse parent
|
|
95
|
+
if hasattr(result, 'parent') and result.parent:
|
|
96
|
+
get_task_ids(result.parent, ids=ids)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def get_task_data(task_id):
|
|
100
|
+
"""Get task info.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
task_id (str): Celery task id.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
dict: Task info (id, name, state, results, chunk_info, count, error, ready).
|
|
107
|
+
"""
|
|
108
|
+
from celery.result import AsyncResult
|
|
109
|
+
res = AsyncResult(task_id)
|
|
110
|
+
if not (res and res.args and len(res.args) > 1):
|
|
111
|
+
return
|
|
112
|
+
data = {}
|
|
113
|
+
task_name = res.args[1]
|
|
114
|
+
data['id'] = task_id
|
|
115
|
+
data['name'] = task_name
|
|
116
|
+
data['state'] = res.state
|
|
117
|
+
data['chunk_info'] = ''
|
|
118
|
+
data['count'] = 0
|
|
119
|
+
data['error'] = None
|
|
120
|
+
data['ready'] = False
|
|
121
|
+
data['descr'] = ''
|
|
122
|
+
data['progress'] = 0
|
|
123
|
+
data['results'] = []
|
|
124
|
+
if res.state in ['FAILURE', 'SUCCESS', 'REVOKED']:
|
|
125
|
+
data['ready'] = True
|
|
126
|
+
if res.info and not isinstance(res.info, list):
|
|
127
|
+
chunk = res.info.get('chunk', '')
|
|
128
|
+
chunk_count = res.info.get('chunk_count', '')
|
|
129
|
+
data['chunk'] = chunk
|
|
130
|
+
data['chunk_count'] = chunk_count
|
|
131
|
+
if chunk:
|
|
132
|
+
data['chunk_info'] = f'{chunk}/{chunk_count}'
|
|
133
|
+
data.update(res.info)
|
|
134
|
+
data['descr'] = data.pop('description', '')
|
|
135
|
+
# del data['results']
|
|
136
|
+
# del data['task_results']
|
|
137
|
+
return data
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def get_task_folder_id(path):
|
|
141
|
+
names = []
|
|
142
|
+
if not os.path.exists(path):
|
|
143
|
+
return 0
|
|
144
|
+
for f in os.scandir(path):
|
|
145
|
+
if f.is_dir():
|
|
146
|
+
try:
|
|
147
|
+
int(f.name)
|
|
148
|
+
names.append(int(f.name))
|
|
149
|
+
except ValueError:
|
|
150
|
+
continue
|
|
151
|
+
names.sort()
|
|
152
|
+
if names:
|
|
153
|
+
return names[-1] + 1
|
|
154
|
+
return 0
|