secator 0.22.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. secator/.gitignore +162 -0
  2. secator/__init__.py +0 -0
  3. secator/celery.py +453 -0
  4. secator/celery_signals.py +138 -0
  5. secator/celery_utils.py +320 -0
  6. secator/cli.py +2035 -0
  7. secator/cli_helper.py +395 -0
  8. secator/click.py +87 -0
  9. secator/config.py +670 -0
  10. secator/configs/__init__.py +0 -0
  11. secator/configs/profiles/__init__.py +0 -0
  12. secator/configs/profiles/aggressive.yaml +8 -0
  13. secator/configs/profiles/all_ports.yaml +7 -0
  14. secator/configs/profiles/full.yaml +31 -0
  15. secator/configs/profiles/http_headless.yaml +7 -0
  16. secator/configs/profiles/http_record.yaml +8 -0
  17. secator/configs/profiles/insane.yaml +8 -0
  18. secator/configs/profiles/paranoid.yaml +8 -0
  19. secator/configs/profiles/passive.yaml +11 -0
  20. secator/configs/profiles/polite.yaml +8 -0
  21. secator/configs/profiles/sneaky.yaml +8 -0
  22. secator/configs/profiles/tor.yaml +5 -0
  23. secator/configs/scans/__init__.py +0 -0
  24. secator/configs/scans/domain.yaml +31 -0
  25. secator/configs/scans/host.yaml +23 -0
  26. secator/configs/scans/network.yaml +30 -0
  27. secator/configs/scans/subdomain.yaml +27 -0
  28. secator/configs/scans/url.yaml +19 -0
  29. secator/configs/workflows/__init__.py +0 -0
  30. secator/configs/workflows/cidr_recon.yaml +48 -0
  31. secator/configs/workflows/code_scan.yaml +29 -0
  32. secator/configs/workflows/domain_recon.yaml +46 -0
  33. secator/configs/workflows/host_recon.yaml +95 -0
  34. secator/configs/workflows/subdomain_recon.yaml +120 -0
  35. secator/configs/workflows/url_bypass.yaml +15 -0
  36. secator/configs/workflows/url_crawl.yaml +98 -0
  37. secator/configs/workflows/url_dirsearch.yaml +62 -0
  38. secator/configs/workflows/url_fuzz.yaml +68 -0
  39. secator/configs/workflows/url_params_fuzz.yaml +66 -0
  40. secator/configs/workflows/url_secrets_hunt.yaml +23 -0
  41. secator/configs/workflows/url_vuln.yaml +91 -0
  42. secator/configs/workflows/user_hunt.yaml +29 -0
  43. secator/configs/workflows/wordpress.yaml +38 -0
  44. secator/cve.py +718 -0
  45. secator/decorators.py +7 -0
  46. secator/definitions.py +168 -0
  47. secator/exporters/__init__.py +14 -0
  48. secator/exporters/_base.py +3 -0
  49. secator/exporters/console.py +10 -0
  50. secator/exporters/csv.py +37 -0
  51. secator/exporters/gdrive.py +123 -0
  52. secator/exporters/json.py +16 -0
  53. secator/exporters/table.py +36 -0
  54. secator/exporters/txt.py +28 -0
  55. secator/hooks/__init__.py +0 -0
  56. secator/hooks/gcs.py +80 -0
  57. secator/hooks/mongodb.py +281 -0
  58. secator/installer.py +694 -0
  59. secator/loader.py +128 -0
  60. secator/output_types/__init__.py +49 -0
  61. secator/output_types/_base.py +108 -0
  62. secator/output_types/certificate.py +78 -0
  63. secator/output_types/domain.py +50 -0
  64. secator/output_types/error.py +42 -0
  65. secator/output_types/exploit.py +58 -0
  66. secator/output_types/info.py +24 -0
  67. secator/output_types/ip.py +47 -0
  68. secator/output_types/port.py +55 -0
  69. secator/output_types/progress.py +36 -0
  70. secator/output_types/record.py +36 -0
  71. secator/output_types/stat.py +41 -0
  72. secator/output_types/state.py +29 -0
  73. secator/output_types/subdomain.py +45 -0
  74. secator/output_types/tag.py +69 -0
  75. secator/output_types/target.py +38 -0
  76. secator/output_types/url.py +112 -0
  77. secator/output_types/user_account.py +41 -0
  78. secator/output_types/vulnerability.py +101 -0
  79. secator/output_types/warning.py +30 -0
  80. secator/report.py +140 -0
  81. secator/rich.py +130 -0
  82. secator/runners/__init__.py +14 -0
  83. secator/runners/_base.py +1240 -0
  84. secator/runners/_helpers.py +218 -0
  85. secator/runners/celery.py +18 -0
  86. secator/runners/command.py +1178 -0
  87. secator/runners/python.py +126 -0
  88. secator/runners/scan.py +87 -0
  89. secator/runners/task.py +81 -0
  90. secator/runners/workflow.py +168 -0
  91. secator/scans/__init__.py +29 -0
  92. secator/serializers/__init__.py +8 -0
  93. secator/serializers/dataclass.py +39 -0
  94. secator/serializers/json.py +45 -0
  95. secator/serializers/regex.py +25 -0
  96. secator/tasks/__init__.py +8 -0
  97. secator/tasks/_categories.py +487 -0
  98. secator/tasks/arjun.py +113 -0
  99. secator/tasks/arp.py +53 -0
  100. secator/tasks/arpscan.py +70 -0
  101. secator/tasks/bbot.py +372 -0
  102. secator/tasks/bup.py +118 -0
  103. secator/tasks/cariddi.py +193 -0
  104. secator/tasks/dalfox.py +87 -0
  105. secator/tasks/dirsearch.py +84 -0
  106. secator/tasks/dnsx.py +186 -0
  107. secator/tasks/feroxbuster.py +93 -0
  108. secator/tasks/ffuf.py +135 -0
  109. secator/tasks/fping.py +85 -0
  110. secator/tasks/gau.py +102 -0
  111. secator/tasks/getasn.py +60 -0
  112. secator/tasks/gf.py +36 -0
  113. secator/tasks/gitleaks.py +96 -0
  114. secator/tasks/gospider.py +84 -0
  115. secator/tasks/grype.py +109 -0
  116. secator/tasks/h8mail.py +75 -0
  117. secator/tasks/httpx.py +167 -0
  118. secator/tasks/jswhois.py +36 -0
  119. secator/tasks/katana.py +203 -0
  120. secator/tasks/maigret.py +87 -0
  121. secator/tasks/mapcidr.py +42 -0
  122. secator/tasks/msfconsole.py +179 -0
  123. secator/tasks/naabu.py +85 -0
  124. secator/tasks/nmap.py +487 -0
  125. secator/tasks/nuclei.py +151 -0
  126. secator/tasks/search_vulns.py +225 -0
  127. secator/tasks/searchsploit.py +109 -0
  128. secator/tasks/sshaudit.py +299 -0
  129. secator/tasks/subfinder.py +48 -0
  130. secator/tasks/testssl.py +283 -0
  131. secator/tasks/trivy.py +130 -0
  132. secator/tasks/trufflehog.py +240 -0
  133. secator/tasks/urlfinder.py +100 -0
  134. secator/tasks/wafw00f.py +106 -0
  135. secator/tasks/whois.py +34 -0
  136. secator/tasks/wpprobe.py +116 -0
  137. secator/tasks/wpscan.py +202 -0
  138. secator/tasks/x8.py +94 -0
  139. secator/tasks/xurlfind3r.py +83 -0
  140. secator/template.py +294 -0
  141. secator/thread.py +24 -0
  142. secator/tree.py +196 -0
  143. secator/utils.py +922 -0
  144. secator/utils_test.py +297 -0
  145. secator/workflows/__init__.py +29 -0
  146. secator-0.22.0.dist-info/METADATA +447 -0
  147. secator-0.22.0.dist-info/RECORD +150 -0
  148. secator-0.22.0.dist-info/WHEEL +4 -0
  149. secator-0.22.0.dist-info/entry_points.txt +2 -0
  150. secator-0.22.0.dist-info/licenses/LICENSE +60 -0
@@ -0,0 +1,42 @@
1
+ import validators
2
+
3
+ from secator.decorators import task
4
+ from secator.definitions import (CIDR_RANGE, IP, OPT_NOT_SUPPORTED, PROXY,
5
+ RATE_LIMIT, RETRIES, THREADS, TIMEOUT, SLUG)
6
+ from secator.output_types import Ip
7
+ from secator.tasks._categories import ReconIp
8
+
9
+
10
+ @task()
11
+ class mapcidr(ReconIp):
12
+ """Utility program to perform multiple operations for a given subnet/cidr ranges."""
13
+ cmd = 'mapcidr'
14
+ input_types = [CIDR_RANGE, IP, SLUG]
15
+ output_types = [Ip]
16
+ tags = ['ip', 'recon']
17
+ input_flag = '-cidr'
18
+ file_flag = '-cl'
19
+ install_version = 'v1.1.34'
20
+ install_pre = {'apk': ['libc6-compat']}
21
+ install_cmd = 'go install -v github.com/projectdiscovery/mapcidr/cmd/mapcidr@[install_version]'
22
+ github_handle = 'projectdiscovery/mapcidr'
23
+ opts = {
24
+ 'hide_ips': {'is_flag': True, 'short': 'hi', 'default': False, 'help': 'Hide IP addresses from output (too verbose)', 'internal': True, 'display': True}, # noqa: E501
25
+ }
26
+ opt_key_map = {
27
+ THREADS: OPT_NOT_SUPPORTED,
28
+ PROXY: OPT_NOT_SUPPORTED,
29
+ RATE_LIMIT: OPT_NOT_SUPPORTED,
30
+ RETRIES: OPT_NOT_SUPPORTED,
31
+ TIMEOUT: OPT_NOT_SUPPORTED,
32
+ }
33
+
34
+ @staticmethod
35
+ def on_line(self, line):
36
+ if validators.ipv4(line) or validators.ipv6(line):
37
+ ip = Ip(ip=line, alive=False)
38
+ if self.get_opt_value('hide_ips'):
39
+ self.add_result(ip, print=False)
40
+ return
41
+ return ip
42
+ return line
@@ -0,0 +1,179 @@
1
+ """Attack tasks."""
2
+
3
+ import logging
4
+
5
+ from rich.panel import Panel
6
+
7
+ from secator.config import CONFIG
8
+ from secator.decorators import task
9
+ from secator.definitions import (DELAY, FOLLOW_REDIRECT, HEADER, HOST, OPT_NOT_SUPPORTED, PROXY, RATE_LIMIT,
10
+ RETRIES, THREADS, TIMEOUT, USER_AGENT)
11
+ from secator.tasks._categories import VulnMulti
12
+ from secator.utils import get_file_timestamp
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @task()
18
+ class msfconsole(VulnMulti):
19
+ """CLI to access and work with the Metasploit Framework."""
20
+ cmd = 'msfconsole --quiet'
21
+ input_types = [HOST]
22
+ output_types = []
23
+ tags = ['exploit', 'attack']
24
+ version_flag = OPT_NOT_SUPPORTED
25
+ input_chunk_size = 1
26
+ opt_prefix = '--'
27
+ opts = {
28
+ 'resource': {'type': str, 'help': 'Metasploit resource script.', 'short': 'r'},
29
+ 'execute_command': {'type': str, 'help': 'Metasploit command.', 'short': 'x'},
30
+ 'environment': {'type': str, 'help': 'Environment variables string KEY=VALUE.', 'short': 'e'}
31
+ }
32
+ opt_key_map = {
33
+ 'x': 'execute_command',
34
+ 'r': 'resource',
35
+ HEADER: OPT_NOT_SUPPORTED,
36
+ DELAY: OPT_NOT_SUPPORTED,
37
+ FOLLOW_REDIRECT: OPT_NOT_SUPPORTED,
38
+ PROXY: OPT_NOT_SUPPORTED,
39
+ RATE_LIMIT: OPT_NOT_SUPPORTED,
40
+ RETRIES: OPT_NOT_SUPPORTED,
41
+ THREADS: OPT_NOT_SUPPORTED,
42
+ TIMEOUT: OPT_NOT_SUPPORTED,
43
+ USER_AGENT: OPT_NOT_SUPPORTED,
44
+ }
45
+ encoding = 'ansi'
46
+ ignore_return_code = True
47
+ install_version = '6.4.59'
48
+ install_cmd_pre = {
49
+ 'apt|apk': ['libpq-dev', 'libpcap-dev', 'libffi-dev', 'g++', 'make'],
50
+ 'pacman': ['ruby-erb', 'postgresql-libs', 'make'],
51
+ 'yum|zypper': ['postgresql-devel', 'make'],
52
+ }
53
+ install_cmd = (
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] && '
56
+ f'gem install bundler --user-install -n {CONFIG.dirs.bin} && '
57
+ f'bundle config set --local path "{CONFIG.dirs.share}" && '
58
+ 'bundle lock --normalize-platforms &&'
59
+ 'bundle install && '
60
+ f'ln -sf $HOME/.local/share/metasploit-framework_[install_version]/msfconsole {CONFIG.dirs.bin}/msfconsole'
61
+ )
62
+
63
+ @staticmethod
64
+ def on_init(self):
65
+ command = self.get_opt_value('execute_command')
66
+ script_path = self.get_opt_value('resource')
67
+ environment = self.run_opts.pop('environment', '')
68
+ env_vars = {}
69
+ if environment:
70
+ env_vars = dict(map(lambda x: x.split('='), environment.strip().split(',')))
71
+ env_vars['RHOST'] = self.inputs[0]
72
+ env_vars['RHOSTS'] = self.inputs[0]
73
+
74
+ # Passing msfconsole command directly, simply add RHOST / RHOSTS from host input and run then exit
75
+ if command:
76
+ self.run_opts['msfconsole.execute_command'] = (
77
+ f'setg RHOST {self.inputs[0]}; '
78
+ f'setg RHOSTS {self.inputs[0]}; '
79
+ f'{command.format(**env_vars)}; '
80
+ f'exit;'
81
+ )
82
+
83
+ # Passing resource script, replace vars inside by our environment variables if any, write to a temp file, and
84
+ # pass this temp file instead of the original one.
85
+ elif script_path:
86
+
87
+ # Read from original resource script
88
+ with open(script_path, 'r') as f:
89
+ content = f.read().replace('exit', '') + 'exit'
90
+
91
+ # Make a copy and replace vars inside by env vars passed on the CLI
92
+ timestr = get_file_timestamp()
93
+ out_path = f'{self.reports_folder}/.inputs/msfconsole_{timestr}.rc'
94
+ logger.debug(
95
+ f'Writing formatted resource script to new temp file {out_path}'
96
+ )
97
+ with open(out_path, 'w') as f:
98
+ content = content.format(**env_vars)
99
+ f.write(content)
100
+
101
+ script_name = script_path.split('/')[-1]
102
+ self._print(Panel(content, title=f'[bold magenta]{script_name}', expand=False), rich=True)
103
+
104
+ # Override original command with new resource script
105
+ self.run_opts['msfconsole.resource'] = out_path
106
+
107
+ # Nothing passed, error out
108
+ else:
109
+ raise ValueError('At least one of "execute_command" or "resource" must be passed.')
110
+
111
+
112
+ # TODO: This is better as it goes through an RPC API to communicate with
113
+ # metasploit rpc server, but it does not give any output.
114
+ # Seems like output is available only in Metasploit Pro, so keeping this in case
115
+ # we add support for it later.
116
+ #
117
+ # from pymetasploit3.msfrpc import MsfRpcClient
118
+ # class msfrpcd():
119
+ #
120
+ # opts = {
121
+ # 'uri': {'type': str, 'default': '/api/', 'help': 'msfrpcd API uri'},
122
+ # 'port': {'type': int, 'default': 55553, 'help': 'msfrpcd port'},
123
+ # 'server': {'type': str, 'default': 'localhost', 'help': 'msfrpcd host'},
124
+ # 'token': {'type': str, 'help': 'msfrpcd token'},
125
+ # 'username': {'type': str, 'default': 'msf', 'help': 'msfrpcd username'},
126
+ # 'password': {'type': str, 'default': 'test', 'help': 'msfrpcd password'},
127
+ # 'module': {'type': str, 'required': True, 'help': 'Metasploit module to run'}
128
+ # }
129
+ #
130
+ # def __init__(self, input, ctx={}, **run_opts):
131
+ # self.module = run_opts.pop('module')
132
+ # pw = run_opts.pop('password')
133
+ # self.run_opts = run_opts
134
+ # self.RHOST = input
135
+ # self.RHOSTS = input
136
+ # self.LHOST = self.get_lhost()
137
+ # # self.start_msgrpc()
138
+ # self.client = MsfRpcClient(pw, ssl=True, **run_opts)
139
+ #
140
+ # # def start_msgrpc(self):
141
+ # # code, out = Command.execute(f'msfrpcd -P {self.password}')
142
+ # # logger.info(out)
143
+ #
144
+ # def get_lhost(self):
145
+ # try:
146
+ # u = miniupnpc.UPnP()
147
+ # u.discoverdelay = 200
148
+ # u.discover()
149
+ # u.selectigd()
150
+ # return u.externalipaddress()
151
+ # except Exception:
152
+ # return 'localhost'
153
+ #
154
+ # def run(self):
155
+ # """Run a metasploit module.
156
+ #
157
+ # Args:
158
+ # modtype: Module type amongst 'auxiliary', 'exploit', 'post',
159
+ # 'encoder', 'nop', 'payload'.
160
+ # modname: Module name e.g 'auxiliary/scanner/ftp/ftp_version
161
+ # kwargs (dict): Module kwargs e.g RHOSTS, LHOST
162
+ # Returns:
163
+ # dict: Job results.
164
+ # """
165
+ # modtype = self.module.split('/')[0].rstrip('s')
166
+ # job = self.client.modules.execute(
167
+ # modtype,
168
+ # self.module,
169
+ # RHOST=self.RHOST,
170
+ # RHOSTS=self.RHOSTS,
171
+ # LHOST=self.LHOST)
172
+ # if job.get('error', False):
173
+ # logger.error(job['error_message'])
174
+ # job_info = self.client.jobs.info_by_uuid(job['uuid'])
175
+ # while (job_info['status'] in ['running', 'ready']):
176
+ # job_info = self.client.jobs.info_by_uuid(job['uuid'])
177
+ # job_info.update(job)
178
+ # print(type(job_info['result']['127.0.0.1']))
179
+ # return job_info
secator/tasks/naabu.py ADDED
@@ -0,0 +1,85 @@
1
+ from secator.decorators import task
2
+ from secator.definitions import (DELAY, HOST, IP, OPT_NOT_SUPPORTED, PORTS,
3
+ PROXY, RATE_LIMIT, RETRIES, THREADS,
4
+ TIMEOUT, TOP_PORTS)
5
+ from secator.output_types import Port, Ip
6
+ from secator.serializers import JSONSerializer
7
+ from secator.tasks._categories import ReconPort
8
+
9
+
10
+ @task()
11
+ class naabu(ReconPort):
12
+ """Port scanning tool written in Go."""
13
+ cmd = 'naabu'
14
+ input_types = [HOST, IP]
15
+ output_types = [Port, Ip]
16
+ tags = ['port', 'scan']
17
+ input_flag = '-host'
18
+ file_flag = '-list'
19
+ json_flag = '-json'
20
+ opts = {
21
+ 'scan_type': {'type': str, 'short': 'st', 'help': 'Scan type (SYN (s)/CONNECT(c))'},
22
+ 'skip_host_discovery': {'is_flag': True, 'short': 'Pn', 'default': False, 'help': 'Skip host discovery'},
23
+ # 'health_check': {'is_flag': True, 'short': 'hc', 'help': 'Health check'}
24
+ }
25
+ opt_key_map = {
26
+ DELAY: OPT_NOT_SUPPORTED,
27
+ PROXY: 'proxy',
28
+ RATE_LIMIT: 'rate',
29
+ RETRIES: 'retries',
30
+ TIMEOUT: 'timeout',
31
+ THREADS: 'c',
32
+ PORTS: 'port',
33
+ TOP_PORTS: 'top-ports',
34
+
35
+ # naabu opts
36
+ 'scan_type': 's',
37
+ # 'health_check': 'hc'
38
+ }
39
+ opt_value_map = {
40
+ TIMEOUT: lambda x: int(x)*1000 if x and int(x) > 0 else None, # convert to milliseconds
41
+ PROXY: lambda x: x.replace('socks5://', '')
42
+ }
43
+ item_loaders = [JSONSerializer()]
44
+ install_version = 'v2.3.3'
45
+ install_cmd = 'go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@[install_version]'
46
+ github_handle = 'projectdiscovery/naabu'
47
+ install_pre = {'apt': ['libpcap-dev'], 'apk': ['libpcap-dev', 'libc6-compat'], 'pacman|brew': ['libpcap']}
48
+ install_post = {'arch|alpine': 'sudo ln -sf /usr/lib/libpcap.so /usr/lib/libpcap.so.0.8'}
49
+ proxychains = False
50
+ proxy_socks5 = True
51
+ proxy_http = False
52
+ profile = 'io'
53
+
54
+ @staticmethod
55
+ def before_init(self):
56
+ self.hosts = []
57
+ for ix, input in enumerate(self.inputs):
58
+ if input == 'localhost':
59
+ self.inputs[ix] = '127.0.0.1'
60
+
61
+ @staticmethod
62
+ def on_cmd(self):
63
+ scan_type = self.get_opt_value('scan_type')
64
+ if scan_type == 's':
65
+ self.requires_sudo = True
66
+
67
+ @staticmethod
68
+ def on_json_loaded(self, item):
69
+ ip = item['ip']
70
+ host = item['host'] if 'host' in item else ip
71
+ if host == '127.0.0.1':
72
+ host = 'localhost'
73
+ if host not in self.hosts:
74
+ yield Ip(
75
+ ip=ip,
76
+ host=host,
77
+ alive=True
78
+ )
79
+ self.hosts.append(host)
80
+ yield Port(
81
+ ip=ip,
82
+ port=item['port'],
83
+ host=host,
84
+ state='open'
85
+ )