forked from MISP/misp-modules
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdefender_endpoint_export.py
executable file
·131 lines (102 loc) · 4.25 KB
/
defender_endpoint_export.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
"""
Export module for coverting MISP events into Defender for Endpoint KQL queries.
Config['Period'] : allows to define period over witch to look for IOC from now
"""
import base64
import json
misperrors = {"error": "Error"}
types_to_use = ['sha256', 'sha1', 'md5', 'domain', 'ip-src', 'ip-dst', 'url']
userConfig = {
}
moduleconfig = ["Period"]
inputSource = ['event']
outputFileExtension = 'kql'
responseType = 'application/txt'
moduleinfo = {'version': '1.1', 'author': 'Julien Bachmann, Hacknowledge, Maik Wuerth',
'description': 'Defender for Endpoint KQL hunting query export module',
'module-type': ['export']}
def handle_sha256(value, period):
query = f"""find in (DeviceEvents, DeviceAlertEvents,AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
where (SHA256 == '{value}' or InitiatingProcessSHA1 == '{value}') and
Timestamp between(ago({period}) .. now())"""
return query.replace('\n', ' ')
def handle_sha1(value, period):
query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
where (SHA1 == '{value}' or InitiatingProcessSHA1 == '{value}') and
Timestamp between(ago({period}) .. now())"""
return query.replace('\n', ' ')
def handle_md5(value, period):
query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
where (MD5 == '{value}' or InitiatingProcessMD5 == '{value}') and
Timestamp between(ago({period}) .. now())"""
return query.replace('\n', ' ')
def handle_domain(value, period):
query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents)
where RemoteUrl contains '{value}' and
Timestamp between(ago({period}) .. now())"""
return query.replace('\n', ' ')
def handle_ip(value, period):
query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents)
where RemoteIP == '{value}' and
Timestamp between(ago({period}) .. now())"""
return query.replace('\n', ' ')
def handle_url(value, period):
query = f"""let url = '{value}';
search in (EmailUrlInfo,UrlClickEvents,DeviceNetworkEvents,DeviceFileEvents,DeviceEvents,BehaviorEntities, AlertInfo, AlertEvidence, DeviceAlertEvents)
Timestamp between(ago({period}) .. now()) and
RemoteUrl has url
or FileOriginUrl has url
or FileOriginReferrerUrl has url
or Url has url"""
return query.replace('\n', ' ')
handlers = {
'sha256': handle_sha256,
'sha1': handle_sha1,
'md5': handle_md5,
'domain': handle_url,
'ip-src': handle_ip,
'ip-dst': handle_ip,
'url': handle_url
}
def handler(q=False):
if q is False:
return False
request = json.loads(q)
config = request.get("config", {"Period": ""})
output = ''
for event in request["data"]:
for attribute in event["Attribute"]:
if attribute['type'] in types_to_use:
output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n'
for obj in event["Object"]:
for attribute in obj["Attribute"]:
if attribute['type'] in types_to_use:
output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n'
r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')}
return r
def introspection():
modulesetup = {}
try:
responseType
modulesetup['responseType'] = responseType
except NameError:
pass
try:
userConfig
modulesetup['userConfig'] = userConfig
except NameError:
pass
try:
outputFileExtension
modulesetup['outputFileExtension'] = outputFileExtension
except NameError:
pass
try:
inputSource
modulesetup['inputSource'] = inputSource
except NameError:
pass
return modulesetup
def version():
moduleinfo['config'] = moduleconfig
return moduleinfo