Merge pull request #448 from HacknowledgeCH/export_defender_endpoint

Export defender endpoint
pull/466/head
Alexandre Dulaunoy 2020-11-27 21:04:23 +01:00 committed by GitHub
commit df69d75d8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 114 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

View File

@ -0,0 +1,11 @@
{
"description": "Defender for Endpoint KQL hunting query export module",
"requirements": [],
"features": "This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC.",
"references": [
"https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference"
],
"input": "MISP Event attributes",
"output": "Defender for Endpoint KQL queries",
"logo": "defender_endpoint.png"
}

View File

@ -1,2 +1,2 @@
__all__ = ['cef_export', 'mass_eql_export', 'liteexport', 'goamlexport', 'threat_connect_export', 'pdfexport',
'threatStream_misp_export', 'osqueryexport', 'nexthinkexport', 'vt_graph']
'threatStream_misp_export', 'osqueryexport', 'nexthinkexport', 'vt_graph', 'defender_endpoint_export']

View File

@ -0,0 +1,102 @@
"""
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 = ['sha1', 'md5', 'domain', 'ip', 'url']
userConfig = {
}
moduleconfig = ["Period"]
inputSource = ['event']
outputFileExtension = 'kql'
responseType = 'application/txt'
moduleinfo = {'version': '1.0', 'author': 'Julien Bachmann, Hacknowledge',
'description': 'Defender for Endpoint KQL hunting query export module',
'module-type': ['export']}
def handle_sha1(value, period):
query = f"""find in (DeviceAlertEvents, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
where SHA1 == '{value}' or InitiatingProcessSHA1 == '{value}'"""
return query.replace('\n', ' ')
def handle_md5(value, period):
query = f"""find in (DeviceAlertEvents, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents)
where MD5 == '{value}' or InitiatingProcessMD5 == '{value}'"""
return query.replace('\n', ' ')
def handle_domain(value, period):
query = f"""find in (DeviceAlertEvents, DeviceNetworkEvents)
where RemoteUrl contains '{value}'"""
return query.replace('\n', ' ')
def handle_ip(value, period):
query = f"""find in (DeviceAlertEvents, DeviceNetworkEvents)
where RemoteIP == '{value}'"""
return query.replace('\n', ' ')
def handle_url(value, period):
query = f"""find in (DeviceAlertEvents, DeviceNetworkEvents)
where RemoteUrl startswith '{value}'"""
return query.replace('\n', ' ')
handlers = {
'sha1': handle_sha1,
'md5': handle_md5,
'domain': handle_domain,
'ip': 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'
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