secator 0.12.0__py3-none-any.whl → 0.14.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/cli.py +199 -66
- secator/configs/profiles/aggressive.yaml +6 -5
- secator/configs/profiles/default.yaml +6 -7
- secator/configs/profiles/insane.yaml +8 -0
- secator/configs/profiles/paranoid.yaml +8 -0
- secator/configs/profiles/polite.yaml +8 -0
- secator/configs/profiles/sneaky.yaml +8 -0
- secator/configs/profiles/tor.yaml +5 -0
- secator/configs/workflows/host_recon.yaml +11 -2
- secator/configs/workflows/url_dirsearch.yaml +5 -0
- secator/decorators.py +1 -0
- secator/definitions.py +0 -4
- secator/installer.py +29 -15
- secator/report.py +2 -2
- secator/runners/_base.py +32 -1
- secator/runners/_helpers.py +13 -2
- secator/runners/command.py +2 -1
- secator/runners/scan.py +1 -0
- secator/runners/task.py +1 -0
- secator/tasks/_categories.py +2 -2
- secator/tasks/arjun.py +2 -1
- secator/tasks/bbot.py +30 -4
- secator/tasks/bup.py +2 -1
- secator/tasks/cariddi.py +15 -3
- secator/tasks/dalfox.py +2 -1
- secator/tasks/dirsearch.py +1 -1
- secator/tasks/dnsx.py +2 -1
- secator/tasks/dnsxbrute.py +2 -1
- secator/tasks/feroxbuster.py +3 -2
- secator/tasks/ffuf.py +2 -1
- secator/tasks/gau.py +2 -1
- secator/tasks/gitleaks.py +4 -3
- secator/tasks/gospider.py +3 -2
- secator/tasks/grype.py +1 -0
- secator/tasks/h8mail.py +2 -1
- secator/tasks/httpx.py +3 -2
- secator/tasks/katana.py +4 -3
- secator/tasks/maigret.py +1 -1
- secator/tasks/mapcidr.py +2 -1
- secator/tasks/msfconsole.py +4 -3
- secator/tasks/naabu.py +4 -2
- secator/tasks/nuclei.py +15 -9
- secator/tasks/searchsploit.py +3 -2
- secator/tasks/subfinder.py +2 -1
- secator/tasks/testssl.py +4 -3
- secator/tasks/trivy.py +2 -2
- secator/tasks/wafw00f.py +2 -1
- secator/tasks/wpprobe.py +2 -1
- secator/tasks/wpscan.py +6 -3
- secator/template.py +1 -1
- {secator-0.12.0.dist-info → secator-0.14.0.dist-info}/METADATA +1 -1
- {secator-0.12.0.dist-info → secator-0.14.0.dist-info}/RECORD +55 -51
- secator/configs/profiles/stealth.yaml +0 -7
- {secator-0.12.0.dist-info → secator-0.14.0.dist-info}/WHEEL +0 -0
- {secator-0.12.0.dist-info → secator-0.14.0.dist-info}/entry_points.txt +0 -0
- {secator-0.12.0.dist-info → secator-0.14.0.dist-info}/licenses/LICENSE +0 -0
secator/report.py
CHANGED
|
@@ -55,7 +55,7 @@ class Report:
|
|
|
55
55
|
f'{str(e)}[/]\n[dim]{traceback_as_string(e)}[/]',
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
def build(self, extractors=[], dedupe=
|
|
58
|
+
def build(self, extractors=[], dedupe=CONFIG.runners.remove_duplicates):
|
|
59
59
|
# Trim options
|
|
60
60
|
from secator.decorators import DEFAULT_CLI_OPTIONS
|
|
61
61
|
opts = merge_opts(self.runner.config.options, self.runner.run_opts)
|
|
@@ -97,7 +97,7 @@ class Report:
|
|
|
97
97
|
if items:
|
|
98
98
|
if sort_by and all(sort_by):
|
|
99
99
|
items = sorted(items, key=operator.attrgetter(*sort_by))
|
|
100
|
-
if dedupe
|
|
100
|
+
if dedupe:
|
|
101
101
|
items = remove_duplicates(items)
|
|
102
102
|
# items = [item for item in items if not item._duplicate and item not in dedupe_from]
|
|
103
103
|
for extractor in extractors:
|
secator/runners/_base.py
CHANGED
|
@@ -130,13 +130,18 @@ class Runner:
|
|
|
130
130
|
|
|
131
131
|
# Determine inputs
|
|
132
132
|
self.inputs = [inputs] if not isinstance(inputs, list) else inputs
|
|
133
|
-
self.
|
|
133
|
+
targets = [Target(name=target) for target in self.inputs]
|
|
134
|
+
self.filter_results(results + targets)
|
|
134
135
|
|
|
135
136
|
# Debug
|
|
136
137
|
self.debug('Inputs', obj=self.inputs, sub='init')
|
|
137
138
|
self.debug('Run opts', obj={k: v for k, v in self.run_opts.items() if v is not None}, sub='init')
|
|
138
139
|
self.debug('Print opts', obj={k: v for k, v in self.print_opts.items() if v is not None}, sub='init')
|
|
139
140
|
|
|
141
|
+
# Load profiles
|
|
142
|
+
profiles_str = run_opts.get('profiles', [])
|
|
143
|
+
self.load_profiles(profiles_str)
|
|
144
|
+
|
|
140
145
|
# Determine exporters
|
|
141
146
|
exporters_str = self.run_opts.get('output') or self.default_exporters
|
|
142
147
|
self.exporters = self.resolve_exporters(exporters_str)
|
|
@@ -952,6 +957,32 @@ class Runner:
|
|
|
952
957
|
]
|
|
953
958
|
return [cls for cls in classes if cls]
|
|
954
959
|
|
|
960
|
+
def load_profiles(self, profiles):
|
|
961
|
+
"""Load profiles and update run options.
|
|
962
|
+
|
|
963
|
+
Args:
|
|
964
|
+
profiles (list[str]): List of profile names to resolve.
|
|
965
|
+
|
|
966
|
+
Returns:
|
|
967
|
+
list: List of profiles.
|
|
968
|
+
"""
|
|
969
|
+
from secator.cli import ALL_PROFILES
|
|
970
|
+
if isinstance(profiles, str):
|
|
971
|
+
profiles = profiles.split(',')
|
|
972
|
+
templates = []
|
|
973
|
+
for pname in profiles:
|
|
974
|
+
matches = [p for p in ALL_PROFILES if p.name == pname]
|
|
975
|
+
if not matches:
|
|
976
|
+
self._print(Warning(message=f'Profile "{pname}" was not found'), rich=True)
|
|
977
|
+
else:
|
|
978
|
+
templates.append(matches[0])
|
|
979
|
+
opts = {}
|
|
980
|
+
for profile in templates:
|
|
981
|
+
self._print(Info(message=f'Loaded profile {profile.name} ({profile.description})'), rich=True)
|
|
982
|
+
opts.update(profile.opts)
|
|
983
|
+
opts = {k: v for k, v in opts.items() if k not in self.run_opts}
|
|
984
|
+
self.run_opts.update(opts)
|
|
985
|
+
|
|
955
986
|
@classmethod
|
|
956
987
|
def get_func_path(cls, func):
|
|
957
988
|
"""Get the full symbolic path of a function or method, including staticmethods, using function and method
|
secator/runners/_helpers.py
CHANGED
|
@@ -18,14 +18,25 @@ def run_extractors(results, opts, inputs=[], dry_run=False):
|
|
|
18
18
|
"""
|
|
19
19
|
extractors = {k: v for k, v in opts.items() if k.endswith('_')}
|
|
20
20
|
errors = []
|
|
21
|
+
computed_inputs = []
|
|
22
|
+
computed_opts = {}
|
|
21
23
|
for key, val in extractors.items():
|
|
22
24
|
key = key.rstrip('_')
|
|
23
25
|
values, err = extract_from_results(results, val)
|
|
24
26
|
errors.extend(err)
|
|
25
27
|
if key == 'targets':
|
|
26
|
-
|
|
28
|
+
targets = ['<COMPUTED>'] if dry_run else deduplicate(values)
|
|
29
|
+
computed_inputs.extend(targets)
|
|
27
30
|
else:
|
|
28
|
-
|
|
31
|
+
computed_opt = ['<COMPUTED>'] if dry_run else deduplicate(values)
|
|
32
|
+
if computed_opt:
|
|
33
|
+
computed_opts[key] = computed_opt
|
|
34
|
+
opts[key] = computed_opts[key]
|
|
35
|
+
if computed_inputs:
|
|
36
|
+
debug('computed_inputs', obj=computed_inputs, sub='extractors')
|
|
37
|
+
inputs = computed_inputs
|
|
38
|
+
if computed_opts:
|
|
39
|
+
debug('computed_opts', obj=computed_opts, sub='extractors')
|
|
29
40
|
return inputs, opts, errors
|
|
30
41
|
|
|
31
42
|
|
secator/runners/command.py
CHANGED
|
@@ -84,6 +84,7 @@ class Command(Runner):
|
|
|
84
84
|
install_post = None
|
|
85
85
|
install_cmd = None
|
|
86
86
|
install_github_handle = None
|
|
87
|
+
install_version = None
|
|
87
88
|
|
|
88
89
|
# Serializer
|
|
89
90
|
item_loader = None
|
|
@@ -246,7 +247,7 @@ class Command(Runner):
|
|
|
246
247
|
def get_version_info(cls):
|
|
247
248
|
from secator.installer import get_version_info
|
|
248
249
|
return get_version_info(
|
|
249
|
-
cls.
|
|
250
|
+
cls.cmd.split(' ')[0],
|
|
250
251
|
cls.get_version_flag(),
|
|
251
252
|
cls.install_github_handle,
|
|
252
253
|
cls.install_cmd
|
secator/runners/scan.py
CHANGED
|
@@ -33,6 +33,7 @@ class Scan(Runner):
|
|
|
33
33
|
sigs = []
|
|
34
34
|
for name, workflow_opts in self.config.workflows.items():
|
|
35
35
|
run_opts = self.run_opts.copy()
|
|
36
|
+
run_opts.pop('profiles', None)
|
|
36
37
|
run_opts['no_poll'] = True
|
|
37
38
|
run_opts['caller'] = 'Scan'
|
|
38
39
|
opts = merge_opts(scan_opts, workflow_opts, run_opts)
|
secator/runners/task.py
CHANGED
secator/tasks/_categories.py
CHANGED
|
@@ -27,7 +27,7 @@ USER_AGENTS = {
|
|
|
27
27
|
OPTS = {
|
|
28
28
|
HEADER: {'type': str, 'help': 'Custom header to add to each request in the form "KEY1:VALUE1; KEY2:VALUE2"', 'default': 'User-Agent: ' + USER_AGENTS['chrome_134.0_win10']}, # noqa: E501
|
|
29
29
|
DELAY: {'type': float, 'short': 'd', 'help': 'Delay to add between each requests'},
|
|
30
|
-
DEPTH: {'type': int, 'help': 'Scan depth'
|
|
30
|
+
DEPTH: {'type': int, 'help': 'Scan depth'},
|
|
31
31
|
FILTER_CODES: {'type': str, 'short': 'fc', 'help': 'Filter out responses with HTTP codes'},
|
|
32
32
|
FILTER_REGEX: {'type': str, 'short': 'fr', 'help': 'Filter out responses with regular expression'},
|
|
33
33
|
FILTER_SIZE: {'type': str, 'short': 'fs', 'help': 'Filter out responses with size'},
|
|
@@ -41,7 +41,7 @@ OPTS = {
|
|
|
41
41
|
PROXY: {'type': str, 'help': 'HTTP(s) / SOCKS5 proxy'},
|
|
42
42
|
RATE_LIMIT: {'type': int, 'short': 'rl', 'help': 'Rate limit, i.e max number of requests per second'},
|
|
43
43
|
RETRIES: {'type': int, 'help': 'Retries'},
|
|
44
|
-
THREADS: {'type': int, 'help': 'Number of threads to run'
|
|
44
|
+
THREADS: {'type': int, 'help': 'Number of threads to run'},
|
|
45
45
|
TIMEOUT: {'type': int, 'help': 'Request timeout'},
|
|
46
46
|
USER_AGENT: {'type': str, 'short': 'ua', 'help': 'User agent, e.g "Mozilla Firefox 1.0"'},
|
|
47
47
|
WORDLIST: {'type': str, 'short': 'w', 'default': 'http', 'process': process_wordlist, 'help': 'Wordlist to use'}
|
secator/tasks/arjun.py
CHANGED
|
@@ -49,7 +49,8 @@ class arjun(Command):
|
|
|
49
49
|
'follow_redirect': '--follow-redirect',
|
|
50
50
|
}
|
|
51
51
|
output_types = [Url]
|
|
52
|
-
|
|
52
|
+
install_version = '2.2.7'
|
|
53
|
+
install_cmd = 'pipx install arjun==[install_version] --force'
|
|
53
54
|
install_github_handle = 's0md3v/Arjun'
|
|
54
55
|
|
|
55
56
|
@staticmethod
|
secator/tasks/bbot.py
CHANGED
|
@@ -121,6 +121,29 @@ BBOT_PRESETS = [
|
|
|
121
121
|
'web-screenshots',
|
|
122
122
|
'web-thorough'
|
|
123
123
|
]
|
|
124
|
+
BBOT_FLAGS = [
|
|
125
|
+
'active',
|
|
126
|
+
'affiliates',
|
|
127
|
+
'aggressive',
|
|
128
|
+
'baddns',
|
|
129
|
+
'cloud-enum,'
|
|
130
|
+
'code-enum,deadly',
|
|
131
|
+
'email-enum',
|
|
132
|
+
'iis-shortnames',
|
|
133
|
+
'passive',
|
|
134
|
+
'portscan',
|
|
135
|
+
'report',
|
|
136
|
+
'safe',
|
|
137
|
+
'service-enum',
|
|
138
|
+
'slow',
|
|
139
|
+
'social-enum',
|
|
140
|
+
'subdomain-enum',
|
|
141
|
+
'subdomain-hijack',
|
|
142
|
+
'web-basic',
|
|
143
|
+
'web-paramminer',
|
|
144
|
+
'web-screenshots',
|
|
145
|
+
'web-thorough'
|
|
146
|
+
]
|
|
124
147
|
BBOT_MODULES_STR = ' '.join(BBOT_MODULES)
|
|
125
148
|
BBOT_MAP_TYPES = {
|
|
126
149
|
'IP_ADDRESS': Ip,
|
|
@@ -159,12 +182,14 @@ class bbot(Command):
|
|
|
159
182
|
file_flag = None
|
|
160
183
|
version_flag = '--help'
|
|
161
184
|
opts = {
|
|
162
|
-
'modules': {'type': str, 'short': 'm', '
|
|
163
|
-
'presets': {'type': str, 'short': 'ps', '
|
|
185
|
+
'modules': {'type': str, 'short': 'm', 'help': ','.join(BBOT_MODULES)},
|
|
186
|
+
'presets': {'type': str, 'short': 'ps', 'help': ','.join(BBOT_PRESETS), 'shlex': False},
|
|
187
|
+
'flags': {'type': str, 'short': 'fl', 'help': ','.join(BBOT_FLAGS)}
|
|
164
188
|
}
|
|
165
189
|
opt_key_map = {
|
|
166
190
|
'modules': 'm',
|
|
167
|
-
'presets': 'p'
|
|
191
|
+
'presets': 'p',
|
|
192
|
+
'flags': 'f'
|
|
168
193
|
}
|
|
169
194
|
opt_value_map = {
|
|
170
195
|
'presets': lambda x: ' '.join(x.split(','))
|
|
@@ -222,7 +247,8 @@ class bbot(Command):
|
|
|
222
247
|
'apk': ['python3-dev', 'linux-headers', 'musl-dev', 'gcc', 'git', 'openssl', 'unzip', 'tar', 'chromium'],
|
|
223
248
|
'*': ['gcc', 'git', 'openssl', 'unzip', 'tar', 'chromium']
|
|
224
249
|
}
|
|
225
|
-
|
|
250
|
+
install_version = '2.4.2'
|
|
251
|
+
install_cmd = 'pipx install bbot==[install_version] --force'
|
|
226
252
|
install_post = {
|
|
227
253
|
'*': f'rm -fr {CONFIG.dirs.share}/pipx/venvs/bbot/lib/python3.12/site-packages/ansible_collections/*'
|
|
228
254
|
}
|
secator/tasks/bup.py
CHANGED
|
@@ -63,7 +63,8 @@ class bup(Http):
|
|
|
63
63
|
'stored_response_path': 'response_html_filename',
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
install_version = '0.4.4'
|
|
67
|
+
install_cmd = 'pipx install bypass-url-parser==[install_version] --force'
|
|
67
68
|
|
|
68
69
|
@staticmethod
|
|
69
70
|
def on_init(self):
|
secator/tasks/cariddi.py
CHANGED
|
@@ -13,12 +13,19 @@ 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
|
|
16
|
+
cmd = 'cariddi'
|
|
17
17
|
input_type = URL
|
|
18
18
|
input_flag = OPT_PIPE_INPUT
|
|
19
19
|
output_types = [Url, Tag]
|
|
20
20
|
file_flag = OPT_PIPE_INPUT
|
|
21
21
|
json_flag = '-json'
|
|
22
|
+
opts = {
|
|
23
|
+
'info': {'is_flag': True, 'short': 'info', 'help': 'Hunt for useful informations in websites.'},
|
|
24
|
+
'secrets': {'is_flag': True, 'short': 'secrets', 'help': 'Hunt for secrets.'},
|
|
25
|
+
'errors': {'is_flag': True, 'short': 'err', 'help': 'Hunt for errors in websites.'},
|
|
26
|
+
'juicy_extensions': {'type': int, 'short': 'jext', 'help': 'Hunt for juicy file extensions. Integer from 1(juicy) to 7(not juicy)'}, # noqa: E501
|
|
27
|
+
'juicy_endpoints': {'is_flag': True, 'short': 'jep', 'help': 'Hunt for juicy endpoints.'}
|
|
28
|
+
}
|
|
22
29
|
opt_key_map = {
|
|
23
30
|
HEADER: 'headers',
|
|
24
31
|
DELAY: 'd',
|
|
@@ -38,10 +45,15 @@ class cariddi(HttpCrawler):
|
|
|
38
45
|
RETRIES: OPT_NOT_SUPPORTED,
|
|
39
46
|
THREADS: 'c',
|
|
40
47
|
TIMEOUT: 't',
|
|
41
|
-
USER_AGENT: 'ua'
|
|
48
|
+
USER_AGENT: 'ua',
|
|
49
|
+
'secrets': 's',
|
|
50
|
+
'errors': 'err',
|
|
51
|
+
'juicy_endpoints': 'e',
|
|
52
|
+
'juicy_extensions': 'ext'
|
|
42
53
|
}
|
|
43
54
|
item_loaders = [JSONSerializer()]
|
|
44
|
-
|
|
55
|
+
install_version = 'v1.3.6'
|
|
56
|
+
install_cmd = 'go install -v github.com/edoardottt/cariddi/cmd/cariddi@[install_version]'
|
|
45
57
|
install_github_handle = 'edoardottt/cariddi'
|
|
46
58
|
encoding = 'ansi'
|
|
47
59
|
proxychains = False
|
secator/tasks/dalfox.py
CHANGED
|
@@ -55,7 +55,8 @@ class dalfox(VulnHttp):
|
|
|
55
55
|
SEVERITY: lambda x: x['severity'].lower()
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
install_version = 'v2.11.0'
|
|
59
|
+
install_cmd = 'go install -v github.com/hahwul/dalfox/v2@latest'
|
|
59
60
|
install_github_handle = 'hahwul/dalfox'
|
|
60
61
|
encoding = 'ansi'
|
|
61
62
|
proxychains = False
|
secator/tasks/dirsearch.py
CHANGED
|
@@ -52,7 +52,7 @@ class dirsearch(HttpFuzzer):
|
|
|
52
52
|
STATUS_CODE: 'status'
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
install_cmd = 'pipx install
|
|
55
|
+
install_cmd = 'pipx install git+https://github.com/maurosoria/dirsearch.git --force'
|
|
56
56
|
proxychains = True
|
|
57
57
|
proxy_socks5 = True
|
|
58
58
|
proxy_http = True
|
secator/tasks/dnsx.py
CHANGED
|
@@ -26,7 +26,8 @@ class dnsx(ReconDns):
|
|
|
26
26
|
'wildcard_domain': {'type': str, 'short': 'wd', 'help': 'Domain name for wildcard filtering'},
|
|
27
27
|
}
|
|
28
28
|
item_loaders = [JSONSerializer()]
|
|
29
|
-
|
|
29
|
+
install_version = 'v1.2.2'
|
|
30
|
+
install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
|
|
30
31
|
install_github_handle = 'projectdiscovery/dnsx'
|
|
31
32
|
profile = 'io'
|
|
32
33
|
|
secator/tasks/dnsxbrute.py
CHANGED
|
@@ -34,6 +34,7 @@ class dnsxbrute(ReconDns):
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
install_version = 'v1.2.2'
|
|
38
|
+
install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
|
|
38
39
|
install_github_handle = 'projectdiscovery/dnsx'
|
|
39
40
|
profile = 'io'
|
secator/tasks/feroxbuster.py
CHANGED
|
@@ -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
|
|
9
|
+
THREADS, TIMEOUT, USER_AGENT, WORDLIST, WORDS)
|
|
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,7 @@ 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 =
|
|
18
|
+
cmd = 'feroxbuster --auto-bail --no-state'
|
|
19
19
|
input_flag = '--url'
|
|
20
20
|
input_chunk_size = 1
|
|
21
21
|
file_flag = OPT_PIPE_INPUT
|
|
@@ -62,6 +62,7 @@ class feroxbuster(HttpFuzzer):
|
|
|
62
62
|
install_pre = {
|
|
63
63
|
'*': ['curl', 'bash']
|
|
64
64
|
}
|
|
65
|
+
install_version = 'v2.11.0'
|
|
65
66
|
install_cmd = (
|
|
66
67
|
f'cd /tmp && curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | bash -s {CONFIG.dirs.bin}' # noqa: E501
|
|
67
68
|
)
|
secator/tasks/ffuf.py
CHANGED
|
@@ -71,7 +71,8 @@ class ffuf(HttpFuzzer):
|
|
|
71
71
|
},
|
|
72
72
|
}
|
|
73
73
|
encoding = 'ansi'
|
|
74
|
-
|
|
74
|
+
install_version = 'v2.1.0'
|
|
75
|
+
install_cmd = 'go install -v github.com/ffuf/ffuf/v2@[install_version]'
|
|
75
76
|
install_github_handle = 'ffuf/ffuf'
|
|
76
77
|
proxychains = False
|
|
77
78
|
proxy_socks5 = True
|
secator/tasks/gau.py
CHANGED
|
@@ -44,7 +44,8 @@ class gau(HttpCrawler):
|
|
|
44
44
|
install_pre = {
|
|
45
45
|
'apk': ['libc6-compat']
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
install_version = 'v2.2.4'
|
|
48
|
+
install_cmd = 'go install -v github.com/lc/gau/v2/cmd/gau@[install_version]'
|
|
48
49
|
install_github_handle = 'lc/gau'
|
|
49
50
|
proxychains = False
|
|
50
51
|
proxy_socks5 = True
|
secator/tasks/gitleaks.py
CHANGED
|
@@ -35,10 +35,11 @@ class gitleaks(Command):
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
install_pre = {'*': ['git', 'make']}
|
|
38
|
+
install_version = 'v8.24.3'
|
|
38
39
|
install_cmd = (
|
|
39
|
-
f'git clone https://github.com/gitleaks/gitleaks.git {CONFIG.dirs.share}/
|
|
40
|
-
f'cd {CONFIG.dirs.share}/
|
|
41
|
-
f'mv {CONFIG.dirs.share}/
|
|
40
|
+
f'git clone https://github.com/gitleaks/gitleaks.git {CONFIG.dirs.share}/gitleaks_[install_version] || true &&'
|
|
41
|
+
f'cd {CONFIG.dirs.share}/gitleaks_[install_version] && make build &&'
|
|
42
|
+
f'mv {CONFIG.dirs.share}/gitleaks_[install_version]/gitleaks {CONFIG.dirs.bin}'
|
|
42
43
|
)
|
|
43
44
|
install_github_handle = 'gitleaks/gitleaks'
|
|
44
45
|
|
secator/tasks/gospider.py
CHANGED
|
@@ -15,7 +15,7 @@ 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
|
|
18
|
+
cmd = 'gospider'
|
|
19
19
|
file_flag = '-S'
|
|
20
20
|
input_flag = '-s'
|
|
21
21
|
json_flag = '--json'
|
|
@@ -53,7 +53,8 @@ class gospider(HttpCrawler):
|
|
|
53
53
|
CONTENT_LENGTH: 'length',
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
install_version = 'v1.1.6'
|
|
57
|
+
install_cmd = 'go install -v github.com/jaeles-project/gospider@[install_version]'
|
|
57
58
|
install_github_handle = 'jaeles-project/gospider'
|
|
58
59
|
proxychains = False
|
|
59
60
|
proxy_socks5 = True # with leaks... https://github.com/jaeles-project/gospider/issues/61
|
secator/tasks/grype.py
CHANGED
secator/tasks/h8mail.py
CHANGED
|
@@ -21,7 +21,8 @@ class h8mail(OSInt):
|
|
|
21
21
|
'config': {'type': str, 'help': 'Configuration file for API keys'},
|
|
22
22
|
'local_breach': {'type': str, 'short': 'lb', 'help': 'Local breach file'}
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
install_version = '2.5.6'
|
|
25
|
+
install_cmd = 'pipx install h8mail==[install_version] --force'
|
|
25
26
|
|
|
26
27
|
@staticmethod
|
|
27
28
|
def on_start(self):
|
secator/tasks/httpx.py
CHANGED
|
@@ -33,7 +33,7 @@ class httpx(Http):
|
|
|
33
33
|
'system_chrome': {'is_flag': True, 'default': False, 'help': 'Use local installed Chrome for screenshot'},
|
|
34
34
|
'headless_options': {'is_flag': False, 'short': 'ho', 'default': None, 'help': 'Headless Chrome additional options'},
|
|
35
35
|
'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':
|
|
36
|
+
'tech_detect': {'is_flag': True, 'short': 'td', 'default': False, 'help': 'Tech detection'},
|
|
37
37
|
'tls_grab': {'is_flag': True, 'short': 'tlsg', 'default': False, 'help': 'Grab some informations from the tls certificate'}, # noqa: E501
|
|
38
38
|
'rstr': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to read (bytes)'},
|
|
39
39
|
'rsts': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to save (bytes)'}
|
|
@@ -68,7 +68,8 @@ class httpx(Http):
|
|
|
68
68
|
install_pre = {
|
|
69
69
|
'apk': ['chromium']
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
install_version = 'v1.7.0'
|
|
72
|
+
install_cmd = 'go install -v github.com/projectdiscovery/httpx/cmd/httpx@[install_version]'
|
|
72
73
|
install_github_handle = 'projectdiscovery/httpx'
|
|
73
74
|
proxychains = False
|
|
74
75
|
proxy_socks5 = True
|
secator/tasks/katana.py
CHANGED
|
@@ -26,8 +26,8 @@ class katana(HttpCrawler):
|
|
|
26
26
|
'form_extraction': {'is_flag': True, 'short': 'fx', 'help': 'Detect forms'},
|
|
27
27
|
'store_responses': {'is_flag': True, 'short': 'sr', 'default': CONFIG.http.store_responses, 'help': 'Store responses'}, # noqa: E501
|
|
28
28
|
'form_fill': {'is_flag': True, 'short': 'ff', 'help': 'Enable form filling'},
|
|
29
|
-
'js_crawl': {'is_flag': True, 'short': 'jc', 'default':
|
|
30
|
-
'jsluice': {'is_flag': True, 'short': 'jsl', 'default':
|
|
29
|
+
'js_crawl': {'is_flag': True, 'short': 'jc', 'default': False, 'help': 'Enable endpoint parsing / crawling in javascript file'}, # noqa: E501
|
|
30
|
+
'jsluice': {'is_flag': True, 'short': 'jsl', 'default': False, 'help': 'Enable jsluice parsing in javascript file (memory intensive)'}, # noqa: E501
|
|
31
31
|
'known_files': {'type': str, 'short': 'kf', 'default': 'all', 'help': 'Enable crawling of known files (all, robotstxt, sitemapxml)'}, # noqa: E501
|
|
32
32
|
'omit_raw': {'is_flag': True, 'short': 'or', 'default': True, 'help': 'Omit raw requests/responses from jsonl output'}, # noqa: E501
|
|
33
33
|
'omit_body': {'is_flag': True, 'short': 'ob', 'default': True, 'help': 'Omit response body from jsonl output'},
|
|
@@ -78,7 +78,8 @@ class katana(HttpCrawler):
|
|
|
78
78
|
install_pre = {
|
|
79
79
|
'apk': ['libc6-compat']
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
install_version = 'v1.1.3'
|
|
82
|
+
install_cmd = 'go install -v github.com/projectdiscovery/katana/cmd/katana@[install_version]'
|
|
82
83
|
install_github_handle = 'projectdiscovery/katana'
|
|
83
84
|
proxychains = False
|
|
84
85
|
proxy_socks5 = True
|
secator/tasks/maigret.py
CHANGED
|
@@ -41,7 +41,7 @@ class maigret(ReconUser):
|
|
|
41
41
|
EXTRA_DATA: lambda x: x['status'].get('ids', {})
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
install_cmd = 'pipx install git+https://github.com/soxoj/maigret'
|
|
44
|
+
install_cmd = 'pipx install git+https://github.com/soxoj/maigret --force'
|
|
45
45
|
socks5_proxy = True
|
|
46
46
|
profile = 'io'
|
|
47
47
|
|
secator/tasks/mapcidr.py
CHANGED
|
@@ -16,7 +16,8 @@ class mapcidr(ReconIp):
|
|
|
16
16
|
install_pre = {
|
|
17
17
|
'apk': ['libc6-compat']
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
install_version = 'v1.1.34'
|
|
20
|
+
install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@[install_version]'
|
|
20
21
|
install_github_handle = 'projectdiscovery/mapcidr'
|
|
21
22
|
input_type = CIDR_RANGE
|
|
22
23
|
output_types = [Ip]
|
secator/tasks/msfconsole.py
CHANGED
|
@@ -48,14 +48,15 @@ class msfconsole(VulnMulti):
|
|
|
48
48
|
'pacman': ['ruby-erb', 'postgresql-libs', 'make'],
|
|
49
49
|
'yum|zypper': ['postgresql-devel', 'make'],
|
|
50
50
|
}
|
|
51
|
+
install_version = '6.4.59'
|
|
51
52
|
install_cmd = (
|
|
52
|
-
f'git clone --depth 1 --single-branch https://github.com/rapid7/metasploit-framework.git {CONFIG.dirs.share}/metasploit-
|
|
53
|
-
f'cd {CONFIG.dirs.share}/metasploit-
|
|
53
|
+
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
|
|
54
|
+
f'cd {CONFIG.dirs.share}/metasploit-framework_[install_version] && '
|
|
54
55
|
f'gem install bundler --user-install -n {CONFIG.dirs.bin} && '
|
|
55
56
|
f'bundle config set --local path "{CONFIG.dirs.share}" && '
|
|
56
57
|
'bundle lock --normalize-platforms &&'
|
|
57
58
|
'bundle install && '
|
|
58
|
-
f'ln -sf $HOME/.local/share/metasploit-
|
|
59
|
+
f'ln -sf $HOME/.local/share/metasploit-framework_[install_version]/msfconsole {CONFIG.dirs.bin}/msfconsole'
|
|
59
60
|
)
|
|
60
61
|
|
|
61
62
|
@staticmethod
|
secator/tasks/naabu.py
CHANGED
|
@@ -10,7 +10,7 @@ from secator.tasks._categories import ReconPort
|
|
|
10
10
|
@task()
|
|
11
11
|
class naabu(ReconPort):
|
|
12
12
|
"""Port scanning tool written in Go."""
|
|
13
|
-
cmd = 'naabu
|
|
13
|
+
cmd = 'naabu'
|
|
14
14
|
input_flag = '-host'
|
|
15
15
|
file_flag = '-list'
|
|
16
16
|
json_flag = '-json'
|
|
@@ -18,6 +18,7 @@ class naabu(ReconPort):
|
|
|
18
18
|
PORTS: {'type': str, 'short': 'p', 'help': 'Ports'},
|
|
19
19
|
TOP_PORTS: {'type': str, 'short': 'tp', 'help': 'Top ports'},
|
|
20
20
|
'scan_type': {'type': str, 'short': 'st', 'help': 'Scan type (SYN (s)/CONNECT(c))'},
|
|
21
|
+
'skip_host_discovery': {'is_flag': True, 'short': 'Pn', 'default': False, 'help': 'Skip host discovery'},
|
|
21
22
|
# 'health_check': {'is_flag': True, 'short': 'hc', 'help': 'Health check'}
|
|
22
23
|
}
|
|
23
24
|
opt_key_map = {
|
|
@@ -47,7 +48,8 @@ class naabu(ReconPort):
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
output_types = [Port]
|
|
50
|
-
|
|
51
|
+
install_version = 'v2.3.3'
|
|
52
|
+
install_cmd = 'go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@[install_version]'
|
|
51
53
|
install_github_handle = 'projectdiscovery/naabu'
|
|
52
54
|
install_pre = {'apt': ['libpcap-dev'], 'apk': ['libpcap-dev', 'libc6-compat'], 'pacman|brew': ['libpcap']}
|
|
53
55
|
install_post = {'arch|alpine': 'sudo ln -sf /usr/lib/libpcap.so /usr/lib/libpcap.so.0.8'}
|
secator/tasks/nuclei.py
CHANGED
|
@@ -18,17 +18,22 @@ class nuclei(VulnMulti):
|
|
|
18
18
|
input_flag = '-u'
|
|
19
19
|
json_flag = '-jsonl'
|
|
20
20
|
opts = {
|
|
21
|
-
'
|
|
22
|
-
'tags': {'type': str, 'help': 'Tags'},
|
|
23
|
-
'exclude_tags': {'type': str, 'short': 'etags', 'help': 'Exclude tags'},
|
|
24
|
-
'exclude_severity': {'type': str, 'short': 'es', 'help': 'Exclude severity'},
|
|
25
|
-
'template_id': {'type': str, 'short': 'tid', 'help': 'Template id'},
|
|
21
|
+
'bulk_size': {'type': int, 'short': 'bs', 'help': 'Maximum number of hosts to be analyzed in parallel per template'}, # noqa: E501
|
|
26
22
|
'debug': {'type': str, 'help': 'Debug mode'},
|
|
23
|
+
'exclude_severity': {'type': str, 'short': 'es', 'help': 'Exclude severity'},
|
|
24
|
+
'exclude_tags': {'type': str, 'short': 'etags', 'help': 'Exclude tags'},
|
|
25
|
+
'input_mode': {'type': str, 'short': 'im', 'help': 'Mode of input file (list, burp, jsonl, yaml, openapi, swagger)'},
|
|
26
|
+
'hang_monitor': {'is_flag': True, 'short': 'hm', 'default': True, 'help': 'Enable nuclei hang monitoring'},
|
|
27
|
+
'headless_bulk_size': {'type': int, 'short': 'hbs', 'help': 'Maximum number of headless hosts to be analzyed in parallel per template'}, # noqa: E501
|
|
28
|
+
'new_templates': {'type': str, 'short': 'nt', 'help': 'Run only new templates added in latest nuclei-templates release'}, # noqa: E501
|
|
29
|
+
'automatic_scan': {'is_flag': True, 'short': 'as', 'help': 'Automatic web scan using wappalyzer technology detection to tags mapping'}, # noqa: E501
|
|
30
|
+
'omit_raw': {'is_flag': True, 'short': 'or', 'default': True, 'help': 'Omit requests/response pairs in the JSON, JSONL, and Markdown outputs (for findings only)'}, # noqa: E501
|
|
27
31
|
'stats': {'is_flag': True, 'short': 'stats', 'default': True, 'help': 'Display statistics about the running scan'},
|
|
28
32
|
'stats_json': {'is_flag': True, 'short': 'sj', 'default': True, 'help': 'Display statistics in JSONL(ines) format'},
|
|
29
|
-
'stats_interval': {'type': str, 'short': 'si', '
|
|
30
|
-
'
|
|
31
|
-
'
|
|
33
|
+
'stats_interval': {'type': str, 'short': 'si', 'help': 'Number of seconds to wait between showing a statistics update'}, # noqa: E501
|
|
34
|
+
'tags': {'type': str, 'help': 'Tags'},
|
|
35
|
+
'templates': {'type': str, 'short': 't', 'help': 'Templates'},
|
|
36
|
+
'template_id': {'type': str, 'short': 'tid', 'help': 'Template id'},
|
|
32
37
|
}
|
|
33
38
|
opt_key_map = {
|
|
34
39
|
HEADER: 'header',
|
|
@@ -76,7 +81,8 @@ class nuclei(VulnMulti):
|
|
|
76
81
|
install_pre = {
|
|
77
82
|
'*': ['git']
|
|
78
83
|
}
|
|
79
|
-
|
|
84
|
+
install_version = 'v3.4.2'
|
|
85
|
+
install_cmd = 'go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@[install_version]'
|
|
80
86
|
install_github_handle = 'projectdiscovery/nuclei'
|
|
81
87
|
install_post = {
|
|
82
88
|
'*': 'nuclei -ut'
|
secator/tasks/searchsploit.py
CHANGED
|
@@ -41,9 +41,10 @@ class searchsploit(Command):
|
|
|
41
41
|
install_pre = {
|
|
42
42
|
'apk': ['ncurses']
|
|
43
43
|
}
|
|
44
|
+
install_version = '2025-04-23'
|
|
44
45
|
install_cmd = (
|
|
45
|
-
f'git clone --depth 1 --single-branch https://gitlab.com/exploit-database/exploitdb.git {CONFIG.dirs.share}/
|
|
46
|
-
f'ln -sf $HOME/.local/share/
|
|
46
|
+
f'git clone --depth 1 --single-branch -b [install_version] https://gitlab.com/exploit-database/exploitdb.git {CONFIG.dirs.share}/exploitdb_[install_version] || true && ' # noqa: E501
|
|
47
|
+
f'ln -sf $HOME/.local/share/exploitdb_[install_version]/searchsploit {CONFIG.dirs.bin}/searchsploit'
|
|
47
48
|
)
|
|
48
49
|
proxychains = False
|
|
49
50
|
proxy_socks5 = False
|
secator/tasks/subfinder.py
CHANGED
|
@@ -31,7 +31,8 @@ class subfinder(ReconDns):
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
output_types = [Subdomain]
|
|
34
|
-
|
|
34
|
+
install_version = 'v2.7.0'
|
|
35
|
+
install_cmd = 'go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@[install_version]'
|
|
35
36
|
install_github_handle = 'projectdiscovery/subfinder'
|
|
36
37
|
proxychains = False
|
|
37
38
|
proxy_http = True
|
secator/tasks/testssl.py
CHANGED
|
@@ -48,13 +48,14 @@ class testssl(Command):
|
|
|
48
48
|
proxy_socks5 = False
|
|
49
49
|
profile = 'io'
|
|
50
50
|
install_pre = {
|
|
51
|
-
'apk': ['hexdump'],
|
|
51
|
+
'apk': ['hexdump', 'coreutils', 'procps'],
|
|
52
52
|
'pacman': ['util-linux'],
|
|
53
53
|
'*': ['bsdmainutils']
|
|
54
54
|
}
|
|
55
|
+
install_version = 'v3.2.0'
|
|
55
56
|
install_cmd = (
|
|
56
|
-
f'git clone --depth 1 https://github.com/drwetter/testssl.sh.git {CONFIG.dirs.share}/testssl.
|
|
57
|
-
f'ln -sf {CONFIG.dirs.share}/testssl.
|
|
57
|
+
f'git clone --depth 1 --single-branch -b [install_version] https://github.com/drwetter/testssl.sh.git {CONFIG.dirs.share}/testssl.sh_[install_version] || true && ' # noqa: E501
|
|
58
|
+
f'ln -sf {CONFIG.dirs.share}/testssl.sh_[install_version]/testssl.sh {CONFIG.dirs.bin}'
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
@staticmethod
|