-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-config.yaml
307 lines (282 loc) · 14.1 KB
/
example-config.yaml
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# -----------------------------------------
# Evaluation doc configuration
# -----------------------------------------
# For each testssl.sh result JSON file that is detected by the
# testssl_result_handler.py watchdog, a larger JSON document
# will be created (i.e. the 'evaluation_doc') that contains the raw
# testssl.sh JSON result contents but also some other metadata properties.
# Here you can customize the top level document property/key names for
# those values
#
# Once the document is constructed, it is passed to the evaluation engine
# where you can use https://github.com/adriank/ObjectPath queries to evaluate
# conditions in the document and trigger alerts on that
#
# Required
evaluation_doc_config:
target_keys:
# The top level key that will contain the raw testssl.sh result JSON contents
testssl_result_json: "testssl_result"
# The top level key that will contain the RELATIVE 'input_dir' path to the
# directory that contains the JSON file result that the watchdog detected
testssl_result_parent_dir_path: "testssl_result_parent_dir_path"
# The top level key that will contain the ABSOLUTE 'input_dir' path to the
# directory that contains the JSON file result that the watchdog detected
testssl_result_parent_dir_abs_path: "testssl_result_parent_dir_abs_path"
# The top level key that will contain the ABSOLUTE path to the
# JSON result filename that the watchdog detected
testssl_result_file_abs_path: "testssl_result_file_abs_path"
# The top level key that will contain the FILENAME ONLY (no path info)
# JSON result file that the watchdog detected
testssl_result_filename: "testssl_result_filename"
# The top level key that will contain the integer value of days till expiration
# the value placed here is the result of the `cert_expires_objectpath` below
cert_expires_in_days: "cert_expires_in_days"
# The top level key that will contain any any properties extracted out of the
# full PATH to the raw testssl.sh result JSON that triggered the watchdog
# as defined in `path_properties_grok` below
result_metadata: "result_metadata"
# Optional: Custom GROKs defined here can be used in the
# 'path_properties_grok' below to extract variables
# out of the testssl.sh result JSON file path which can
# will then be applied as sub-properties of the evaluation_docs
# 'result_metadata' key defined above.
custom_groks:
PATHPART: '[A-Za-z0-9-_.]+'
MANYPATHPARTS: '[A-Za-z0-9-_./]+'
# Optional: If defined, the variables extracted here will
# be applied as sub-properties of the evaluation_docs
# 'result_metadata' key defined above.
#
# NOTE! any grok field name of 'ignored' will be excluded/ignored
path_properties_grok: '%{MANYPATHPARTS:ignored}/%{PATHPART:fqdn}/%{PATHPART:scan_timestamp}/%{PATHPART:site_category}/%{PATHPART:site_type}/%{PATHPART:filename}'
# Required: a custom 'ObjectPath' query relative from the root of the 'evaluation_doc'
# that yields the property value that holds the certificate expiration date.
# The value here will be applied to the evaluation_doc_config.cert_expires_in_days property
# as an integer (days) @ see http://objectpath.org/reference.html
#
# NOTE! sometimes multiple certs are returned, so they are keyed by `cert_notAfter <cert#[N]>`
# so the syntax here leverages an ObjectPath split() to only check 1st part
cert_expires_objectpath: "$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_notAfter'][@.finding]"
# -----------------------------------------
# Trigger definitions
# -----------------------------------------
# For every testssl.sh JSON result file, the 'evaluation_doc' constructed
# via the above configuration will be passed to the evaluation engine
# which applies the following triggers if the 'objectpath' yields a result
# @ see http://objectpath.org/reference.html
#
# Behaviors:
# - queries that yield a Boolean will only fire if the result is True
# - queries that return a string/int/boolean(True) will have their (title,value) passed to the the alert
# - queries that return a list/generator will have (title,[results]) passed to the alert
#
# For all triggers matched, they will all be sent to the configured reactors
# which must match a supported `reactor_engine`
#
trigger_on:
# NOTE! this one is here for the example...
# you would likely never take action on
# such a trigger like this..
cert_expiration_gte30days:
objectpath: "$.cert_expires_in_days >= 30"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in >= ~30 days"
# Expiration triggers and vulnerabilities
cert_expiration_90days:
objectpath: "$.cert_expires_in_days is 90"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in ~90 days"
cert_expiration_60days:
objectpath: "$.cert_expires_in_days is 60"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in ~60 days"
cert_expiration_30days:
objectpath: "$.cert_expires_in_days is 30"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in ~30 days"
cert_expiration_7days:
objectpath: "$.cert_expires_in_days is 7"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in ~7 days"
cert_expiration_1day:
objectpath: "$.cert_expires_in_days is 1"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert Expires in ~1 days"
cert_expired:
objectpath: "$.cert_expires_in_days <= 0"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "Cert is EXPIRED!"
protocol_issues:
objectpath: "$.testssl_result.scanResult[0].protocols[@.severity in MEDIUMHIGHCRITICAL]"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "One or more testssl.sh protocol issues found"
cipher_issues:
objectpath: "$.testssl_result.scanResult[0].ciphers[@.severity in MEDIUMHIGHCRITICAL]"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "One or more testssl.sh cipher issues found"
vulnerabilities_issues:
objectpath: "$.testssl_result.scanResult[0].vulnerabilities[@.severity in MEDIUMHIGHCRITICAL]"
reactors: ["slack","copy_json_result","copy_html_result"]
title: "One or more testssl.sh vulnerabilities issues found"
# -----------------------------------------
# Reactor Engines
# -----------------------------------------
# For each trigger fired above, a 'trigger_result' is created
# that contains the following information. Each reactor engine
# is passed the following information to its "handleTriggers()" method
#
# - 'triggers_fired' - array of trigger_result objects.
# Where each trigge_result is defined as:
# {
# 'tag': [short name of the trigger]
# 'title':[see above, title of the trigger name],
# 'reactors':[see above, array of configured reactor names],
# 'objectpath':[see above, the objectpath],
# 'results':[array of raw object path result values],
# 'config_filename':[name of the YAML config the trigger was defined in],
# 'testssl_json_result_abs_file_path':[absolute path to the testssl.sh JSON result file],
# 'testssl_json_result_filename':[filename only of JSON result file],
# 'evaluation_doc':[the evalution_doc object that the trigger evaluated]
# }
#
#
# - 'objectpath_ctx' - a reference to the ObjectPathContext object used
# when processing the trigger evaluations. The following
# ObjectPathContext properties can be used in the reactor
# for further ObjectPath based functionality if the reactor
# plugin wishes to take advantage of it.
# {
# exec_objectpath: ObjectPathContext function reference
# exec_objectpath_specific_match: ObjectPathContext function reference
# exec_objectpath_first_match: ObjectPathContext function reference
# evaluation_doc: the raw evalution_doc object that the trigger evaluated
# }
#
#
reactor_engines:
#----------------
# CopyFileReactor
# - Copy files around based on fired trigger results
# ---------------
copy_json_result:
class_name: "CopyFileReactor"
# If specified will cleanup all the path
# listed below where dirs/files are
# older than `delete_older_than_days`
# This is OPTIONAL
cleanup:
path: "output/"
delete_older_than_days: .0001 # can be a decimal as well
# Each 'copy_from' and 'copy_to' property below is a jinja2 template
#
# Each jinja2 copy_from/to template below is rendered with the `trigger_result`
# object currently being evaluated from the array (described above)
# passed as its jinja2 template context object root
#
# The jinja2 environment executing the templates exposes several filter functions
# which yield the result(s) of an ObjectPath query against the
# jinja2 template context if needed ('trigger_result' object contents).
#
# - `exec_objectpath`: can return a [] or single value for all matches
#
# - `exec_objectpath_first_match` : returns only the first match found
#
# - `exec_objectpath_specific_match(N)` : returns the match found at index N
#
#
# AFTER the copy_from/to values are evaluated the any needed target directories
# will automatically be created and the 'from' file will be copied to the destination
#
copy_from: "{{testssl_json_result_abs_file_path}}"
copy_to: "output/testssl.sh-issues/{{tag}}/{{testssl_result_filename}}"
#----------------
# copy_html_result
# - Copy HTML result files around based on fired trigger results
# ---------------
copy_html_result:
class_name: "CopyFileReactor"
copy_from: "{{testssl_json_result_abs_file_path|replace('.json','.html')}}"
copy_to: "output/testssl.sh-issues/{{tag}}/{{testssl_result_filename|replace('.json','.html')}}"
#----------------
# SlackReactor
# - Send alerts to slack based on fired trigger results
# ---------------
slack:
class_name: "SlackReactor"
# Leverages a webhook url.
# Example hook posts to: https://bitsofinfo.slack.com/messages/CE46Z3TJA/
# the #bitsofinfo-dev channel (this webhook is INTENTIONALLY PUBLIC for example purposes!)
webhook_url: https://hooks.slack.com/services/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
# The template engine is jinja2 and the below can be crafted however you want
# The following template is ONLY rendered when one or more triggers fire.
# Any trigger data sent to this engine will apply each one as an additional
# slack attachment to be appended to the list of attachments below.
#
# The jinja2 template below is rendered with the `evaluation_doc`
# passed as its template context object
#
# The jinja2 environment executing this table exposes several filter functions
# which yield the result(s) of an ObjectPath query against the
# jinja2 template context ('evaluation_doc' object contents).
#
# - `exec_objectpath`: can return a [] or single value for all matches
#
# - `exec_objectpath_first_match` : returns only the first match found
#
# - `exec_objectpath_specific_match(N)` : returns the match found at index N
#
# The template below is intended to be used as the pre-amble for any alert sent.
# any trigger results will be appended as additional attachments with the trigger
# title + value=objectpath query result
#
template: >
{
"text":"*testssl.sh -> {{"$.result_metadata.fqdn"|exec_objectpath}} expires in {{"$.cert_expires_in_days"|exec_objectpath}} days*",
"attachments": [
{
"fields": [
{
"title":"Site Category",
"value":"{{"$.result_metadata.site_category"|exec_objectpath}}",
"short":true
},
{
"title":"Site Type",
"value":"{{"$.result_metadata.site_type"|exec_objectpath}}",
"short":true
},
{
"title":"Valid from",
"value":"{{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_notBefore'][@.finding]"|exec_objectpath_first_match}}",
"short":true
},
{
"title":"Valid to",
"value":"{{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_notAfter'][@.finding]"|exec_objectpath_first_match}}",
"short":true
},
{
"title":"Cert Names",
"value":"`{{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_commonName'][@.finding]"|exec_objectpath_first_match}}, {{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_commonName_wo_SNI'][@.finding]"|exec_objectpath_first_match}}, {{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_subjectAltName'][@.finding]"|exec_objectpath_first_match}}`",
"short":false
},
{
"title":"Censys.io SHA256 check",
"value":"https://censys.io/ipv4?q={{"$.testssl_result.scanResult[0].serverDefaults[split(@.id,' ')[0] is 'cert_fingerprintSHA256'][@.finding]"|exec_objectpath_first_match}}",
"short":false
},
{
"title":"testssl.sh cmd",
"value":"`{{"$.testssl_result.Invocation"|exec_objectpath}}`",
"short":false
},
{
"title":"testssl.sh cmd result files",
"value":"http://localhost:8888/{{"$.testssl_result_parent_dir_path"|exec_objectpath}}",
"short":false
}
]
}
]
}