secator 0.2.0__py2.py3-none-any.whl → 0.3.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/cli.py +445 -405
- secator/decorators.py +2 -2
- secator/definitions.py +25 -5
- secator/exporters/txt.py +1 -1
- secator/installer.py +192 -0
- secator/runners/command.py +2 -16
- secator/tasks/dalfox.py +1 -0
- secator/tasks/dnsx.py +1 -0
- secator/tasks/dnsxbrute.py +1 -0
- secator/tasks/feroxbuster.py +1 -0
- secator/tasks/ffuf.py +1 -0
- secator/tasks/gau.py +1 -0
- secator/tasks/gospider.py +1 -0
- secator/tasks/grype.py +1 -0
- secator/tasks/httpx.py +1 -0
- secator/tasks/katana.py +1 -0
- secator/tasks/mapcidr.py +1 -0
- secator/tasks/naabu.py +1 -0
- secator/tasks/nuclei.py +1 -0
- secator/tasks/subfinder.py +1 -0
- secator/utils_test.py +1 -0
- {secator-0.2.0.dist-info → secator-0.3.0.dist-info}/METADATA +1 -1
- {secator-0.2.0.dist-info → secator-0.3.0.dist-info}/RECORD +26 -25
- {secator-0.2.0.dist-info → secator-0.3.0.dist-info}/WHEEL +0 -0
- {secator-0.2.0.dist-info → secator-0.3.0.dist-info}/entry_points.txt +0 -0
- {secator-0.2.0.dist-info → secator-0.3.0.dist-info}/licenses/LICENSE +0 -0
secator/decorators.py
CHANGED
|
@@ -53,7 +53,7 @@ class OrderedGroup(RichGroup):
|
|
|
53
53
|
if not name:
|
|
54
54
|
raise click.UsageError("`name` command argument is required when using aliases.")
|
|
55
55
|
|
|
56
|
-
f.__doc__ = f.__doc__ or '
|
|
56
|
+
f.__doc__ = f.__doc__ or '\0'.ljust(padding+1)
|
|
57
57
|
f.__doc__ = f'{f.__doc__:<{padding}}[dim](aliases)[/] {aliases_str}'
|
|
58
58
|
base_command = super(OrderedGroup, self).command(
|
|
59
59
|
name, *args, **kwargs
|
|
@@ -79,7 +79,7 @@ class OrderedGroup(RichGroup):
|
|
|
79
79
|
max_width = _get_rich_console().width
|
|
80
80
|
aliases_str = ', '.join(f'[bold cyan]{alias}[/]' for alias in aliases)
|
|
81
81
|
padding = max_width // 4
|
|
82
|
-
f.__doc__ = f.__doc__ or '
|
|
82
|
+
f.__doc__ = f.__doc__ or '\0'.ljust(padding+1)
|
|
83
83
|
f.__doc__ = f'{f.__doc__:<{padding}}[dim](aliases)[/] {aliases_str}'
|
|
84
84
|
for alias in aliases:
|
|
85
85
|
grp = super(OrderedGroup, self).group(
|
secator/definitions.py
CHANGED
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/python
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import requests
|
|
4
5
|
|
|
5
6
|
from dotenv import find_dotenv, load_dotenv
|
|
6
|
-
from pkg_resources import get_distribution
|
|
7
|
+
from pkg_resources import get_distribution, parse_version
|
|
7
8
|
|
|
8
9
|
load_dotenv(find_dotenv(usecwd=True), override=False)
|
|
9
10
|
|
|
11
|
+
|
|
12
|
+
def get_latest_version():
|
|
13
|
+
"""Get latest secator version from GitHub API."""
|
|
14
|
+
try:
|
|
15
|
+
resp = requests.get('https://api.github.com/repos/freelabz/secator/releases/latest', timeout=2)
|
|
16
|
+
resp.raise_for_status()
|
|
17
|
+
latest_version = resp.json()['name'].lstrip('v')
|
|
18
|
+
return latest_version
|
|
19
|
+
except (requests.exceptions.RequestException):
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
|
|
10
23
|
# Globals
|
|
11
24
|
VERSION = get_distribution('secator').version
|
|
25
|
+
VERSION_LATEST = get_latest_version()
|
|
26
|
+
VERSION_OBSOLETE = parse_version(VERSION_LATEST) > parse_version(VERSION) if VERSION_LATEST else False
|
|
27
|
+
VERSION_STR = f'{VERSION} [bold red](outdated)[/]' if VERSION_OBSOLETE else VERSION
|
|
28
|
+
|
|
12
29
|
ASCII = f"""
|
|
13
30
|
__
|
|
14
31
|
________ _________ _/ /_____ _____
|
|
15
32
|
/ ___/ _ \/ ___/ __ `/ __/ __ \/ ___/
|
|
16
33
|
(__ / __/ /__/ /_/ / /_/ /_/ / /
|
|
17
|
-
/____/\___/\___/\__,_/\__/\____/_/ v{
|
|
34
|
+
/____/\___/\___/\__,_/\__/\____/_/ v{VERSION_STR}
|
|
18
35
|
|
|
19
36
|
freelabz.com
|
|
20
37
|
""" # noqa: W605,W291
|
|
@@ -24,6 +41,7 @@ ROOT_FOLDER = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
|
24
41
|
LIB_FOLDER = ROOT_FOLDER + '/secator'
|
|
25
42
|
CONFIGS_FOLDER = LIB_FOLDER + '/configs'
|
|
26
43
|
EXTRA_CONFIGS_FOLDER = os.environ.get('SECATOR_EXTRA_CONFIGS_FOLDER')
|
|
44
|
+
BIN_FOLDER = os.environ.get('SECATOR_BIN_FOLDER', f'{os.path.expanduser("~")}/.local/bin')
|
|
27
45
|
DATA_FOLDER = os.environ.get('SECATOR_DATA_FOLDER', f'{os.path.expanduser("~")}/.secator')
|
|
28
46
|
REPORTS_FOLDER = os.environ.get('SECATOR_REPORTS_FOLDER', f'{DATA_FOLDER}/reports')
|
|
29
47
|
WORDLISTS_FOLDER = os.environ.get('SECATOR_WORDLISTS_FOLDER', f'{DATA_FOLDER}/wordlists')
|
|
@@ -32,6 +50,7 @@ CVES_FOLDER = f'{DATA_FOLDER}/cves'
|
|
|
32
50
|
PAYLOADS_FOLDER = f'{DATA_FOLDER}/payloads'
|
|
33
51
|
REVSHELLS_FOLDER = f'{DATA_FOLDER}/revshells'
|
|
34
52
|
TESTS_FOLDER = f'{ROOT_FOLDER}/tests'
|
|
53
|
+
os.makedirs(BIN_FOLDER, exist_ok=True)
|
|
35
54
|
os.makedirs(DATA_FOLDER, exist_ok=True)
|
|
36
55
|
os.makedirs(REPORTS_FOLDER, exist_ok=True)
|
|
37
56
|
os.makedirs(WORDLISTS_FOLDER, exist_ok=True)
|
|
@@ -58,6 +77,7 @@ CELERY_BROKER_VISIBILITY_TIMEOUT = int(os.environ.get('CELERY_BROKER_VISIBILITY_
|
|
|
58
77
|
CELERY_OVERRIDE_DEFAULT_LOGGING = bool(int(os.environ.get('CELERY_OVERRIDE_DEFAULT_LOGGING', 1)))
|
|
59
78
|
GOOGLE_DRIVE_PARENT_FOLDER_ID = os.environ.get('GOOGLE_DRIVE_PARENT_FOLDER_ID')
|
|
60
79
|
GOOGLE_CREDENTIALS_PATH = os.environ.get('GOOGLE_CREDENTIALS_PATH')
|
|
80
|
+
GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN')
|
|
61
81
|
|
|
62
82
|
# Defaults HTTP and Proxy settings
|
|
63
83
|
DEFAULT_SOCKS5_PROXY = os.environ.get('SOCKS5_PROXY', "socks5://127.0.0.1:9050")
|
|
@@ -205,7 +225,7 @@ except ModuleNotFoundError:
|
|
|
205
225
|
TRACE_ADDON_ENABLED = 0
|
|
206
226
|
|
|
207
227
|
# Check dev package
|
|
208
|
-
if
|
|
209
|
-
DEV_PACKAGE = 0
|
|
210
|
-
else:
|
|
228
|
+
if os.path.exists(f'{ROOT_FOLDER}/pyproject.toml'):
|
|
211
229
|
DEV_PACKAGE = 1
|
|
230
|
+
else:
|
|
231
|
+
DEV_PACKAGE = 0
|
secator/exporters/txt.py
CHANGED
|
@@ -11,7 +11,7 @@ class TxtExporter(Exporter):
|
|
|
11
11
|
items = [str(i) for i in items]
|
|
12
12
|
if not items:
|
|
13
13
|
continue
|
|
14
|
-
txt_path = f'{self.report.output_folder}/
|
|
14
|
+
txt_path = f'{self.report.output_folder}/report_{output_type}.txt'
|
|
15
15
|
with open(txt_path, 'w') as f:
|
|
16
16
|
f.write('\n'.join(items))
|
|
17
17
|
txt_paths.append(txt_path)
|
secator/installer.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
|
|
2
|
+
import requests
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import shutil
|
|
6
|
+
import tarfile
|
|
7
|
+
import zipfile
|
|
8
|
+
import io
|
|
9
|
+
|
|
10
|
+
from secator.rich import console
|
|
11
|
+
from secator.runners import Command
|
|
12
|
+
from secator.definitions import BIN_FOLDER, GITHUB_TOKEN
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ToolInstaller:
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def install(cls, tool_cls):
|
|
19
|
+
"""Install a tool.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
cls: ToolInstaller class.
|
|
23
|
+
tool_cls: Tool class (derived from secator.runners.Command).
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
bool: True if install is successful, False otherwise.
|
|
27
|
+
"""
|
|
28
|
+
console.print(f'[bold gold3]:wrench: Installing {tool_cls.__name__}')
|
|
29
|
+
success = False
|
|
30
|
+
|
|
31
|
+
if not tool_cls.install_github_handle and not tool_cls.install_cmd:
|
|
32
|
+
console.print(
|
|
33
|
+
f'[bold red]{tool_cls.__name__} install is not supported yet. Please install it manually.[/]')
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
if tool_cls.install_github_handle:
|
|
37
|
+
success = GithubInstaller.install(tool_cls.install_github_handle)
|
|
38
|
+
|
|
39
|
+
if tool_cls.install_cmd and not success:
|
|
40
|
+
success = SourceInstaller.install(tool_cls.install_cmd)
|
|
41
|
+
|
|
42
|
+
if success:
|
|
43
|
+
console.print(
|
|
44
|
+
f'[bold green]:tada: {tool_cls.__name__} installed successfully[/] !')
|
|
45
|
+
else:
|
|
46
|
+
console.print(
|
|
47
|
+
f'[bold red]:exclamation_mark: Failed to install {tool_cls.__name__}.[/]')
|
|
48
|
+
return success
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SourceInstaller:
|
|
52
|
+
"""Install a tool from source."""
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def install(cls, install_cmd):
|
|
56
|
+
"""Install from source.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
cls: ToolInstaller class.
|
|
60
|
+
install_cmd (str): Install command.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
bool: True if install is successful, False otherwise.
|
|
64
|
+
"""
|
|
65
|
+
ret = Command.execute(install_cmd, cls_attributes={'shell': True})
|
|
66
|
+
return ret.return_code == 0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class GithubInstaller:
|
|
70
|
+
"""Install a tool from GitHub releases."""
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def install(cls, github_handle):
|
|
74
|
+
"""Find and install a release from a GitHub handle {user}/{repo}.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
github_handle (str): A GitHub handle {user}/{repo}
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
bool: True if install is successful,, False otherwise.
|
|
81
|
+
"""
|
|
82
|
+
owner, repo = tuple(github_handle.split('/'))
|
|
83
|
+
releases_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
|
|
84
|
+
|
|
85
|
+
# Query latest release endpoint
|
|
86
|
+
headers = {}
|
|
87
|
+
if GITHUB_TOKEN:
|
|
88
|
+
headers['Authorization'] = f'Bearer {GITHUB_TOKEN}'
|
|
89
|
+
response = requests.get(releases_url, headers=headers)
|
|
90
|
+
if response.status_code == 403:
|
|
91
|
+
console.print('[bold red]Rate-limited by GitHub API. Retry later or set a GITHUB_TOKEN.')
|
|
92
|
+
return False
|
|
93
|
+
elif response.status_code == 404:
|
|
94
|
+
console.print('[dim red]No GitHub releases found.')
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
# Find the right asset to download
|
|
98
|
+
latest_release = response.json()
|
|
99
|
+
os_identifiers, arch_identifiers = cls._get_platform_identifier()
|
|
100
|
+
download_url = cls._find_matching_asset(latest_release['assets'], os_identifiers, arch_identifiers)
|
|
101
|
+
if not download_url:
|
|
102
|
+
console.print('[dim red]Could not find a GitHub release matching distribution.[/]')
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
# Download and unpack asset
|
|
106
|
+
console.print(f'Found release URL: {download_url}')
|
|
107
|
+
cls._download_and_unpack(download_url, BIN_FOLDER, repo)
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def _get_platform_identifier(cls):
|
|
112
|
+
"""Generate lists of possible identifiers for the current platform."""
|
|
113
|
+
system = platform.system().lower()
|
|
114
|
+
arch = platform.machine().lower()
|
|
115
|
+
|
|
116
|
+
# Mapping common platform.system() values to those found in release names
|
|
117
|
+
os_mapping = {
|
|
118
|
+
'linux': ['linux'],
|
|
119
|
+
'windows': ['windows', 'win'],
|
|
120
|
+
'darwin': ['darwin', 'macos', 'osx', 'mac']
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
# Enhanced architecture mapping to avoid conflicts
|
|
124
|
+
arch_mapping = {
|
|
125
|
+
'x86_64': ['amd64', 'x86_64'],
|
|
126
|
+
'amd64': ['amd64', 'x86_64'],
|
|
127
|
+
'aarch64': ['arm64', 'aarch64'],
|
|
128
|
+
'armv7l': ['armv7', 'arm'],
|
|
129
|
+
'386': ['386', 'x86', 'i386'],
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
os_identifiers = os_mapping.get(system, [])
|
|
133
|
+
arch_identifiers = arch_mapping.get(arch, [])
|
|
134
|
+
return os_identifiers, arch_identifiers
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def _find_matching_asset(cls, assets, os_identifiers, arch_identifiers):
|
|
138
|
+
"""Find a release asset matching the current platform more precisely."""
|
|
139
|
+
potential_matches = []
|
|
140
|
+
|
|
141
|
+
for asset in assets:
|
|
142
|
+
asset_name = asset['name'].lower()
|
|
143
|
+
if any(os_id in asset_name for os_id in os_identifiers) and \
|
|
144
|
+
any(arch_id in asset_name for arch_id in arch_identifiers):
|
|
145
|
+
potential_matches.append(asset['browser_download_url'])
|
|
146
|
+
|
|
147
|
+
# Preference ordering for file formats, if needed
|
|
148
|
+
preferred_formats = ['.tar.gz', '.zip']
|
|
149
|
+
|
|
150
|
+
for format in preferred_formats:
|
|
151
|
+
for match in potential_matches:
|
|
152
|
+
if match.endswith(format):
|
|
153
|
+
return match
|
|
154
|
+
|
|
155
|
+
if potential_matches:
|
|
156
|
+
return potential_matches[0]
|
|
157
|
+
|
|
158
|
+
@classmethod
|
|
159
|
+
def _download_and_unpack(cls, url, destination, repo_name):
|
|
160
|
+
"""Download and unpack a release asset."""
|
|
161
|
+
console.print(f'Downloading and unpacking to {destination}...')
|
|
162
|
+
response = requests.get(url)
|
|
163
|
+
response.raise_for_status()
|
|
164
|
+
|
|
165
|
+
# Create a temporary directory to extract the archive
|
|
166
|
+
temp_dir = os.path.join("/tmp", repo_name)
|
|
167
|
+
os.makedirs(temp_dir, exist_ok=True)
|
|
168
|
+
|
|
169
|
+
if url.endswith('.zip'):
|
|
170
|
+
with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:
|
|
171
|
+
zip_ref.extractall(temp_dir)
|
|
172
|
+
elif url.endswith('.tar.gz'):
|
|
173
|
+
with tarfile.open(fileobj=io.BytesIO(response.content), mode='r:gz') as tar:
|
|
174
|
+
tar.extractall(path=temp_dir)
|
|
175
|
+
|
|
176
|
+
# For archives, find and move the binary that matches the repo name
|
|
177
|
+
binary_path = cls._find_binary_in_directory(temp_dir, repo_name)
|
|
178
|
+
if binary_path:
|
|
179
|
+
os.chmod(binary_path, 0o755) # Make it executable
|
|
180
|
+
shutil.move(binary_path, os.path.join(destination, repo_name)) # Move the binary
|
|
181
|
+
else:
|
|
182
|
+
console.print('[bold red]Binary matching the repository name was not found in the archive.[/]')
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def _find_binary_in_directory(cls, directory, binary_name):
|
|
186
|
+
"""Search for the binary in the given directory that matches the repository name."""
|
|
187
|
+
for root, _, files in os.walk(directory):
|
|
188
|
+
for file in files:
|
|
189
|
+
# Match the file name exactly with the repository name
|
|
190
|
+
if file == binary_name:
|
|
191
|
+
return os.path.join(root, file)
|
|
192
|
+
return None
|
secator/runners/command.py
CHANGED
|
@@ -16,7 +16,6 @@ from secator.definitions import (DEFAULT_HTTP_PROXY,
|
|
|
16
16
|
DEFAULT_PROXYCHAINS_COMMAND,
|
|
17
17
|
DEFAULT_SOCKS5_PROXY, OPT_NOT_SUPPORTED,
|
|
18
18
|
OPT_PIPE_INPUT, DEFAULT_INPUT_CHUNK_SIZE)
|
|
19
|
-
from secator.rich import console
|
|
20
19
|
from secator.runners import Runner
|
|
21
20
|
from secator.serializers import JSONSerializer
|
|
22
21
|
from secator.utils import debug
|
|
@@ -81,8 +80,9 @@ class Command(Runner):
|
|
|
81
80
|
# Flag to show version
|
|
82
81
|
version_flag = None
|
|
83
82
|
|
|
84
|
-
# Install
|
|
83
|
+
# Install
|
|
85
84
|
install_cmd = None
|
|
85
|
+
install_github_handle = None
|
|
86
86
|
|
|
87
87
|
# Serializer
|
|
88
88
|
item_loader = None
|
|
@@ -252,20 +252,6 @@ class Command(Runner):
|
|
|
252
252
|
# Class methods #
|
|
253
253
|
#---------------#
|
|
254
254
|
|
|
255
|
-
@classmethod
|
|
256
|
-
def install(cls):
|
|
257
|
-
"""Install command by running the content of cls.install_cmd."""
|
|
258
|
-
console.print(f':heavy_check_mark: Installing {cls.__name__}...', style='bold yellow')
|
|
259
|
-
if not cls.install_cmd:
|
|
260
|
-
console.print(f'{cls.__name__} install is not supported yet. Please install it manually.', style='bold red')
|
|
261
|
-
return
|
|
262
|
-
ret = cls.execute(cls.install_cmd, name=cls.__name__, cls_attributes={'shell': True})
|
|
263
|
-
if ret.return_code != 0:
|
|
264
|
-
console.print(f':exclamation_mark: Failed to install {cls.__name__}.', style='bold red')
|
|
265
|
-
else:
|
|
266
|
-
console.print(f':tada: {cls.__name__} installed successfully !', style='bold green')
|
|
267
|
-
return ret
|
|
268
|
-
|
|
269
255
|
@classmethod
|
|
270
256
|
def execute(cls, cmd, name=None, cls_attributes={}, **kwargs):
|
|
271
257
|
"""Execute an ad-hoc command.
|
secator/tasks/dalfox.py
CHANGED
secator/tasks/dnsx.py
CHANGED
secator/tasks/dnsxbrute.py
CHANGED
secator/tasks/feroxbuster.py
CHANGED
|
@@ -64,6 +64,7 @@ class feroxbuster(HttpFuzzer):
|
|
|
64
64
|
'curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | '
|
|
65
65
|
'bash && sudo mv feroxbuster /usr/local/bin'
|
|
66
66
|
)
|
|
67
|
+
install_github_handle = 'epi052/feroxbuster'
|
|
67
68
|
proxychains = False
|
|
68
69
|
proxy_socks5 = True
|
|
69
70
|
proxy_http = True
|
secator/tasks/ffuf.py
CHANGED
|
@@ -71,6 +71,7 @@ class ffuf(HttpFuzzer):
|
|
|
71
71
|
}
|
|
72
72
|
encoding = 'ansi'
|
|
73
73
|
install_cmd = f'go install -v github.com/ffuf/ffuf@latest && sudo git clone https://github.com/danielmiessler/SecLists {WORDLISTS_FOLDER}/seclists || true' # noqa: E501
|
|
74
|
+
install_github_handle = 'ffuf/ffuf'
|
|
74
75
|
proxychains = False
|
|
75
76
|
proxy_socks5 = True
|
|
76
77
|
proxy_http = True
|
secator/tasks/gau.py
CHANGED
secator/tasks/gospider.py
CHANGED
|
@@ -52,6 +52,7 @@ class gospider(HttpCrawler):
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
install_cmd = 'go install -v github.com/jaeles-project/gospider@latest'
|
|
55
|
+
install_github_handle = 'jaeles-project/gospider'
|
|
55
56
|
ignore_return_code = True
|
|
56
57
|
proxychains = False
|
|
57
58
|
proxy_socks5 = True # with leaks... https://github.com/jaeles-project/gospider/issues/61
|
secator/tasks/grype.py
CHANGED
secator/tasks/httpx.py
CHANGED
|
@@ -60,6 +60,7 @@ class httpx(Http):
|
|
|
60
60
|
DELAY: lambda x: str(x) + 's' if x else None,
|
|
61
61
|
}
|
|
62
62
|
install_cmd = 'go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest'
|
|
63
|
+
install_github_handle = 'projectdiscovery/httpx'
|
|
63
64
|
proxychains = False
|
|
64
65
|
proxy_socks5 = True
|
|
65
66
|
proxy_http = True
|
secator/tasks/katana.py
CHANGED
|
@@ -71,6 +71,7 @@ class katana(HttpCrawler):
|
|
|
71
71
|
}
|
|
72
72
|
item_loaders = []
|
|
73
73
|
install_cmd = 'sudo apt install build-essential && go install -v github.com/projectdiscovery/katana/cmd/katana@latest'
|
|
74
|
+
install_github_handle = 'projectdiscovery/katana'
|
|
74
75
|
proxychains = False
|
|
75
76
|
proxy_socks5 = True
|
|
76
77
|
proxy_http = True
|
secator/tasks/mapcidr.py
CHANGED
|
@@ -14,6 +14,7 @@ class mapcidr(ReconIp):
|
|
|
14
14
|
input_flag = '-cidr'
|
|
15
15
|
file_flag = '-cl'
|
|
16
16
|
install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@latest'
|
|
17
|
+
install_github_handle = 'projectdiscovery/mapcidr'
|
|
17
18
|
input_type = CIDR_RANGE
|
|
18
19
|
output_types = [Ip]
|
|
19
20
|
opt_key_map = {
|
secator/tasks/naabu.py
CHANGED
|
@@ -46,6 +46,7 @@ class naabu(ReconPort):
|
|
|
46
46
|
}
|
|
47
47
|
output_types = [Port]
|
|
48
48
|
install_cmd = 'sudo apt install -y build-essential libpcap-dev && go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@latest' # noqa: E501
|
|
49
|
+
install_github_handle = 'projectdiscovery/naabu'
|
|
49
50
|
proxychains = False
|
|
50
51
|
proxy_socks5 = True
|
|
51
52
|
proxy_http = False
|
secator/tasks/nuclei.py
CHANGED
|
@@ -68,6 +68,7 @@ class nuclei(VulnMulti):
|
|
|
68
68
|
}
|
|
69
69
|
ignore_return_code = True
|
|
70
70
|
install_cmd = 'go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest && nuclei update-templates'
|
|
71
|
+
install_github_handle = 'projectdiscovery/nuclei'
|
|
71
72
|
proxychains = False
|
|
72
73
|
proxy_socks5 = True # kind of, leaks data when running network / dns templates
|
|
73
74
|
proxy_http = True # same
|
secator/tasks/subfinder.py
CHANGED
|
@@ -30,6 +30,7 @@ class subfinder(ReconDns):
|
|
|
30
30
|
}
|
|
31
31
|
output_types = [Subdomain]
|
|
32
32
|
install_cmd = 'go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest'
|
|
33
|
+
install_github_handle = 'projectdiscovery/subfinder'
|
|
33
34
|
proxychains = False
|
|
34
35
|
proxy_http = True
|
|
35
36
|
proxy_socks5 = False
|
secator/utils_test.py
CHANGED
|
@@ -92,6 +92,7 @@ META_OPTS = {
|
|
|
92
92
|
'msfconsole.resource': load_fixture('msfconsole_input', FIXTURES_DIR, only_path=True),
|
|
93
93
|
'dirsearch.output_path': load_fixture('dirsearch_output', FIXTURES_DIR, only_path=True),
|
|
94
94
|
'maigret.output_path': load_fixture('maigret_output', FIXTURES_DIR, only_path=True),
|
|
95
|
+
'nuclei.template_id': 'prometheus-metrics',
|
|
95
96
|
'wpscan.output_path': load_fixture('wpscan_output', FIXTURES_DIR, only_path=True),
|
|
96
97
|
'h8mail.output_path': load_fixture('h8mail_output', FIXTURES_DIR, only_path=True),
|
|
97
98
|
'h8mail.local_breach': load_fixture('h8mail_breach', FIXTURES_DIR, only_path=True)
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
secator/.gitignore,sha256=da8MUc3hdb6Mo0WjZu2upn5uZMbXcBGvhdhTQ1L89HI,3093
|
|
2
2
|
secator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
secator/celery.py,sha256=zXjg7EKneWjErBTNrJCHOXCJzs-P5jBi5gYqrSqjW4k,12227
|
|
4
|
-
secator/cli.py,sha256=
|
|
4
|
+
secator/cli.py,sha256=MmB7KpOm7w0JA1ZMD15yE_zLTAZtGypc5rKN7-3i8gw,33245
|
|
5
5
|
secator/config.py,sha256=iOeRzq7u1rvR1-Oq5v9wGxQYB613X0xKGLIcrfhEGc4,3693
|
|
6
|
-
secator/decorators.py,sha256=
|
|
7
|
-
secator/definitions.py,sha256=
|
|
6
|
+
secator/decorators.py,sha256=Ueti-ppprM4e2vnx-QY9U_hpll990hkSxbMFPfbq6MY,10524
|
|
7
|
+
secator/definitions.py,sha256=DNxiXCtTqpg6wYory2E9J_Cpop7_9iyGn0GMcFuGwnY,7306
|
|
8
|
+
secator/installer.py,sha256=FEYHgdt5yS8_pJ8tvDBaOByB-47aL21oE8cOBm-dHA8,5943
|
|
8
9
|
secator/report.py,sha256=g0stVCcx9klbUS01uKvWcxNE9MJfNFMexYA2SoDIWJU,2596
|
|
9
10
|
secator/rich.py,sha256=7-uKJrQWiCKM0gPNIr_cr1c9KrcJSVd2ht-DgLXhBro,3392
|
|
10
11
|
secator/utils.py,sha256=oJEEls4Z8SfTxiG6keCfqLMMWA97ftS5aiABhBPRduU,9964
|
|
11
|
-
secator/utils_test.py,sha256=
|
|
12
|
+
secator/utils_test.py,sha256=xVF9RH1-p3X0TdmODJi4k62H7Xth96Ib7qnUZ4vAJs8,5043
|
|
12
13
|
secator/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
14
|
secator/configs/profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
15
|
secator/configs/profiles/aggressive.yaml,sha256=JilVySABlSCYEFMjH7V0Oc3dAVlkfHOh1odTGhtm7BQ,108
|
|
@@ -39,7 +40,7 @@ secator/exporters/csv.py,sha256=xsPMljzJhoTc8lcfxWBIKH2niK6KeYL7Bx2NzpdsYw0,982
|
|
|
39
40
|
secator/exporters/gdrive.py,sha256=VI6r1vlChz39myaN4sFvOlHO32SAhZS5_mI5EwGUdq8,4056
|
|
40
41
|
secator/exporters/json.py,sha256=cWkDugUdy-lbcPFKNgBrRFxHspiFhjVbJfdDABjJ9uk,431
|
|
41
42
|
secator/exporters/table.py,sha256=RHQoaFeeyeoBGNucJgrlk2KtmVqe9BGNtAAYee7xJ8Y,210
|
|
42
|
-
secator/exporters/txt.py,sha256=
|
|
43
|
+
secator/exporters/txt.py,sha256=QbiwWYGgHpITGw1sL2TX-S3AfmBdJ-VOWkPJzuBvOu4,785
|
|
43
44
|
secator/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
45
|
secator/hooks/mongodb.py,sha256=GTd6BeiGtWUPWjmXKmalZYNoeGNZfNqEJ6BxRJh1Mr8,7149
|
|
45
46
|
secator/output_types/__init__.py,sha256=uj6AXDeorECPwhwekNVGjQbGv41jHG_8udkuoc4XzW0,854
|
|
@@ -58,7 +59,7 @@ secator/output_types/vulnerability.py,sha256=p0DTbr5w7Vv5D3dgbdnvsG5qXzqVVk4YPOP
|
|
|
58
59
|
secator/runners/__init__.py,sha256=EBbOk37vkBy9p8Hhrbi-2VtM_rTwQ3b-0ggTyiD22cE,290
|
|
59
60
|
secator/runners/_base.py,sha256=Or9bDSsxcwYTUeW6G7-Pmag82_yGUtREuzSZWj9IgHY,27268
|
|
60
61
|
secator/runners/_helpers.py,sha256=7UUboSsr4b6srIOOHtSSYhJ9Jxq_qaMVbbF2gVEBnR4,3703
|
|
61
|
-
secator/runners/command.py,sha256=
|
|
62
|
+
secator/runners/command.py,sha256=JzdwhbvsDujOyE-i_XgBGH-g6jaEoDNwL7CU2BIZ-Ng,18737
|
|
62
63
|
secator/runners/scan.py,sha256=FjmlL_zkraqhS3rBwy5jHnGsKt2n7Hb2gi4qhgeGenw,1727
|
|
63
64
|
secator/runners/task.py,sha256=JS8JPCW6v3_f_jbFV1-robR53epPPDj0PdxqAtXKmEs,2775
|
|
64
65
|
secator/runners/workflow.py,sha256=Mz8Q4OT48B-o-iQHgZ84WpZfwaECQOp8KRdIirg3He0,3766
|
|
@@ -69,31 +70,31 @@ secator/serializers/regex.py,sha256=hGJ_1JSOv9xPtfn_umHlsjnR_alnsDFv-UmjYCC3vwU,
|
|
|
69
70
|
secator/tasks/__init__.py,sha256=Wp2QF5QS2e_BlVygsIEFbmYPTfTg7v_Vd3LQJeXTC7I,344
|
|
70
71
|
secator/tasks/_categories.py,sha256=RuN483yhmzOPg_eR1-djR8MQe96lH4d8UVvaKvcXmiI,9069
|
|
71
72
|
secator/tasks/cariddi.py,sha256=Np9QPMpuqGtsLGHANfcbNaYjoQaqjkFXX9Dbtbtcgu4,3109
|
|
72
|
-
secator/tasks/dalfox.py,sha256=
|
|
73
|
+
secator/tasks/dalfox.py,sha256=nrLkIbTNz_J7LgUy_3kBgzhTUbQi3RmiSJhc9HWa05c,1744
|
|
73
74
|
secator/tasks/dirsearch.py,sha256=2hJeJZJwaAl3-UAjBwlmjW1w9bxjVWxxwfcaTTxqClc,2387
|
|
74
|
-
secator/tasks/dnsx.py,sha256=
|
|
75
|
-
secator/tasks/dnsxbrute.py,sha256=
|
|
76
|
-
secator/tasks/feroxbuster.py,sha256=
|
|
77
|
-
secator/tasks/ffuf.py,sha256=
|
|
75
|
+
secator/tasks/dnsx.py,sha256=H_3z87KAK-ndAQgCwS8TRWaUX_Hh54qEeuKQCS4rjBw,1771
|
|
76
|
+
secator/tasks/dnsxbrute.py,sha256=obr2SsxIJlO2KckxrCOPHvvzyfequFW6-D4ZAUq4Egk,1224
|
|
77
|
+
secator/tasks/feroxbuster.py,sha256=9QQpd8T0CSMfXf_BMmCX4LeIogyvsc_ccXFJnEocxVo,3011
|
|
78
|
+
secator/tasks/ffuf.py,sha256=ocmFfJJoV4zF8zkhUxHqUyDuJe9flmuijHCq_xk2pa4,2558
|
|
78
79
|
secator/tasks/fping.py,sha256=P2EAPUGgwEC4Geh2zUbBPKF9bdqrlrdDg-R_TYLTFng,1127
|
|
79
|
-
secator/tasks/gau.py,sha256=
|
|
80
|
+
secator/tasks/gau.py,sha256=Sq5l277cGxpT2bB5s1RqrggP804RKbC6xxgLDZZzLFs,1391
|
|
80
81
|
secator/tasks/gf.py,sha256=WlhoEyL6xE79w6nE5XNSXHs-jVeO10njqJxBF8w20sA,945
|
|
81
|
-
secator/tasks/gospider.py,sha256
|
|
82
|
-
secator/tasks/grype.py,sha256=
|
|
82
|
+
secator/tasks/gospider.py,sha256=_UlTb9G5Ss8D68NT53s0_rI6TnG00Ph0yxWyHic7cKs,2172
|
|
83
|
+
secator/tasks/grype.py,sha256=n60Zs9d1NWJFHQ0DwIZib5wu3xH-tV2RzgLYwuQSTo4,2413
|
|
83
84
|
secator/tasks/h8mail.py,sha256=hZBpfV6M1mbpD_PbDHxLI5HMvqAvTeY_W0lbkq3Hugo,2037
|
|
84
|
-
secator/tasks/httpx.py,sha256=
|
|
85
|
-
secator/tasks/katana.py,sha256=
|
|
85
|
+
secator/tasks/httpx.py,sha256=NuycnbPejEZoUdFYFXyahYiZnzhz1cPJarHdP7WyP6c,3979
|
|
86
|
+
secator/tasks/katana.py,sha256=Xa03zP2-78Ns59unUPrR_MHSd1DugTQlThxl8cL6pX4,4370
|
|
86
87
|
secator/tasks/maigret.py,sha256=PZDTICJ4LZF3joKe-dXu2alffakD_1sxBuNEUBtJDm4,2098
|
|
87
|
-
secator/tasks/mapcidr.py,sha256=
|
|
88
|
+
secator/tasks/mapcidr.py,sha256=7aa2WXQATWgIQo5oA12URjAg80L6MFMGdxScxls8DuA,980
|
|
88
89
|
secator/tasks/msfconsole.py,sha256=VlhEzsdYMHb6eJy4HBRdXMtRKhdzf5KtQGh7qZqO9Rs,6073
|
|
89
|
-
secator/tasks/naabu.py,sha256=
|
|
90
|
+
secator/tasks/naabu.py,sha256=RNs4NCZXgKhPqzR78l6l61tau0mGHuj6C3If7fimpgs,1594
|
|
90
91
|
secator/tasks/nmap.py,sha256=LS5FBo-vFxbHVK4DxF5x-O2cAvAK3zL1pROT1GddX9E,9459
|
|
91
|
-
secator/tasks/nuclei.py,sha256=
|
|
92
|
+
secator/tasks/nuclei.py,sha256=7MlTygHd4EVz81ndrVwP5y6PZ-4j-Y8Oxuk3G3ayHPI,3343
|
|
92
93
|
secator/tasks/searchsploit.py,sha256=RD2uv3GFI3Eb-DiTzJp59jyXnvAZRACq-WjDI1NgFM0,1664
|
|
93
|
-
secator/tasks/subfinder.py,sha256=
|
|
94
|
+
secator/tasks/subfinder.py,sha256=cpFyFCpVaDZ3QAjNId26ezOwntn3CA5Uk-AC2l0mo0E,1087
|
|
94
95
|
secator/tasks/wpscan.py,sha256=OgFCWEPOjOVdFreBXZDLBRc-PrFmTUv97UaXmaAS9yc,5413
|
|
95
|
-
secator-0.
|
|
96
|
-
secator-0.
|
|
97
|
-
secator-0.
|
|
98
|
-
secator-0.
|
|
99
|
-
secator-0.
|
|
96
|
+
secator-0.3.0.dist-info/METADATA,sha256=D13Fu1aoN5q5jlvpWnlvtdDAPI39Q1NHW1245e3qU18,13553
|
|
97
|
+
secator-0.3.0.dist-info/WHEEL,sha256=wpsUbWzR9la66_V7_eWTdyvs6WD26tazKT2BBEAC-EM,105
|
|
98
|
+
secator-0.3.0.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
|
|
99
|
+
secator-0.3.0.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
|
|
100
|
+
secator-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|