Merge pull request #258 from HacknowledgeCH/export_nexthink

Export nexthink
pull/259/head
Alexandre Dulaunoy 2018-12-26 12:09:57 +01:00 committed by GitHub
commit fdc8be0790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 153 additions and 1 deletions

View File

@ -0,0 +1,9 @@
{
"description": "Nexthink NXQL query export module",
"requirements": [],
"features": "This module export an event as Nexthink NXQL queries that can then be used in your own python3 tool or from wget/powershell",
"references": ["https://doc.nexthink.com/Documentation/Nexthink/latest/APIAndIntegrations/IntroducingtheWebAPIV2"],
"input": "MISP Event attributes",
"output": "Nexthink NXQL queries",
"logo": "logos/nexthink.svg"
}

22
doc/logos/nexthink.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="125px" height="32px" viewBox="0 0 125 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47 (45396) - http://www.bohemiancoding.com/sketch -->
<title>nexthink</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="nexthink" fill-rule="nonzero">
<path d="M0,8 C0.7,7.8 1.5,7.6 2.7,7.4 C3.9,7.2 5.3,7.1 6.9,7.1 C8.3,7.1 9.5,7.3 10.4,7.7 C11.3,8.1 11.9,8.7 12.5,9.4 C13.1,10.1 13.5,11 13.7,12 C13.9,13 14,14.1 14,15.3 L14,25.4 L11,25.4 L11,16 C11,14.9 10.9,14 10.8,13.2 C10.7,12.4 10.4,11.8 10.1,11.3 C9.8,10.8 9.3,10.5 8.7,10.2 C8.1,10 7.4,9.9 6.5,9.9 L5.4,9.9 C5.1,10 4.7,10 4.4,10 C4.1,10 3.8,10.1 3.5,10.1 C3.2,10.1 3.1,10.2 3,10.2 L3,25.3 L0,25.3 L0,8 Z" id="Shape" fill="#333333"></path>
<path d="M17.5,16.4 C17.5,14.8 17.7,13.6 18.2,12.4 C18.7,11.2 19.3,10.2 20,9.4 C20.8,8.6 21.6,8 22.6,7.6 C23.6,7.2 24.6,7 25.6,7 C28,7 29.9,7.8 31.2,9.3 C32.5,10.8 33.1,13.1 33.1,16.2 L33.1,16.6 L33.1,17.4 L20.9,17.4 C21,19.3 21.6,20.6 22.5,21.6 C23.4,22.6 24.9,23 26.9,23 C28,23 29,22.9 29.7,22.7 C30.5,22.5 31.1,22.3 31.4,22.1 L31.8,24.8 C31.4,25 30.7,25.2 29.7,25.5 C28.7,25.7 27.6,25.8 26.4,25.8 C24.8,25.8 23.5,25.6 22.3,25.1 C21.2,24.6 20.2,24 19.5,23.1 C18.8,22.3 18.2,21.3 17.9,20.1 C17.7,19.1 17.5,17.8 17.5,16.4 L17.5,16.4 Z M29.8,14.4 C29.8,13 29.5,12.1 28.7,11.2 C28,10.3 27,9.8 25.7,9.8 C25,9.8 24.3,9.9 23.8,10.2 C23.2,10.5 22.8,10.9 22.4,11.3 C22,11.8 21.7,12.3 21.5,12.9 C21.3,13.5 21.1,13.8 21.1,14.4 L29.8,14.4 Z" id="Shape" fill="#333333"></path>
<path d="M56,7.4 L63,7.4 L63,10.4 L56,10.4 L56,18.4 C56,19.3 56.1,20 56.2,20.6 C56.3,21.2 56.5,21.6 56.8,22 C57.1,22.3 57.4,22.6 57.8,22.7 C58.2,22.8 58.6,22.9 59.2,22.9 C60.2,22.9 61.3,22.8 61.8,22.6 C62.4,22.4 62.8,22.2 63,22.1 L63.6,24.8 C63.3,25 62.7,25.2 61.9,25.4 C61.1,25.6 60.2,25.8 59.1,25.8 C57.9,25.8 56.9,25.6 56.1,25.3 C55.3,25 54.7,24.5 54.2,23.9 C53.7,23.3 53.4,22.5 53.2,21.6 C53,20.7 52.9,19.6 52.9,18.4 L52.9,2.4 L55.9,1.8 L55.9,7.4 L56,7.4 Z" id="Shape" fill="#333333"></path>
<path d="M67,25.4 L67,1.2 L70,0.6 L70,7.8 C70.6,7.6 71.2,7.4 71.8,7.3 C72.5,7.2 73.2,7.1 73.8,7.1 C75.2,7.1 76.1,7.3 77.1,7.7 C78,8.1 78.9,8.7 79.4,9.4 C80,10.1 80.4,11 80.6,12 C80.8,13 80.9,14.1 80.9,15.3 L80.9,25.4 L77.9,25.4 L77.9,16 C77.9,14.9 77.8,14 77.7,13.2 C77.6,12.4 77.3,11.8 77,11.3 C76.7,10.8 76.2,10.5 75.6,10.2 C75,10 74.6,9.9 73.7,9.9 C73.4,9.9 72.7,9.9 72.3,10 C71.9,10 71.6,10.1 71.2,10.2 C70.9,10.3 70.6,10.3 70.3,10.4 C70,10.5 69.9,10.5 69.8,10.6 L69.8,25.5 L67,25.5 L67,25.4 Z" id="Shape" fill="#333333"></path>
<path d="M86.6,4.2 C86,4.2 85.5,4 85.1,3.6 C84.7,3.2 84.5,2.7 84.5,2.1 C84.5,1.5 84.7,0.9 85.1,0.6 C85.5,0.2 86,0 86.6,0 C87.2,0 87.7,0.2 88.1,0.6 C88.5,1 88.7,1.5 88.7,2.1 C88.7,2.7 88.5,3.3 88.1,3.6 C87.7,4 87.2,4.2 86.6,4.2 L86.6,4.2 Z M88,25.4 L85,25.4 L85,7.4 L88,7.4 L88,25.4 Z" id="Shape" fill="#333333"></path>
<path d="M92,8 C92.7,7.8 93.5,7.6 94.7,7.4 C95.9,7.2 96.5,7.1 98.1,7.1 C99.5,7.1 101.2,7.3 102.1,7.7 C103,8.1 103.8,8.7 104.4,9.4 C105,10.1 105.4,11 105.6,12 C105.8,13 105.9,14.1 105.9,15.3 L105.9,25.4 L102.9,25.4 L102.9,16 C102.9,14.9 102.8,14 102.7,13.2 C102.6,12.4 102.3,11.8 102,11.3 C101.7,10.8 101.2,10.5 100.6,10.2 C100,10 98.9,9.9 98,9.9 L97.4,9.9 C97,9.9 96.7,10 96.3,10 C96,10 95.7,10.1 95.5,10.1 C95.2,10.1 95,10.2 94.9,10.2 L94.9,25.3 L91.9,25.3 L91.9,8 L92,8 Z" id="Shape" fill="#333333"></path>
<path d="M116.2,15.5 C116.9,16 117.6,16.7 118.4,17.5 C119.2,18.3 119.9,19.1 120.7,20 C121.4,20.9 122.2,21.8 122.8,22.8 C123.5,23.7 124,24.6 124.5,25.4 L120.7,25.4 C120.2,24.6 119.7,23.8 119,22.9 C118.4,22.1 117.7,21.3 117,20.5 C116.3,19.7 115.6,19 114.9,18.4 C114.2,17.8 113.6,17.2 112.9,16.8 L112.9,25.4 L109.9,25.4 L109.9,1.2 L112.9,0.6 L112.9,15 C113.5,14.4 114,13.8 114.7,13.2 C115.4,12.5 116,11.9 116.7,11.2 C117.3,10.5 118,9.9 118.5,9.2 C119.1,8.6 119.6,8 120,7.5 L123.8,7.5 C123.3,8.1 122.7,8.7 122.1,9.4 C121.5,10.1 120.8,10.8 120.2,11.5 C119.5,12.2 118.9,12.9 118.2,13.6 C117.4,14.2 116.8,14.9 116.2,15.5" id="Shape" fill="#333333"></path>
<g id="Group" transform="translate(15.000000, 1.000000)" fill="#333333">
<path d="M1.7,2.4 C14.8,-0.3 22.7,11.4 29.6,20.6 C32.1,23.9 34.7,26.9 38.5,28.8 C43,31 48.3,30.8 53.1,30.3 C53.9,30.2 56.6,28.9 54.5,29.1 C48.3,29.7 42.4,29.2 37.5,25.1 C33.8,22 31.3,17.6 28.3,14 C25.1,10.1 21.7,6.1 17.5,3.3 C12.9,0.3 7.4,0.2 2.3,1.3 C1.1,1.5 -0.5,2.9 1.7,2.4" id="Shape"></path>
<polygon id="Shape" points="23 24.4 19.7 24.4 32.3 6.4 35.6 6.4"></polygon>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

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

View File

@ -0,0 +1,121 @@
"""
Export module for coverting MISP events into Nexthink NXQL queries.
Source: https://github.com/HacknowledgeCH/misp-modules/blob/master/misp_modules/modules/export_mod/nexthinkexport.py
Config['Period'] : allows to define period over witch to look for IOC from now (15m, 1d, 2w, 30d, ...), see Nexthink data model documentation
"""
import base64
import json
misperrors = {"error": "Error"}
types_to_use = ['sha1', 'sha256', 'md5', 'domain']
userConfig = {
}
moduleconfig = ["Period"]
inputSource = ['event']
outputFileExtension = 'nxql'
responseType = 'application/txt'
moduleinfo = {'version': '1.0', 'author': 'Julien Bachmann, Hacknowledge',
'description': 'Nexthink NXQL query export module',
'module-type': ['export']}
def handle_sha1(value, period):
query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time)))
(from (binary user device execution)
(where binary (eq sha1 (sha1 %s)))
(between now-%s now))
(limit 1000)
''' % (value, period)
return query.replace('\n', ' ')
def handle_sha256(value, period):
query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time)))
(from (binary user device execution)
(where binary (eq sha256 (sha256 %s)))
(between now-%s now))
(limit 1000)
''' % (value, period)
return query.replace('\n', ' ')
def handle_md5(value, period):
query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time)))
(from (binary user device execution)
(where binary (eq hash (md5 %s)))
(between now-%s now))
(limit 1000)
''' % (value, period)
return query.replace('\n', ' ')
def handle_domain(value, period):
query = '''select ((device name) (device (name last_ip_address)) (user name)(user department) (binary executable_name)(binary application_name)(binary description)(binary application_category)(binary (executable_name version)) (binary #"Suspicious binary")(binary first_seen)(binary last_seen)(binary threat_level)(binary hash) (binary paths)
(destination name)(domain name) (domain domain_category)(domain hosting_country)(domain protocol)(domain threat_level) (port port_number)(web_request incoming_traffic)(web_request outgoing_traffic))
(from (web_request device user binary executable destination domain port)
(where domain (eq name(string %s)))
(between now-%s now))
(limit 1000)
''' % (value, period)
return query.replace('\n', ' ')
handlers = {
'sha1': handle_sha1,
'sha256': handle_sha256,
'md5': handle_md5,
'domain': handle_domain
}
def handler(q=False):
if q is False:
return False
r = {'results': []}
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