Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Azure
GitHub Repository: Azure/Azure-Sentinel-Notebooks
Path: blob/master/src/SentinelUtilities/SentinelPortal/bookmark_helper.py
3255 views
1
# -------------------------------------------------------------------------
2
# Copyright (c) Microsoft Corporation. All rights reserved.
3
# Licensed under the MIT License. See License.txt in the project root for
4
# license information.
5
# --------------------------------------------------------------------------
6
"""
7
Hunting Bookmark Helper:
8
This module provides helper methods to initialize and
9
manipulate Hunting Bookmark (create, read, and delete).
10
"""
11
# pylint: disable-msg=C0103
12
# pylint: disable-msg=E0401
13
# pylint: disable-msg=E0602
14
# pylint: disable-msg=R0902
15
# pylint: disable-msg=R0903
16
# pylint: disable-msg=R0913
17
# pylint: disable-msg=W0201
18
# pylint: disable=line-too-long
19
20
import uuid
21
import requests
22
import jsons
23
from SentinelUtils import InputValidation
24
25
26
class Constants():
27
""" This class holds constants """
28
TYPE = 'Microsoft.SecurityInsights/Bookmarks'
29
ETAG = '*'
30
BOOKMARK_RESOURCE_BASE = '/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.OperationalInsights/workspaces/{2}/providers/Microsoft.SecurityInsights/bookmarks'
31
BOOKMARK_ID = '/{0}'
32
BOOKMARK_RESOURCE_ID = BOOKMARK_RESOURCE_BASE + BOOKMARK_ID
33
ENTITY_MAPPING = '__entityMapping'
34
ENTITY_TYPE = ['Bookmark'
35
'SecurityAlert',
36
'Account',
37
'Host',
38
'Malware',
39
'File',
40
'Process',
41
'CloudApplication',
42
'DnsResolution',
43
'AzureResource',
44
'FileHash',
45
'RegistryKey',
46
'RegistryValue',
47
'SecurityGroup',
48
'Url']
49
50
51
class BookmarkProperties():
52
"""
53
This class holds properties for Hunting bookmark.
54
Special Note: For query_result_dict, actual value is the key, and the entity type is the value.
55
"""
56
57
def __init__(self,
58
display_name,
59
query,
60
query_result_dict=None,
61
tag_list=None,
62
notes=None,
63
event_time=None,
64
query_start_time=None,
65
query_end_time=None):
66
self.displayName = display_name
67
self.labels = tag_list
68
self.query = query
69
self.queryResult = query_result_dict
70
self.notes = notes
71
self.eventTime = event_time
72
self.queryStartTime = query_start_time
73
self.queryEndTime = query_end_time
74
self.bookmarkId = str(uuid.uuid4())
75
76
@property
77
def bookmarkId(self):
78
""" bookmarkId getter """
79
return self._bookmarkId
80
81
@bookmarkId.setter
82
def bookmarkId(self, bookmark_id):
83
""" bookmarkId setter """
84
self._bookmarkId = bookmark_id
85
86
@property
87
def displayName(self):
88
""" displayName getter """
89
return self._displayName
90
91
@displayName.setter
92
def displayName(self, display_name):
93
""" displayName setter """
94
InputValidation.validate_input('display_name', display_name)
95
self._displayName = display_name
96
97
@property
98
def labels(self):
99
""" labels getter """
100
return self._labels
101
102
@labels.setter
103
def labels(self, tag_list):
104
""" labels setter """
105
if tag_list:
106
self._labels = tag_list
107
else:
108
self._labels = []
109
110
@property
111
def query(self):
112
""" query """
113
return self._query
114
115
@query.setter
116
def query(self, query):
117
""" query setter """
118
InputValidation.validate_input('query', query)
119
self._query = query
120
121
@property
122
def queryResult(self):
123
""" queryResult """
124
return self._queryResult
125
126
@queryResult.setter
127
def queryResult(self, query_result):
128
""" queryResult setter """
129
result_str = None
130
if query_result and isinstance(query_result, dict):
131
if all(elem in Constants.ENTITY_TYPE for elem in list(query_result.values())):
132
query_result_dict = {}
133
query_result_dict.update({Constants.ENTITY_MAPPING: query_result})
134
result_str = jsons.dumps(query_result_dict)
135
self._queryResult = result_str
136
if not result_str:
137
self._queryResult = '{}'
138
139
@property
140
def notes(self):
141
""" notes getter """
142
return self._notes
143
144
@notes.setter
145
def notes(self, notes):
146
""" notes setter """
147
self._notes = notes
148
149
@property
150
def eventTime(self):
151
""" eventTime """
152
return self._eventTime
153
154
@eventTime.setter
155
def eventTime(self, event_time):
156
""" eventTime setter """
157
self._eventTime = event_time
158
159
@property
160
def queryStartTime(self):
161
""" queryStartTime """
162
return self._queryStartTime
163
164
@queryStartTime.setter
165
def queryStartTime(self, query_start_time):
166
""" queryStartTime setter """
167
self._queryStartTime = query_start_time
168
169
@property
170
def queryEndTime(self):
171
""" queryEndTime """
172
return self._queryEndTime
173
174
@queryEndTime.setter
175
def queryEndTime(self, query_end_time):
176
""" queryEndTime setter """
177
self._queryEndTime = query_end_time
178
179
180
class BookmarkModel():
181
""" This class holds data model for Bookmark """
182
183
def __init__(self,
184
bookmark_name,
185
subscription_id,
186
resource_group_name,
187
workspace_name,
188
bookmark_properties):
189
self.name = bookmark_name
190
self.type = Constants.TYPE
191
self.etag = Constants.ETAG
192
self.properties = bookmark_properties
193
self.bookmark_resource_base = Constants.BOOKMARK_RESOURCE_BASE.format(subscription_id, resource_group_name, workspace_name)
194
self.id = self.bookmark_resource_base + Constants.BOOKMARK_ID.format(bookmark_properties.bookmarkId)
195
196
@property
197
def id(self):
198
""" id getter """
199
return self._id
200
201
@id.setter
202
def id(self, bookmark_resource_id):
203
""" id setter """
204
self._id = bookmark_resource_id
205
206
@property
207
def name(self):
208
""" name getter """
209
return self._name
210
211
@name.setter
212
def name(self, bookmark_name):
213
""" name setter """
214
InputValidation.validate_input('bookmark_name', bookmark_name)
215
self._name = bookmark_name
216
217
@property
218
def type(self):
219
""" type getter """
220
return self._type
221
222
@type.setter
223
def type(self, t):
224
""" type setter """
225
self._type = t
226
227
@property
228
def etag(self):
229
""" etag getter """
230
return self._etag
231
232
@etag.setter
233
def etag(self, etag):
234
""" etag setter """
235
self._etag = etag
236
237
@property
238
def properties(self):
239
""" properties getter """
240
return self._properties
241
242
@properties.setter
243
def properties(self, bookmark_properties):
244
""" properties setter """
245
InputValidation.validate_input('bookmark_properties', bookmark_properties)
246
self._properties = bookmark_properties
247
248
# pylint: disable-msg=W0703
249
class BookmarkHelper:
250
""" This class provides CRUD methods for bookmark """
251
252
BOOKMARK_BASE_URL = 'https://management.azure.com'
253
BOOKMARK_API_VERSION = '?api-version=2019-01-01-preview'
254
255
def __init__(self, access_token):
256
self.access_token = access_token
257
258
def _set_header(self):
259
return {'Authorization': 'Bearer ' + self.access_token}
260
261
def _set_rp_put_url(self, bookmark_model):
262
return self.BOOKMARK_BASE_URL + bookmark_model.id + self.BOOKMARK_API_VERSION
263
264
def _set_rp_get_url(self, bookmark_model):
265
return self.BOOKMARK_BASE_URL + bookmark_model.bookmark_resource_base + self.BOOKMARK_API_VERSION
266
267
def _set_rp_delete_url(self, bookmark_model):
268
return self.BOOKMARK_BASE_URL + bookmark_model.id + self.BOOKMARK_API_VERSION
269
270
def _generate_bookmark_payload(self, bookmark_model):
271
items = jsons.dump(bookmark_model, strip_privates=True)
272
return jsons.dump(self._cleanup_json(items))
273
274
def _cleanup_json(self, data):
275
"""
276
Delete keys with the value ``None`` in a dictionary, recursively.
277
This alters the input so you may wish to ``copy`` the dict first.
278
"""
279
for key, value in list(data.items()):
280
if key == 'bookmark_resource_base':
281
del data[key]
282
elif value is None:
283
del data[key]
284
elif isinstance(value, dict):
285
self._cleanup_json(value)
286
287
return data
288
289
def add_bookmark(self, bookmark_model):
290
""" Create a hunting bookmark """
291
try:
292
result = requests.put(
293
self._set_rp_put_url(bookmark_model),
294
headers=self._set_header(),
295
json=self._generate_bookmark_payload(bookmark_model))
296
print('Success')
297
return result
298
except Exception as e:
299
print(str(e))
300
301
def get_bookmarks(self, bookmark_model):
302
""" Retrieve hunting bookmarks for workspace """
303
try:
304
result = requests.get(
305
self._set_rp_get_url(bookmark_model),
306
headers=self._set_header())
307
print('Success')
308
return result
309
except Exception as e:
310
print(str(e))
311
312
def delete_bookmark(self, bookmark_model):
313
""" Delete a hunting bookmark, not recommend for notebook users """
314
try:
315
result = requests.delete(
316
self._set_rp_delete_url(bookmark_model),
317
headers=self._set_header())
318
print('Success')
319
return result
320
except Exception as e:
321
print(str(e))
322
323
# end of the class
324
325