-
Notifications
You must be signed in to change notification settings - Fork 13
/
run.py
283 lines (266 loc) · 8.4 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
import argparse
from argparse import RawTextHelpFormatter
from tlsa.tlsa import Tlsa
from utils.globals import version
class ComplianceAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
super().__init__(option_strings, dest, nargs, **kwargs)
def __call__(self, parser, namespace, values, option_string=""):
if not isinstance(namespace.__getattribute__(self.dest), dict):
namespace.__setattr__(self.dest, {})
converters = {
"false": False,
"true": True
}
dictionary = namespace.__getattribute__(self.dest)
value = values[0].lower() if isinstance(values[0], str) else values[0]
dictionary[option_string.strip("-")] = converters.get(value, value)
class ComplianceTrue(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
super().__init__(option_strings, dest, nargs, **kwargs)
def __call__(self, parser, namespace, values, option_string=""):
if not isinstance(namespace.__getattribute__(self.dest), dict):
namespace.__setattr__(self.dest, {})
dictionary = namespace.__getattribute__(self.dest)
dictionary[option_string.strip("-")] = True
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="TLSAssistant",
description="%(prog)s Help",
formatter_class=RawTextHelpFormatter, # todo: change the desc
epilog="https://st.fbk.eu - Security and Trust, FBK Research Unit",
)
parser.add_argument("--version", action="version", version=f"%(prog)s v{version}")
parser.add_argument(
"-v",
"--verbosity",
action="store_true",
help="increase output verbosity",
default=False,
)
openssl = parser.add_mutually_exclusive_group()
openssl.add_argument(
"--openssl",
"--openssl-version",
action="store",
type=str,
help="Add openSSL version to consider if configuration analysis is asked.",
)
openssl.add_argument(
"--ignore-openssl",
action="store_true",
dest="ignore_openssl",
help="During configuration analysis, ignore openssl version completely.",
)
hostname_or_apk = parser.add_mutually_exclusive_group(required=True)
parser.add_argument(
"-ot",
"--output-type",
action="store",
type=str,
choices=["pdf", "html"],
default=None,
help="The type of the report output.\nOutput type can be omitted and can be obtained"
" by --output extension.",
)
parser.add_argument(
"-o",
"--output",
type=str,
action="store",
help="Set report path.",
default=None,
)
parser.add_argument(
"--group-by",
action="store",
help="Choose how to group results by.",
choices=["host", "module"],
default="host",
)
hostname_or_apk.add_argument(
"-s",
"--server",
type=str,
action="store",
help="The hostname, target of the analysis.",
)
hostname_or_apk.add_argument(
"-f",
"--file",
type=str,
action="store",
help="The configuration to analyze.",
)
hostname_or_apk.add_argument(
"-d",
"--domain_file",
type=str,
action="store",
help="The file path which has the hostname to analyze.",
)
hostname_or_apk.add_argument(
"-l",
"--list",
nargs="?",
help="List all modules or print an help of a module.\nFor Example\n-l freak",
default="",
)
hostname_or_apk.add_argument(
"-a",
"--app",
type=str,
action="store",
help="The apk/ipa path, target of the analysis.",
)
parser.add_argument(
"--apply-fix",
dest="apply_fix",
action="store",
type=str,
nargs="?",
default="",
help="Apply fix in the current configuration.\n Give a path if using -s.\ni.e."
"\n\tpython3 run.py -s fbk.eu --apply-fix myconf.conf",
)
configurations = parser.add_mutually_exclusive_group()
configurations.add_argument(
"-c",
"--conf",
"--configuration",
action="store",
dest="configuration",
help="Configuration path.",
default="default",
)
configurations.add_argument(
"-m",
"--modules",
action="store",
dest="configuration",
nargs="+",
help="List of modules to run" "\nFor example\n\t-m breach crime freak",
)
parser.add_argument(
"-e",
"--exclude",
action="store",
dest="exclude",
nargs="+",
help="List of modules to exclude" "\nFor example\n\t-e breach crime",
)
parser.add_argument(
"--stix",
action="store_true",
help="Generate STIX2 compliant output.",
default=False,
)
parser.add_argument(
"--webhook",
dest="webhook",
action="store",
type=str,
nargs="?",
default="",
help="Add a webhook url to send the results.",
)
parser.add_argument(
"--prometheus",
dest="prometheus",
action="store",
type=str,
nargs="?",
default="",
help="Generate the prometheus output in a default path or in the specified path.",
)
parser.add_argument(
"--config_type",
action="store",
help="Define the type of configuration to analyze.",
choices=["apache", "nginx", "auto"],
default="auto",
)
parser.add_argument(
"--guidelines",
type=str,
nargs=1,
action=ComplianceAction,
dest="compliance_args",
help="A string containing the names of the guidelines that should be checked in the form: "
"guideline_profile_variant in the case of multiple guidelines they should be comma separated. "
"Use \"list\" for a list of valid strings and \"aliases\" for a list of aliases."
)
parser.add_argument(
"--apache",
type=str,
nargs=0,
action=ComplianceTrue,
default=True,
dest="compliance_args",
help="Default to False. If True the output configuration will have apache syntax, if false nginx will be used."
)
parser.add_argument(
"--security",
type=str,
nargs=1,
action=ComplianceAction,
default=True,
dest="compliance_args",
help="Default to True. If False the legacy level priority will be used"
)
parser.add_argument(
"--output_config",
type=str,
nargs=1,
action=ComplianceAction,
dest="compliance_args",
help="Where to save the output configuration file, only needed for generate one/many"
)
parser.add_argument(
"--certificate_index",
type=int,
nargs=1,
action=ComplianceAction,
dest="compliance_args",
help="The index of the certificate to use for the analysis, only needed if the website has multiple certificates."
"Default to 1 (first certificate)."
)
parser.add_argument(
"--custom_guidelines",
type=str,
nargs=1,
action=ComplianceAction,
dest="compliance_args",
help="A path to a custom guideline file, only needed if the user wants to use a custom guideline."
)
parser.add_argument(
"--use_cache",
type=bool,
nargs=0,
default=False,
action=ComplianceTrue,
dest="compliance_args",
help="Default to False. If True the program will use the cached testssl analysis, if False the cache will be ignored."
)
parser.add_argument(
"--clean",
type=bool,
nargs=0,
default=False,
action=ComplianceTrue,
dest="compliance_args",
help="Default to False. If True the program will remove the cached testssl analysis for this host."
)
parser.add_argument(
"--no_psk",
type=bool,
nargs=0,
default=False,
action=ComplianceTrue,
dest="compliance_args",
help="Default to False. If True the program will not consider PSK ciphersuites during analysis."
)
# todo add default aliases configurations for analysis
# configurations.add_argument()
args = parser.parse_args()
tlsa = Tlsa(args)