secator 0.10.1a12__py3-none-any.whl → 0.15.1__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 +10 -5
- secator/celery_signals.py +2 -11
- secator/cli.py +309 -69
- secator/config.py +3 -2
- 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/configs/workflows/url_params_fuzz.yaml +25 -0
- secator/configs/workflows/wordpress.yaml +4 -1
- secator/decorators.py +64 -34
- secator/definitions.py +8 -4
- secator/installer.py +84 -49
- secator/output_types/__init__.py +2 -1
- secator/output_types/certificate.py +78 -0
- secator/output_types/stat.py +3 -0
- secator/output_types/user_account.py +1 -1
- secator/report.py +2 -2
- secator/rich.py +1 -1
- secator/runners/_base.py +50 -11
- secator/runners/_helpers.py +15 -3
- secator/runners/command.py +85 -21
- secator/runners/scan.py +6 -3
- secator/runners/task.py +1 -0
- secator/runners/workflow.py +22 -4
- secator/tasks/_categories.py +25 -17
- secator/tasks/arjun.py +92 -0
- secator/tasks/bbot.py +33 -4
- secator/tasks/bup.py +4 -2
- secator/tasks/cariddi.py +17 -4
- secator/tasks/dalfox.py +4 -2
- secator/tasks/dirsearch.py +4 -2
- secator/tasks/dnsx.py +5 -2
- secator/tasks/dnsxbrute.py +4 -1
- secator/tasks/feroxbuster.py +5 -2
- secator/tasks/ffuf.py +7 -3
- secator/tasks/fping.py +4 -1
- secator/tasks/gau.py +5 -2
- secator/tasks/gf.py +4 -2
- secator/tasks/gitleaks.py +79 -0
- secator/tasks/gospider.py +5 -2
- secator/tasks/grype.py +5 -2
- secator/tasks/h8mail.py +4 -2
- secator/tasks/httpx.py +6 -3
- secator/tasks/katana.py +6 -3
- secator/tasks/maigret.py +4 -2
- secator/tasks/mapcidr.py +5 -3
- secator/tasks/msfconsole.py +8 -6
- secator/tasks/naabu.py +16 -5
- secator/tasks/nmap.py +31 -29
- secator/tasks/nuclei.py +18 -10
- secator/tasks/searchsploit.py +8 -3
- secator/tasks/subfinder.py +6 -3
- secator/tasks/testssl.py +276 -0
- secator/tasks/trivy.py +98 -0
- secator/tasks/wafw00f.py +85 -0
- secator/tasks/wpprobe.py +96 -0
- secator/tasks/wpscan.py +8 -4
- secator/template.py +61 -67
- secator/utils.py +31 -18
- secator/utils_test.py +34 -10
- {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/METADATA +11 -3
- secator-0.15.1.dist-info/RECORD +128 -0
- secator/configs/profiles/stealth.yaml +0 -7
- secator-0.10.1a12.dist-info/RECORD +0 -116
- {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/WHEEL +0 -0
- {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/entry_points.txt +0 -0
- {secator-0.10.1a12.dist-info → secator-0.15.1.dist-info}/licenses/LICENSE +0 -0
secator/tasks/cariddi.py
CHANGED
|
@@ -13,12 +13,20 @@ 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
|
|
17
|
-
|
|
16
|
+
cmd = 'cariddi'
|
|
17
|
+
tags = ['url', 'crawl']
|
|
18
|
+
input_types = [URL]
|
|
18
19
|
input_flag = OPT_PIPE_INPUT
|
|
19
20
|
output_types = [Url, Tag]
|
|
20
21
|
file_flag = OPT_PIPE_INPUT
|
|
21
22
|
json_flag = '-json'
|
|
23
|
+
opts = {
|
|
24
|
+
'info': {'is_flag': True, 'short': 'info', 'help': 'Hunt for useful informations in websites.'},
|
|
25
|
+
'secrets': {'is_flag': True, 'short': 'secrets', 'help': 'Hunt for secrets.'},
|
|
26
|
+
'errors': {'is_flag': True, 'short': 'err', 'help': 'Hunt for errors in websites.'},
|
|
27
|
+
'juicy_extensions': {'type': int, 'short': 'jext', 'help': 'Hunt for juicy file extensions. Integer from 1(juicy) to 7(not juicy)'}, # noqa: E501
|
|
28
|
+
'juicy_endpoints': {'is_flag': True, 'short': 'jep', 'help': 'Hunt for juicy endpoints.'}
|
|
29
|
+
}
|
|
22
30
|
opt_key_map = {
|
|
23
31
|
HEADER: 'headers',
|
|
24
32
|
DELAY: 'd',
|
|
@@ -38,10 +46,15 @@ class cariddi(HttpCrawler):
|
|
|
38
46
|
RETRIES: OPT_NOT_SUPPORTED,
|
|
39
47
|
THREADS: 'c',
|
|
40
48
|
TIMEOUT: 't',
|
|
41
|
-
USER_AGENT: 'ua'
|
|
49
|
+
USER_AGENT: 'ua',
|
|
50
|
+
'secrets': 's',
|
|
51
|
+
'errors': 'err',
|
|
52
|
+
'juicy_endpoints': 'e',
|
|
53
|
+
'juicy_extensions': 'ext'
|
|
42
54
|
}
|
|
43
55
|
item_loaders = [JSONSerializer()]
|
|
44
|
-
|
|
56
|
+
install_version = 'v1.3.6'
|
|
57
|
+
install_cmd = 'go install -v github.com/edoardottt/cariddi/cmd/cariddi@[install_version]'
|
|
45
58
|
install_github_handle = 'edoardottt/cariddi'
|
|
46
59
|
encoding = 'ansi'
|
|
47
60
|
proxychains = False
|
secator/tasks/dalfox.py
CHANGED
|
@@ -21,7 +21,8 @@ DALFOX_TYPE_MAP = {
|
|
|
21
21
|
class dalfox(VulnHttp):
|
|
22
22
|
"""Powerful open source XSS scanning tool."""
|
|
23
23
|
cmd = 'dalfox'
|
|
24
|
-
|
|
24
|
+
tags = ['url', 'fuzz']
|
|
25
|
+
input_types = [URL]
|
|
25
26
|
input_flag = 'url'
|
|
26
27
|
file_flag = 'file'
|
|
27
28
|
# input_chunk_size = 1
|
|
@@ -55,7 +56,8 @@ class dalfox(VulnHttp):
|
|
|
55
56
|
SEVERITY: lambda x: x['severity'].lower()
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
+
install_version = 'v2.11.0'
|
|
60
|
+
install_cmd = 'go install -v github.com/hahwul/dalfox/v2@latest'
|
|
59
61
|
install_github_handle = 'hahwul/dalfox'
|
|
60
62
|
encoding = 'ansi'
|
|
61
63
|
proxychains = False
|
secator/tasks/dirsearch.py
CHANGED
|
@@ -9,7 +9,7 @@ from secator.definitions import (CONTENT_LENGTH, CONTENT_TYPE, DELAY, DEPTH,
|
|
|
9
9
|
MATCH_CODES, MATCH_REGEX, MATCH_SIZE,
|
|
10
10
|
MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED, OUTPUT_PATH, PROXY,
|
|
11
11
|
RATE_LIMIT, RETRIES, STATUS_CODE,
|
|
12
|
-
THREADS, TIMEOUT, USER_AGENT, WORDLIST)
|
|
12
|
+
THREADS, TIMEOUT, USER_AGENT, WORDLIST, URL)
|
|
13
13
|
from secator.output_types import Url, Info, Error
|
|
14
14
|
from secator.tasks._categories import HttpFuzzer
|
|
15
15
|
|
|
@@ -18,6 +18,8 @@ from secator.tasks._categories import HttpFuzzer
|
|
|
18
18
|
class dirsearch(HttpFuzzer):
|
|
19
19
|
"""Advanced web path brute-forcer."""
|
|
20
20
|
cmd = 'dirsearch'
|
|
21
|
+
tags = ['url', 'fuzz']
|
|
22
|
+
input_types = [URL]
|
|
21
23
|
input_flag = '-u'
|
|
22
24
|
file_flag = '-l'
|
|
23
25
|
json_flag = '-O json'
|
|
@@ -52,7 +54,7 @@ class dirsearch(HttpFuzzer):
|
|
|
52
54
|
STATUS_CODE: 'status'
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
install_cmd = 'pipx install
|
|
57
|
+
install_cmd = 'pipx install git+https://github.com/maurosoria/dirsearch.git --force'
|
|
56
58
|
proxychains = True
|
|
57
59
|
proxy_socks5 = True
|
|
58
60
|
proxy_http = True
|
secator/tasks/dnsx.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from secator.decorators import task
|
|
2
|
-
from secator.definitions import (OPT_PIPE_INPUT, RATE_LIMIT, RETRIES, THREADS)
|
|
2
|
+
from secator.definitions import (HOST, OPT_PIPE_INPUT, RATE_LIMIT, RETRIES, THREADS)
|
|
3
3
|
from secator.output_types import Record, Ip, Subdomain
|
|
4
4
|
from secator.output_types.ip import IpProtocol
|
|
5
5
|
from secator.tasks._categories import ReconDns
|
|
@@ -11,8 +11,10 @@ from secator.utils import extract_domain_info
|
|
|
11
11
|
class dnsx(ReconDns):
|
|
12
12
|
"""dnsx is a fast and multi-purpose DNS toolkit designed for running various retryabledns library."""
|
|
13
13
|
cmd = 'dnsx -resp -recon'
|
|
14
|
+
tags = ['dns', 'fuzz']
|
|
14
15
|
json_flag = '-json'
|
|
15
16
|
input_flag = OPT_PIPE_INPUT
|
|
17
|
+
input_types = [HOST]
|
|
16
18
|
file_flag = OPT_PIPE_INPUT
|
|
17
19
|
output_types = [Record, Ip, Subdomain]
|
|
18
20
|
opt_key_map = {
|
|
@@ -26,7 +28,8 @@ class dnsx(ReconDns):
|
|
|
26
28
|
'wildcard_domain': {'type': str, 'short': 'wd', 'help': 'Domain name for wildcard filtering'},
|
|
27
29
|
}
|
|
28
30
|
item_loaders = [JSONSerializer()]
|
|
29
|
-
|
|
31
|
+
install_version = 'v1.2.2'
|
|
32
|
+
install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
|
|
30
33
|
install_github_handle = 'projectdiscovery/dnsx'
|
|
31
34
|
profile = 'io'
|
|
32
35
|
|
secator/tasks/dnsxbrute.py
CHANGED
|
@@ -11,8 +11,10 @@ from secator.utils import process_wordlist
|
|
|
11
11
|
class dnsxbrute(ReconDns):
|
|
12
12
|
"""dnsx is a fast and multi-purpose DNS toolkit designed for running various library."""
|
|
13
13
|
cmd = 'dnsx'
|
|
14
|
+
tags = ['dns', 'fuzz']
|
|
14
15
|
json_flag = '-json'
|
|
15
16
|
input_flag = '-domain'
|
|
17
|
+
input_types = [HOST]
|
|
16
18
|
file_flag = '-domain'
|
|
17
19
|
opt_key_map = {
|
|
18
20
|
RATE_LIMIT: 'rate-limit',
|
|
@@ -34,6 +36,7 @@ class dnsxbrute(ReconDns):
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
|
|
39
|
+
install_version = 'v1.2.2'
|
|
40
|
+
install_cmd = 'go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@[install_version]'
|
|
38
41
|
install_github_handle = 'projectdiscovery/dnsx'
|
|
39
42
|
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, URL)
|
|
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,9 @@ 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
|
+
tags = ['url', 'fuzz']
|
|
20
|
+
input_types = [URL]
|
|
19
21
|
input_flag = '--url'
|
|
20
22
|
input_chunk_size = 1
|
|
21
23
|
file_flag = OPT_PIPE_INPUT
|
|
@@ -62,6 +64,7 @@ class feroxbuster(HttpFuzzer):
|
|
|
62
64
|
install_pre = {
|
|
63
65
|
'*': ['curl', 'bash']
|
|
64
66
|
}
|
|
67
|
+
install_version = 'v2.11.0'
|
|
65
68
|
install_cmd = (
|
|
66
69
|
f'cd /tmp && curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | bash -s {CONFIG.dirs.bin}' # noqa: E501
|
|
67
70
|
)
|
secator/tasks/ffuf.py
CHANGED
|
@@ -7,7 +7,7 @@ from secator.definitions import (AUTO_CALIBRATION, CONTENT_LENGTH,
|
|
|
7
7
|
MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
|
|
8
8
|
PERCENT, PROXY, RATE_LIMIT, RETRIES,
|
|
9
9
|
STATUS_CODE, THREADS, TIME, TIMEOUT,
|
|
10
|
-
USER_AGENT, WORDLIST)
|
|
10
|
+
USER_AGENT, WORDLIST, URL)
|
|
11
11
|
from secator.output_types import Progress, Url
|
|
12
12
|
from secator.serializers import JSONSerializer, RegexSerializer
|
|
13
13
|
from secator.tasks._categories import HttpFuzzer
|
|
@@ -18,7 +18,9 @@ FFUF_PROGRESS_REGEX = r':: Progress: \[(?P<count>\d+)/(?P<total>\d+)\] :: Job \[
|
|
|
18
18
|
@task()
|
|
19
19
|
class ffuf(HttpFuzzer):
|
|
20
20
|
"""Fast web fuzzer written in Go."""
|
|
21
|
-
cmd = 'ffuf -noninteractive
|
|
21
|
+
cmd = 'ffuf -noninteractive'
|
|
22
|
+
tags = ['url', 'fuzz']
|
|
23
|
+
input_types = [URL]
|
|
22
24
|
input_flag = '-u'
|
|
23
25
|
input_chunk_size = 1
|
|
24
26
|
file_flag = None
|
|
@@ -30,6 +32,7 @@ class ffuf(HttpFuzzer):
|
|
|
30
32
|
]
|
|
31
33
|
opts = {
|
|
32
34
|
AUTO_CALIBRATION: {'is_flag': True, 'short': 'ac', 'help': 'Auto-calibration'},
|
|
35
|
+
'recursion': {'is_flag': True, 'default': True, 'short': 'recursion', 'help': 'Recursion'},
|
|
33
36
|
}
|
|
34
37
|
opt_key_map = {
|
|
35
38
|
HEADER: 'H',
|
|
@@ -70,7 +73,8 @@ class ffuf(HttpFuzzer):
|
|
|
70
73
|
},
|
|
71
74
|
}
|
|
72
75
|
encoding = 'ansi'
|
|
73
|
-
|
|
76
|
+
install_version = 'v2.1.0'
|
|
77
|
+
install_cmd = 'go install -v github.com/ffuf/ffuf/v2@[install_version]'
|
|
74
78
|
install_github_handle = 'ffuf/ffuf'
|
|
75
79
|
proxychains = False
|
|
76
80
|
proxy_socks5 = True
|
secator/tasks/fping.py
CHANGED
|
@@ -11,8 +11,10 @@ from secator.tasks._categories import ReconIp
|
|
|
11
11
|
class fping(ReconIp):
|
|
12
12
|
"""Send ICMP echo probes to network hosts, similar to ping, but much better."""
|
|
13
13
|
cmd = 'fping -a'
|
|
14
|
+
tags = ['ip', 'recon']
|
|
14
15
|
file_flag = '-f'
|
|
15
16
|
input_flag = None
|
|
17
|
+
input_types = [IP]
|
|
16
18
|
opt_prefix = '--'
|
|
17
19
|
opt_key_map = {
|
|
18
20
|
DELAY: 'period',
|
|
@@ -26,9 +28,10 @@ class fping(ReconIp):
|
|
|
26
28
|
DELAY: lambda x: x * 1000, # convert s to ms
|
|
27
29
|
TIMEOUT: lambda x: x * 1000 # convert s to ms
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
input_types = [IP]
|
|
30
32
|
output_types = [Ip]
|
|
31
33
|
install_pre = {'*': ['fping']}
|
|
34
|
+
ignore_return_code = True
|
|
32
35
|
|
|
33
36
|
@staticmethod
|
|
34
37
|
def item_loader(self, line):
|
secator/tasks/gau.py
CHANGED
|
@@ -4,7 +4,7 @@ from secator.definitions import (DELAY, DEPTH, FILTER_CODES, FILTER_REGEX,
|
|
|
4
4
|
HEADER, MATCH_CODES, MATCH_REGEX, MATCH_SIZE,
|
|
5
5
|
MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
|
|
6
6
|
OPT_PIPE_INPUT, PROXY, RATE_LIMIT, RETRIES,
|
|
7
|
-
THREADS, TIMEOUT, USER_AGENT)
|
|
7
|
+
THREADS, TIMEOUT, USER_AGENT, URL)
|
|
8
8
|
from secator.serializers import JSONSerializer
|
|
9
9
|
from secator.tasks._categories import HttpCrawler
|
|
10
10
|
|
|
@@ -13,6 +13,8 @@ from secator.tasks._categories import HttpCrawler
|
|
|
13
13
|
class gau(HttpCrawler):
|
|
14
14
|
"""Fetch known URLs from AlienVault's Open Threat Exchange, the Wayback Machine, Common Crawl, and URLScan."""
|
|
15
15
|
cmd = 'gau'
|
|
16
|
+
tags = ['pattern', 'scan']
|
|
17
|
+
input_types = [URL]
|
|
16
18
|
file_flag = OPT_PIPE_INPUT
|
|
17
19
|
json_flag = '--json'
|
|
18
20
|
opt_prefix = '--'
|
|
@@ -44,7 +46,8 @@ class gau(HttpCrawler):
|
|
|
44
46
|
install_pre = {
|
|
45
47
|
'apk': ['libc6-compat']
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
install_version = 'v2.2.4'
|
|
50
|
+
install_cmd = 'go install -v github.com/lc/gau/v2/cmd/gau@[install_version]'
|
|
48
51
|
install_github_handle = 'lc/gau'
|
|
49
52
|
proxychains = False
|
|
50
53
|
proxy_socks5 = True
|
secator/tasks/gf.py
CHANGED
|
@@ -8,6 +8,7 @@ from secator.tasks._categories import Tagger
|
|
|
8
8
|
class gf(Tagger):
|
|
9
9
|
"""Wrapper around grep, to help you grep for things."""
|
|
10
10
|
cmd = 'gf'
|
|
11
|
+
tags = ['pattern', 'scan']
|
|
11
12
|
file_flag = OPT_PIPE_INPUT
|
|
12
13
|
input_flag = OPT_PIPE_INPUT
|
|
13
14
|
version_flag = OPT_NOT_SUPPORTED
|
|
@@ -17,7 +18,7 @@ class gf(Tagger):
|
|
|
17
18
|
opt_key_map = {
|
|
18
19
|
'pattern': ''
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
input_types = [URL]
|
|
21
22
|
install_cmd = (
|
|
22
23
|
'go install -v github.com/tomnomnom/gf@latest && '
|
|
23
24
|
'git clone https://github.com/1ndianl33t/Gf-Patterns $HOME/.gf || true'
|
|
@@ -30,5 +31,6 @@ class gf(Tagger):
|
|
|
30
31
|
|
|
31
32
|
@staticmethod
|
|
32
33
|
def on_item(self, item):
|
|
33
|
-
item
|
|
34
|
+
if isinstance(item, Tag):
|
|
35
|
+
item.extra_data = {'source': 'url'}
|
|
34
36
|
return item
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import os
|
|
3
|
+
import yaml
|
|
4
|
+
|
|
5
|
+
from secator.config import CONFIG
|
|
6
|
+
from secator.decorators import task
|
|
7
|
+
from secator.runners import Command
|
|
8
|
+
from secator.definitions import (OUTPUT_PATH, PATH, GIT_REPOSITORY)
|
|
9
|
+
from secator.utils import caml_to_snake
|
|
10
|
+
from secator.output_types import Tag, Info, Error
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@task()
|
|
14
|
+
class gitleaks(Command):
|
|
15
|
+
"""Tool for detecting secrets like passwords, API keys, and tokens in git repos, files, and stdin."""
|
|
16
|
+
cmd = 'gitleaks'
|
|
17
|
+
tags = ['secret', 'scan']
|
|
18
|
+
input_types = [PATH, GIT_REPOSITORY]
|
|
19
|
+
input_flag = None
|
|
20
|
+
json_flag = '-f json'
|
|
21
|
+
opt_prefix = '--'
|
|
22
|
+
opts = {
|
|
23
|
+
'ignore_path': {'type': str, 'help': 'Path to .gitleaksignore file or folder containing one'},
|
|
24
|
+
'mode': {'type': click.Choice(['git', 'dir']), 'default': 'dir', 'help': 'Gitleaks mode', 'internal': True, 'display': True}, # noqa: E501
|
|
25
|
+
'config': {'type': str, 'short': 'config', 'help': 'Gitleaks config file path'}
|
|
26
|
+
}
|
|
27
|
+
opt_key_map = {
|
|
28
|
+
"ignore_path": "gitleaks-ignore-path"
|
|
29
|
+
}
|
|
30
|
+
input_type = "folder"
|
|
31
|
+
output_types = [Tag]
|
|
32
|
+
output_map = {
|
|
33
|
+
Tag: {
|
|
34
|
+
'name': 'RuleID',
|
|
35
|
+
'match': lambda x: f'{x["File"]}:{x["StartLine"]}:{x["StartColumn"]}',
|
|
36
|
+
'extra_data': lambda x: {caml_to_snake(k): v for k, v in x.items() if k not in ['RuleID', 'File']}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
install_pre = {'*': ['git', 'make']}
|
|
40
|
+
install_version = 'v8.24.3'
|
|
41
|
+
install_cmd = (
|
|
42
|
+
f'git clone https://github.com/gitleaks/gitleaks.git {CONFIG.dirs.share}/gitleaks_[install_version] || true &&'
|
|
43
|
+
f'cd {CONFIG.dirs.share}/gitleaks_[install_version] && make build &&'
|
|
44
|
+
f'mv {CONFIG.dirs.share}/gitleaks_[install_version]/gitleaks {CONFIG.dirs.bin}'
|
|
45
|
+
)
|
|
46
|
+
install_github_handle = 'gitleaks/gitleaks'
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def on_cmd(self):
|
|
50
|
+
# replace fake -mode opt by subcommand
|
|
51
|
+
mode = self.get_opt_value('mode')
|
|
52
|
+
self.cmd = self.cmd.replace(f'{gitleaks.cmd} ', f'{gitleaks.cmd} {mode} ')
|
|
53
|
+
|
|
54
|
+
# add output path
|
|
55
|
+
output_path = self.get_opt_value(OUTPUT_PATH)
|
|
56
|
+
if not output_path:
|
|
57
|
+
output_path = f'{self.reports_folder}/.outputs/{self.unique_name}.json'
|
|
58
|
+
self.output_path = output_path
|
|
59
|
+
self.cmd += f' -r {self.output_path}'
|
|
60
|
+
self.cmd += ' --exit-code 0'
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def on_cmd_done(self):
|
|
64
|
+
if not os.path.exists(self.output_path):
|
|
65
|
+
yield Error(message=f'Could not find JSON results in {self.output_path}')
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
yield Info(message=f'JSON results saved to {self.output_path}')
|
|
69
|
+
with open(self.output_path, 'r') as f:
|
|
70
|
+
results = yaml.safe_load(f.read())
|
|
71
|
+
for result in results:
|
|
72
|
+
yield Tag(
|
|
73
|
+
name=result['RuleID'],
|
|
74
|
+
match='{File}:{StartLine}:{StartColumn}'.format(**result),
|
|
75
|
+
extra_data={
|
|
76
|
+
caml_to_snake(k): v for k, v in result.items()
|
|
77
|
+
if k not in ['RuleID', 'File']
|
|
78
|
+
}
|
|
79
|
+
)
|
secator/tasks/gospider.py
CHANGED
|
@@ -15,9 +15,11 @@ 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
|
+
tags = ['url', 'crawl']
|
|
19
20
|
file_flag = '-S'
|
|
20
21
|
input_flag = '-s'
|
|
22
|
+
input_types = [URL]
|
|
21
23
|
json_flag = '--json'
|
|
22
24
|
opt_prefix = '--'
|
|
23
25
|
opt_key_map = {
|
|
@@ -53,7 +55,8 @@ class gospider(HttpCrawler):
|
|
|
53
55
|
CONTENT_LENGTH: 'length',
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
|
-
|
|
58
|
+
install_version = 'v1.1.6'
|
|
59
|
+
install_cmd = 'go install -v github.com/jaeles-project/gospider@[install_version]'
|
|
57
60
|
install_github_handle = 'jaeles-project/gospider'
|
|
58
61
|
proxychains = False
|
|
59
62
|
proxy_socks5 = True # with leaks... https://github.com/jaeles-project/gospider/issues/61
|
secator/tasks/grype.py
CHANGED
|
@@ -2,7 +2,7 @@ from secator.config import CONFIG
|
|
|
2
2
|
from secator.decorators import task
|
|
3
3
|
from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER,
|
|
4
4
|
OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT, RETRIES,
|
|
5
|
-
THREADS, TIMEOUT, USER_AGENT)
|
|
5
|
+
THREADS, TIMEOUT, USER_AGENT, PATH, DOCKER_IMAGE)
|
|
6
6
|
from secator.output_types import Vulnerability
|
|
7
7
|
from secator.tasks._categories import VulnCode
|
|
8
8
|
|
|
@@ -11,6 +11,8 @@ from secator.tasks._categories import VulnCode
|
|
|
11
11
|
class grype(VulnCode):
|
|
12
12
|
"""Vulnerability scanner for container images and filesystems."""
|
|
13
13
|
cmd = 'grype --quiet'
|
|
14
|
+
tags = ['vuln', 'scan']
|
|
15
|
+
input_types = [PATH, DOCKER_IMAGE]
|
|
14
16
|
input_flag = ''
|
|
15
17
|
file_flag = OPT_NOT_SUPPORTED
|
|
16
18
|
json_flag = None
|
|
@@ -30,6 +32,7 @@ class grype(VulnCode):
|
|
|
30
32
|
install_pre = {
|
|
31
33
|
'*': ['curl']
|
|
32
34
|
}
|
|
35
|
+
install_version = 'v0.91.2'
|
|
33
36
|
install_cmd = (
|
|
34
37
|
f'curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b {CONFIG.dirs.bin}'
|
|
35
38
|
)
|
|
@@ -66,7 +69,7 @@ class grype(VulnCode):
|
|
|
66
69
|
if vuln_id.startswith('GHSA'):
|
|
67
70
|
data['provider'] = 'github.com'
|
|
68
71
|
data['references'] = [f'https://github.com/advisories/{vuln_id}']
|
|
69
|
-
vuln = VulnCode.
|
|
72
|
+
vuln = VulnCode.lookup_cve_from_ghsa(vuln_id)
|
|
70
73
|
if vuln:
|
|
71
74
|
data.update(vuln)
|
|
72
75
|
data['severity'] = data['severity'] or severity.lower()
|
secator/tasks/h8mail.py
CHANGED
|
@@ -11,9 +11,10 @@ from secator.output_types import UserAccount, Info, Error
|
|
|
11
11
|
class h8mail(OSInt):
|
|
12
12
|
"""Email information and password lookup tool."""
|
|
13
13
|
cmd = 'h8mail'
|
|
14
|
+
tags = ['user', 'recon', 'email']
|
|
14
15
|
json_flag = '--json '
|
|
15
16
|
input_flag = '--targets'
|
|
16
|
-
|
|
17
|
+
input_types = [EMAIL]
|
|
17
18
|
file_flag = '-domain'
|
|
18
19
|
version_flag = '--help'
|
|
19
20
|
opt_prefix = '--'
|
|
@@ -21,7 +22,8 @@ class h8mail(OSInt):
|
|
|
21
22
|
'config': {'type': str, 'help': 'Configuration file for API keys'},
|
|
22
23
|
'local_breach': {'type': str, 'short': 'lb', 'help': 'Local breach file'}
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
install_version = '2.5.6'
|
|
26
|
+
install_cmd = 'pipx install h8mail==[install_version] --force'
|
|
25
27
|
|
|
26
28
|
@staticmethod
|
|
27
29
|
def on_start(self):
|
secator/tasks/httpx.py
CHANGED
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
from secator.decorators import task
|
|
4
4
|
from secator.definitions import (DELAY, DEPTH, FILTER_CODES, FILTER_REGEX, FILTER_SIZE, FILTER_WORDS, FOLLOW_REDIRECT,
|
|
5
5
|
HEADER, MATCH_CODES, MATCH_REGEX, MATCH_SIZE, MATCH_WORDS, METHOD, OPT_NOT_SUPPORTED,
|
|
6
|
-
PROXY, RATE_LIMIT, RETRIES, THREADS, TIMEOUT, URL, USER_AGENT)
|
|
6
|
+
PROXY, RATE_LIMIT, RETRIES, THREADS, TIMEOUT, URL, USER_AGENT, HOST, IP)
|
|
7
7
|
from secator.config import CONFIG
|
|
8
8
|
from secator.output_types import Url, Subdomain
|
|
9
9
|
from secator.serializers import JSONSerializer
|
|
@@ -15,8 +15,10 @@ from secator.utils import (sanitize_url, extract_domain_info, extract_subdomains
|
|
|
15
15
|
class httpx(Http):
|
|
16
16
|
"""Fast and multi-purpose HTTP toolkit."""
|
|
17
17
|
cmd = 'httpx'
|
|
18
|
+
tags = ['url', 'probe']
|
|
18
19
|
file_flag = '-l'
|
|
19
20
|
input_flag = '-u'
|
|
21
|
+
input_types = [HOST, IP, URL]
|
|
20
22
|
json_flag = '-json'
|
|
21
23
|
opts = {
|
|
22
24
|
# 'silent': {'is_flag': True, 'default': False, 'help': 'Silent mode'},
|
|
@@ -33,7 +35,7 @@ class httpx(Http):
|
|
|
33
35
|
'system_chrome': {'is_flag': True, 'default': False, 'help': 'Use local installed Chrome for screenshot'},
|
|
34
36
|
'headless_options': {'is_flag': False, 'short': 'ho', 'default': None, 'help': 'Headless Chrome additional options'},
|
|
35
37
|
'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':
|
|
38
|
+
'tech_detect': {'is_flag': True, 'short': 'td', 'default': False, 'help': 'Tech detection'},
|
|
37
39
|
'tls_grab': {'is_flag': True, 'short': 'tlsg', 'default': False, 'help': 'Grab some informations from the tls certificate'}, # noqa: E501
|
|
38
40
|
'rstr': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to read (bytes)'},
|
|
39
41
|
'rsts': {'type': int, 'default': CONFIG.http.response_max_size_bytes, 'help': 'Max body size to save (bytes)'}
|
|
@@ -68,7 +70,8 @@ class httpx(Http):
|
|
|
68
70
|
install_pre = {
|
|
69
71
|
'apk': ['chromium']
|
|
70
72
|
}
|
|
71
|
-
|
|
73
|
+
install_version = 'v1.7.0'
|
|
74
|
+
install_cmd = 'go install -v github.com/projectdiscovery/httpx/cmd/httpx@[install_version]'
|
|
72
75
|
install_github_handle = 'projectdiscovery/httpx'
|
|
73
76
|
proxychains = False
|
|
74
77
|
proxy_socks5 = True
|
secator/tasks/katana.py
CHANGED
|
@@ -17,8 +17,10 @@ from secator.tasks._categories import HttpCrawler
|
|
|
17
17
|
class katana(HttpCrawler):
|
|
18
18
|
"""Next-generation crawling and spidering framework."""
|
|
19
19
|
cmd = 'katana'
|
|
20
|
+
tags = ['url', 'crawl']
|
|
20
21
|
file_flag = '-list'
|
|
21
22
|
input_flag = '-u'
|
|
23
|
+
input_types = [URL]
|
|
22
24
|
json_flag = '-jsonl'
|
|
23
25
|
opts = {
|
|
24
26
|
'headless': {'is_flag': True, 'short': 'hl', 'help': 'Headless mode'},
|
|
@@ -26,8 +28,8 @@ class katana(HttpCrawler):
|
|
|
26
28
|
'form_extraction': {'is_flag': True, 'short': 'fx', 'help': 'Detect forms'},
|
|
27
29
|
'store_responses': {'is_flag': True, 'short': 'sr', 'default': CONFIG.http.store_responses, 'help': 'Store responses'}, # noqa: E501
|
|
28
30
|
'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':
|
|
31
|
+
'js_crawl': {'is_flag': True, 'short': 'jc', 'default': False, 'help': 'Enable endpoint parsing / crawling in javascript file'}, # noqa: E501
|
|
32
|
+
'jsluice': {'is_flag': True, 'short': 'jsl', 'default': False, 'help': 'Enable jsluice parsing in javascript file (memory intensive)'}, # noqa: E501
|
|
31
33
|
'known_files': {'type': str, 'short': 'kf', 'default': 'all', 'help': 'Enable crawling of known files (all, robotstxt, sitemapxml)'}, # noqa: E501
|
|
32
34
|
'omit_raw': {'is_flag': True, 'short': 'or', 'default': True, 'help': 'Omit raw requests/responses from jsonl output'}, # noqa: E501
|
|
33
35
|
'omit_body': {'is_flag': True, 'short': 'ob', 'default': True, 'help': 'Omit response body from jsonl output'},
|
|
@@ -78,7 +80,8 @@ class katana(HttpCrawler):
|
|
|
78
80
|
install_pre = {
|
|
79
81
|
'apk': ['libc6-compat']
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
install_version = 'v1.1.3'
|
|
84
|
+
install_cmd = 'go install -v github.com/projectdiscovery/katana/cmd/katana@[install_version]'
|
|
82
85
|
install_github_handle = 'projectdiscovery/katana'
|
|
83
86
|
proxychains = False
|
|
84
87
|
proxy_socks5 = True
|
secator/tasks/maigret.py
CHANGED
|
@@ -17,8 +17,10 @@ logger = logging.getLogger(__name__)
|
|
|
17
17
|
class maigret(ReconUser):
|
|
18
18
|
"""Collect a dossier on a person by username."""
|
|
19
19
|
cmd = 'maigret'
|
|
20
|
+
tags = ['user', 'recon', 'username']
|
|
20
21
|
file_flag = None
|
|
21
22
|
input_flag = None
|
|
23
|
+
input_types = [USERNAME]
|
|
22
24
|
json_flag = '--json ndjson'
|
|
23
25
|
opt_prefix = '--'
|
|
24
26
|
opts = {
|
|
@@ -32,7 +34,7 @@ class maigret(ReconUser):
|
|
|
32
34
|
TIMEOUT: 'timeout',
|
|
33
35
|
THREADS: OPT_NOT_SUPPORTED
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
input_types = [USERNAME]
|
|
36
38
|
output_types = [UserAccount]
|
|
37
39
|
output_map = {
|
|
38
40
|
UserAccount: {
|
|
@@ -41,7 +43,7 @@ class maigret(ReconUser):
|
|
|
41
43
|
EXTRA_DATA: lambda x: x['status'].get('ids', {})
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
|
-
install_cmd = 'pipx install git+https://github.com/soxoj/maigret'
|
|
46
|
+
install_cmd = 'pipx install git+https://github.com/soxoj/maigret --force'
|
|
45
47
|
socks5_proxy = True
|
|
46
48
|
profile = 'io'
|
|
47
49
|
|
secator/tasks/mapcidr.py
CHANGED
|
@@ -10,15 +10,17 @@ from secator.tasks._categories import ReconIp
|
|
|
10
10
|
@task()
|
|
11
11
|
class mapcidr(ReconIp):
|
|
12
12
|
"""Utility program to perform multiple operations for a given subnet/cidr ranges."""
|
|
13
|
-
cmd = 'mapcidr
|
|
13
|
+
cmd = 'mapcidr'
|
|
14
|
+
tags = ['ip', 'recon']
|
|
14
15
|
input_flag = '-cidr'
|
|
15
16
|
file_flag = '-cl'
|
|
16
17
|
install_pre = {
|
|
17
18
|
'apk': ['libc6-compat']
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
install_version = 'v1.1.34'
|
|
21
|
+
install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@[install_version]'
|
|
20
22
|
install_github_handle = 'projectdiscovery/mapcidr'
|
|
21
|
-
|
|
23
|
+
input_types = [CIDR_RANGE]
|
|
22
24
|
output_types = [Ip]
|
|
23
25
|
opt_key_map = {
|
|
24
26
|
THREADS: OPT_NOT_SUPPORTED,
|
secator/tasks/msfconsole.py
CHANGED
|
@@ -6,8 +6,8 @@ from rich.panel import Panel
|
|
|
6
6
|
|
|
7
7
|
from secator.config import CONFIG
|
|
8
8
|
from secator.decorators import task
|
|
9
|
-
from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER, HOST, OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT,
|
|
10
|
-
THREADS, TIMEOUT, USER_AGENT)
|
|
9
|
+
from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER, HOST, IP, OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT,
|
|
10
|
+
RETRIES, THREADS, TIMEOUT, USER_AGENT, URL)
|
|
11
11
|
from secator.tasks._categories import VulnMulti
|
|
12
12
|
from secator.utils import get_file_timestamp
|
|
13
13
|
|
|
@@ -18,8 +18,9 @@ logger = logging.getLogger(__name__)
|
|
|
18
18
|
class msfconsole(VulnMulti):
|
|
19
19
|
"""CLI to access and work with the Metasploit Framework."""
|
|
20
20
|
cmd = 'msfconsole --quiet'
|
|
21
|
+
tags = ['exploit', 'attack']
|
|
21
22
|
version_flag = OPT_NOT_SUPPORTED
|
|
22
|
-
|
|
23
|
+
input_types = [HOST, IP, URL]
|
|
23
24
|
input_chunk_size = 1
|
|
24
25
|
output_types = []
|
|
25
26
|
opt_prefix = '--'
|
|
@@ -48,14 +49,15 @@ class msfconsole(VulnMulti):
|
|
|
48
49
|
'pacman': ['ruby-erb', 'postgresql-libs', 'make'],
|
|
49
50
|
'yum|zypper': ['postgresql-devel', 'make'],
|
|
50
51
|
}
|
|
52
|
+
install_version = '6.4.59'
|
|
51
53
|
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-
|
|
54
|
+
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
|
|
55
|
+
f'cd {CONFIG.dirs.share}/metasploit-framework_[install_version] && '
|
|
54
56
|
f'gem install bundler --user-install -n {CONFIG.dirs.bin} && '
|
|
55
57
|
f'bundle config set --local path "{CONFIG.dirs.share}" && '
|
|
56
58
|
'bundle lock --normalize-platforms &&'
|
|
57
59
|
'bundle install && '
|
|
58
|
-
f'ln -sf $HOME/.local/share/metasploit-
|
|
60
|
+
f'ln -sf $HOME/.local/share/metasploit-framework_[install_version]/msfconsole {CONFIG.dirs.bin}/msfconsole'
|
|
59
61
|
)
|
|
60
62
|
|
|
61
63
|
@staticmethod
|