diff --git a/.gitignore b/.gitignore index 86b4fe0..e8babde 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ *.egg *.egg-info *.*.swp - +/build/ # Locally genenerated mtz /*.mtz diff --git a/build/lib/MISP_maltego/__init__.py b/build/lib/MISP_maltego/__init__.py deleted file mode 100644 index 6d1d06b..0000000 --- a/build/lib/MISP_maltego/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -__license__ = 'AGPLv3' -__version__ = '0.1' -__author__ = 'Christophe Vandeplas' -__email__ = 'christophe@vandeplas.com' - -__all__ = [ - 'transforms', - 'resources' -] diff --git a/build/lib/MISP_maltego/resources/__init__.py b/build/lib/MISP_maltego/resources/__init__.py deleted file mode 100644 index 01c2c5d..0000000 --- a/build/lib/MISP_maltego/resources/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'etc', - 'images' -] diff --git a/build/lib/MISP_maltego/resources/etc/MISP_maltego.conf b/build/lib/MISP_maltego/resources/etc/MISP_maltego.conf deleted file mode 100644 index 24806b7..0000000 --- a/build/lib/MISP_maltego/resources/etc/MISP_maltego.conf +++ /dev/null @@ -1,10 +0,0 @@ -[MISP_maltego.local] -misp_url = https://url -misp_key = very_secret_key - -misp_verify = True -misp_debug = False - -[MISP_maltego.remote] - -# TODO: put remote transform options here diff --git a/build/lib/MISP_maltego/resources/etc/__init__.py b/build/lib/MISP_maltego/resources/etc/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/MISP_maltego/resources/external/__init__.py b/build/lib/MISP_maltego/resources/external/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/MISP_maltego/resources/images/MISPEvent.png b/build/lib/MISP_maltego/resources/images/MISPEvent.png deleted file mode 100644 index ddf470a..0000000 Binary files a/build/lib/MISP_maltego/resources/images/MISPEvent.png and /dev/null differ diff --git a/build/lib/MISP_maltego/resources/images/MISPObject.png b/build/lib/MISP_maltego/resources/images/MISPObject.png deleted file mode 100644 index 0870390..0000000 Binary files a/build/lib/MISP_maltego/resources/images/MISPObject.png and /dev/null differ diff --git a/build/lib/MISP_maltego/resources/images/__init__.py b/build/lib/MISP_maltego/resources/images/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/MISP_maltego/resources/maltego/__init__.py b/build/lib/MISP_maltego/resources/maltego/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/MISP_maltego/resources/maltego/entities.mtz b/build/lib/MISP_maltego/resources/maltego/entities.mtz deleted file mode 100644 index d52217b..0000000 Binary files a/build/lib/MISP_maltego/resources/maltego/entities.mtz and /dev/null differ diff --git a/build/lib/MISP_maltego/transforms/__init__.py b/build/lib/MISP_maltego/transforms/__init__.py deleted file mode 100644 index 6ac2922..0000000 --- a/build/lib/MISP_maltego/transforms/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'common' -] diff --git a/build/lib/MISP_maltego/transforms/attributetoevent.py b/build/lib/MISP_maltego/transforms/attributetoevent.py deleted file mode 100644 index 4f72663..0000000 --- a/build/lib/MISP_maltego/transforms/attributetoevent.py +++ /dev/null @@ -1,84 +0,0 @@ -from canari.maltego.entities import Hash, Domain, IPv4Address, URL, DNSName, AS, Website, NSRecord, PhoneNumber, EmailAddress, File -from canari.maltego.transform import Transform -# from canari.framework import EnableDebugWindow -from MISP_maltego.transforms.common.entities import MISPEvent -from MISP_maltego.transforms.common.util import get_misp_connection - -__author__ = 'Christophe Vandeplas' -__copyright__ = 'Copyright 2018, MISP_maltego Project' -__credits__ = [] - -__license__ = 'AGPLv3' -__version__ = '0.1' -__maintainer__ = 'Christophe Vandeplas' -__email__ = 'christophe@vandeplas.com' -__status__ = 'Development' - - -# @EnableDebugWindow -class AttributeToEvent(Transform): - # The transform input entity type. - input_type = None - - def do_transform(self, request, response, config): - maltego_misp_attribute = request.entity - misp = get_misp_connection(config) - # misp. - events_json = misp.search(controller='events', values=maltego_misp_attribute.value, withAttachments=False) - for e in events_json['response']: - response += MISPEvent(e['Event']['id'], uuid=e['Event']['uuid'], info=e['Event']['info']) - return response - - def on_terminate(self): - """This method gets called when transform execution is prematurely terminated. It is only applicable for local - transforms. It can be excluded if you don't need it.""" - pass - - -class HashToEvent(AttributeToEvent): - input_type = Hash - - -class DomainToEvent(AttributeToEvent): - input_type = Domain - - -class IPv4AddressToEvent(AttributeToEvent): - display_name = 'IPv4AddressToEvent' - input_type = IPv4Address - - -class URLToEvent(AttributeToEvent): - display_name = 'URLToEvent' - input_type = URL - - -class DNSNameToEvent(AttributeToEvent): - display_name = 'DNSNameToEvent' - input_type = DNSName - - -class ASToEvent(AttributeToEvent): - display_name = 'ASToEvent' - input_type = AS - - -class WebsiteToEvent(AttributeToEvent): - input_type = Website - - -class NSRecordToEvent(AttributeToEvent): - display_name = 'NSRecordToEvent' - input_type = NSRecord - - -class PhoneNumberToEvent(AttributeToEvent): - input_type = PhoneNumber - - -class EmailAddressToEvent(AttributeToEvent): - input_type = EmailAddress - - -class FileToEvent(AttributeToEvent): - input_type = File diff --git a/build/lib/MISP_maltego/transforms/common/__init__.py b/build/lib/MISP_maltego/transforms/common/__init__.py deleted file mode 100644 index 943b99a..0000000 --- a/build/lib/MISP_maltego/transforms/common/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'entities', - 'util' -] diff --git a/build/lib/MISP_maltego/transforms/common/entities.py b/build/lib/MISP_maltego/transforms/common/entities.py deleted file mode 100644 index ae1d577..0000000 --- a/build/lib/MISP_maltego/transforms/common/entities.py +++ /dev/null @@ -1,57 +0,0 @@ -from canari.maltego.message import Entity, IntegerEntityField, StringEntityField, MatchingRule - -__author__ = 'Christophe Vandeplas' -__copyright__ = 'Copyright 2018, MISP_maltego Project' -__credits__ = [] - -__license__ = 'AGPLv3' -__version__ = '0.1' -__maintainer__ = 'Christophe Vandeplas' -__email__ = 'christophe@vandeplas.com' -__status__ = 'Development' - -__all__ = [ - 'MISPEvent', - 'MISPObject', - 'MISPGalaxy' -] - - -class MISPEvent(Entity): - _category_ = 'MISP' - _namespace_ = 'misp' - - icon_url = 'file://MISP_maltego/resources/images/MISPEvent.png' - uuid = StringEntityField('uuid', display_name='UUID', matching_rule=MatchingRule.Loose) - id = IntegerEntityField('id', display_name='id', is_value=True) - # date = DateEntityField('type.date', display_name='Event date') - info = StringEntityField('info', display_name='Event info', matching_rule=MatchingRule.Loose) - # threat_level = EnumEntityField('type.enum', choices=['Undefined', 'Low', 'Medium', 'High'], display_name='Threat Level') - # analysis = EnumEntityField('type.enum', choices=['Initial', 'Ongoing', 'Completed']) - # org = StringEntityField('type.str', display_name='Organisation') - - -class MISPObject(Entity): - _category_ = 'MISP' - _namespace_ = 'misp' - - icon_url = 'file://MISP_maltego/resources/images/MISPObject.png' - uuid = StringEntityField('uuid', display_name='UUID') - event_id = IntegerEntityField('event_id', display_name='Event ID') - name = StringEntityField('name', display_name='Name', is_value=True) - meta_category = StringEntityField('meta_category', display_name='Meta Category') - description = StringEntityField('description', display_name='Description') - comment = StringEntityField('comment', display_name='Comment') - - -class MISPGalaxy(Entity): - _category_ = 'MISP' - _namespace_ = 'misp' - - uuid = StringEntityField('uuid', display_name='UUID') - name = StringEntityField('name', display_name='Name', is_value=True) - description = StringEntityField('description', display_name='Description') - cluster_type = StringEntityField('galaxy_type', display_name='Type') - cluster_value = StringEntityField('value', display_name='Value') - synonyms = StringEntityField('synonyms', display_name='Synonyms') - tag_name = StringEntityField('tag_name', display_name='Tag') diff --git a/build/lib/MISP_maltego/transforms/common/util.py b/build/lib/MISP_maltego/transforms/common/util.py deleted file mode 100644 index e1644b8..0000000 --- a/build/lib/MISP_maltego/transforms/common/util.py +++ /dev/null @@ -1,288 +0,0 @@ -from canari.maltego.entities import Unknown, Hash, Domain, IPv4Address, URL, DNSName, AS, Website, NSRecord, PhoneNumber, EmailAddress, File, Person, Hashtag -from MISP_maltego.transforms.common.entities import MISPEvent, MISPObject, MISPGalaxy -from canari.maltego.message import UIMessageType, UIMessage, Label -from pymisp import PyMISP -import json -import tempfile -import os - - -# mapping_maltego_to_misp = { -# 'maltego.Hash': ['md5', 'sha1', 'sha256', 'sha224', 'sha384', 'sha512', 'sha512/224', 'sha512/256'], -# # 'maltego.Banner': [''], -# # 'maltego.WebTitle': [''], -# 'maltego.Domain': ['domain', 'hostname'], -# # 'maltego.Netblock': [''], -# # 'maltego.MXRecord': [''], -# 'maltego.IPv4Address': ['ip-src', 'ip-dst', 'ip'], -# 'maltego.URL': ['url', 'uri'], -# 'maltego.DNSName': ['domain', 'hostname'], -# 'maltego.AS': ['AS'], -# # 'maltego.UniqueIdentifier': [''], -# 'maltego.Website': ['domain', 'hostname'], -# 'maltego.NSRecord': ['domain', 'hostname'], -# # 'maltego.Document': [''], -# 'maltego.PhoneNumber': ['phone-number'], -# 'maltego.EmailAddress': ['email-src', 'email-dst'], -# # 'maltego.Image': [''], # LATER file image -# # 'maltego.Phrase': [''], -# 'maltego.File': ['filename'], -# # 'maltego.Person': [''], -# # 'maltego.Sentiment': [''], -# # 'maltego.Alias': [''], -# # 'maltego.GPS': [''], -# # 'maltego.CircularArea': [''], -# # 'maltego.NominatimLocation': [''], -# # 'maltego.Location': [''], -# # 'maltego.Device': [''], -# # 'maltego.affiliation.Flickr': [''], -# # 'maltego.FacebookObject': [''], -# # 'maltego.hashtag': [''], -# # 'maltego.affiliation.Twitter': [''], -# # 'maltego.affiliation.Facebook': [''], -# # 'maltego.Twit': [''], -# # 'maltego.Port': [''], -# # 'maltego.Service': [''], -# # 'maltego.BuiltWithTechnology': [''], -# } - -# mapping_misp_to_maltego = {} -# for key, vals in mapping_maltego_to_misp.items(): -# for val in vals: -# if val not in mapping_misp_to_maltego: -# mapping_misp_to_maltego[val] = [] -# mapping_misp_to_maltego[val].append(key) - -mapping_misp_to_maltego = { - 'AS': [AS], - 'domain': [Domain, NSRecord, Website, DNSName], - 'email-dst': [EmailAddress], - 'email-src': [EmailAddress], - 'filename': [File], - 'hostname': [Website, NSRecord, Domain, DNSName], - 'ip': [IPv4Address], - 'ip-dst': [IPv4Address], - 'ip-src': [IPv4Address], - 'md5': [Hash], - 'phone-number': [PhoneNumber], - 'sha1': [Hash], - 'sha224': [Hash], - 'sha256': [Hash], - 'sha384': [Hash], - 'sha512': [Hash], - 'sha512/224': [Hash], - 'sha512/256': [Hash], - 'uri': [URL], - 'url': [URL], - - 'whois-registrant-email': [EmailAddress], - - # object mappings - 'nameserver': [NSRecord], - # FIXME add more object mappings - # custom types created internally for technical reasons - # 'rekey_value': [Unknown] -} - - -def get_misp_connection(config): - if config['MISP_maltego.local.misp_verify'] in ['True', 'true', 1, 'yes', 'Yes']: - misp_verify = True - else: - misp_verify = False - if config['MISP_maltego.local.misp_debug'] in ['True', 'true', 1, 'yes', 'Yes']: - misp_debug = True - else: - misp_debug = False - return PyMISP(config['MISP_maltego.local.misp_url'], config['MISP_maltego.local.misp_key'], misp_verify, 'json', misp_debug) - - -def entity_obj_to_entity(entity_obj, v, t, **kwargs): - if entity_obj == Hash: - return entity_obj(v, _type=t, **kwargs) # FIXME type is conflicting with type of Entity, Report this as bug see line 326 /usr/local/lib/python3.5/dist-packages/canari/maltego/entities.py - - return entity_obj(v, **kwargs) - - -def attribute_to_entity(a): - # prepare some attributes to a better form - a['data'] = None # empty the file content as we really don't need this here # FIXME feature request for misp.get_event() to not get attachment content - if a['type'] == 'malware-sample': - a['type'] = 'filename|md5' - if a['type'] == 'regkey|value': - a['type'] = 'regkey' - # FIXME regkey|value => needs to be a special non-combined object - - # attribute is from an object, and a relation gives better understanding of the type of attribute - if a.get('object_relation') and mapping_misp_to_maltego.get(a['object_relation']): - entity_obj = mapping_misp_to_maltego[a['object_relation']][0] - yield entity_obj(a['value'], labels=[Label('comment', a['comment'])]) - - # combined attributes - elif '|' in a['type']: - t_1, t_2 = a['type'].split('|') - v_1, v_2 = a['value'].split('|') - if t_1 in mapping_misp_to_maltego: - entity_obj = mapping_misp_to_maltego[t_1][0] - labels = [Label('comment', a['comment'])] - if entity_obj == File: - labels.append(Label('hash', v_2)) - yield entity_obj_to_entity(entity_obj, v_1, t_1, labels=labels) # TODO change the comment to include the second part of the regkey - else: - yield UIMessage("Type {} of combined type {} not supported for attribute: {}".format(t_1, a['type'], a), type=UIMessageType.Inform) - if t_2 in mapping_misp_to_maltego: - entity_obj = mapping_misp_to_maltego[t_2][0] - labels = [Label('comment', a['comment'])] - if entity_obj == Hash: - labels.append(Label('filename', v_1)) - yield entity_obj_to_entity(entity_obj, v_2, t_2, labels=labels) # TODO change the comment to include the first part of the regkey - else: - yield UIMessage("Type {} of combined type {} not supported for attribute: {}".format(t_2, a['type'], a), type=UIMessageType.Inform) - - # normal attributes - elif a['type'] in mapping_misp_to_maltego: - entity_obj = mapping_misp_to_maltego[a['type']][0] - yield entity_obj_to_entity(entity_obj, a['value'], a['type'], labels=[Label('comment', a['comment'])]) - - # not supported in our maltego mapping - else: - yield Unknown(a['value'], type=a['type'], labels=[Label('comment', a['comment'])]) - yield UIMessage("Type {} not fully supported for attribute: {}".format(a['type'], a), type=UIMessageType.Inform) - - if 'Galaxy' in a: - for g in a['Galaxy']: - for c in g['GalaxyCluster']: - yield galaxycluster_to_entity(c) - - if 'Tag' in a: - for t in a['Tag']: - # ignore all misp-galaxies - if t['name'].startswith('misp-galaxy'): - continue - yield Hashtag(t['name']) - - -def object_to_entity(o): - return MISPObject( - o['name'], - uuid=o['uuid'], - event_id=int(o['event_id']), - meta_category=o.get('meta_category'), - description=o['description'], - comment=o['comment'] - ) - - -def object_to_attributes(o): - # first process attributes from an object that belong together (eg: first-name + last-name), and remove them from the list - if o['name'] == 'person': - first_name = get_attribute_in_object(o, 'first-name', drop=True).get('value') - last_name = get_attribute_in_object(o, 'last-name', drop=True).get('value') - yield entity_obj_to_entity(Person, ' '.join([first_name, last_name]).strip(), 'person', lastname=last_name, firstnames=first_name) - - # process normal attributes - for a in o['Attribute']: - for item in attribute_to_entity(a): - yield item - - -def get_attribute_in_object(o, attribute_type, drop=False): - '''Gets the first attribute of a specific type within an object''' - found_attribute = {'value': ''} - for i, a in enumerate(o['Attribute']): - if a['type'] == attribute_type: - found_attribute = a.copy() - if drop: # drop the attribute from the object - o['Attribute'].pop(i) - break - return found_attribute - - -def event_to_entity(e): - return MISPEvent(e['Event']['id'], uuid=e['Event']['uuid'], info=e['Event']['info']) - - -def galaxycluster_to_entity(c, link_label=None): - # print(json.dumps(c, sort_keys=True, indent=4)) - if c['meta'].get('synonyms'): - synonyms = ', '.join(c['meta']['synonyms']) - else: - synonyms = '' - return MISPGalaxy( - '{}\n{}'.format(c['type'], c['value']), - uuid=c['uuid'], - description=c['description'], - cluster_type=c['type'], - cluster_value=c['value'], - synonyms=synonyms, - tag_name=c['tag_name'], - link_label=link_label - ) - - -# FIXME this uses the galaxies from github as the MISP web UI does not fully support the Galaxies in the webui. -# See https://github.com/MISP/MISP/issues/3801 -galaxy_archive_url = 'https://github.com/MISP/misp-galaxy/archive/master.zip' -local_path_root = os.path.join(tempfile.gettempdir(), 'MISP-maltego') -local_path_uuid_mapping = os.path.join(local_path_root, 'MISP_maltego_galaxy_mapping.json') -local_path_clusters = os.path.join(local_path_root, 'misp-galaxy-master', 'clusters') -galaxy_cluster_uuids = None - - -def galaxy_update_local_copy(force=False): - import io - import json - import os - import requests - from zipfile import ZipFile - - # FIXME put some aging and automatic re-downloading - if not os.path.exists(local_path_root): - os.mkdir(local_path_root) - force = True - - if force: - # download the latest zip of the public galaxy - resp = requests.get(galaxy_archive_url) - zf = ZipFile(io.BytesIO(resp.content)) - zf.extractall(local_path_root) - zf.close() - - # generate the uuid mapping and save it to a file - galaxies_fnames = [] - for f in os.listdir(local_path_clusters): - if '.json' in f: - galaxies_fnames.append(f) - galaxies_fnames.sort() - - cluster_uuids = {} - for galaxy_fname in galaxies_fnames: - fullPathClusters = os.path.join(local_path_clusters, galaxy_fname) - with open(fullPathClusters) as fp: - galaxy = json.load(fp) - for cluster in galaxy['values']: - # print(cluster['uuid']) - if 'uuid' not in cluster: - continue - # keep track of the cluster, but also enhance it to look like the cluster we receive when accessing the web. - cluster_uuids[cluster['uuid']] = cluster - cluster_uuids[cluster['uuid']]['type'] = galaxy['type'] - cluster_uuids[cluster['uuid']]['tag_name'] = 'misp-galaxy:{}="{}"'.format(galaxy['type'], cluster['value']) - - with open(local_path_uuid_mapping, 'w') as f: - json.dump(cluster_uuids, f, sort_keys=True, indent=4) - - -def galaxy_load_cluster_mapping(): - galaxy_update_local_copy() - with open(local_path_uuid_mapping, 'r') as f: - cluster_uuids = json.load(f) - return cluster_uuids - - -def get_galaxy_cluster(uuid): - global galaxy_cluster_uuids - if not galaxy_cluster_uuids: - galaxy_cluster_uuids = galaxy_load_cluster_mapping() - - return galaxy_cluster_uuids.get(uuid) diff --git a/build/lib/MISP_maltego/transforms/eventtoattributes.py b/build/lib/MISP_maltego/transforms/eventtoattributes.py deleted file mode 100644 index 0c45ee1..0000000 --- a/build/lib/MISP_maltego/transforms/eventtoattributes.py +++ /dev/null @@ -1,77 +0,0 @@ -from canari.maltego.entities import Hashtag -from canari.maltego.transform import Transform -# from canari.framework import EnableDebugWindow -from MISP_maltego.transforms.common.entities import MISPEvent, MISPObject -from MISP_maltego.transforms.common.util import get_misp_connection, attribute_to_entity, event_to_entity, galaxycluster_to_entity, object_to_entity, object_to_attributes -import json - -__author__ = 'Christophe Vandeplas' -__copyright__ = 'Copyright 2018, MISP_maltego Project' -__credits__ = [] - -__license__ = 'AGPLv3' -__version__ = '0.1' -__maintainer__ = 'Christophe Vandeplas' -__email__ = 'christophe@vandeplas.com' -__status__ = 'Development' - - -# @EnableDebugWindow -class EventToAttributes(Transform): - """Expands an event to attributes, objects, tags and galaxies.""" - - # The transform input entity type. - input_type = MISPEvent - description = 'Expands an Event to Attributes, Tags, Galaxies and related events' - - def do_transform(self, request, response, config): - maltego_misp_event = request.entity - # print(dir(maltego_misp_event)) - misp = get_misp_connection(config) - event_json = misp.get_event(maltego_misp_event.id) # FIXME get it without attachments - # print(json.dumps(event_json, sort_keys=True, indent=4)) - if not event_json.get('Event'): - return response - for e in event_json['Event']['RelatedEvent']: - response += event_to_entity(e) - for a in event_json['Event']["Attribute"]: - for entity in attribute_to_entity(a): - if entity: - response += entity - for o in event_json['Event']['Object']: - # LATER unfortunately we cannot automatically expand the objects - response += object_to_entity(o) - for g in event_json['Event']['Galaxy']: - for c in g['GalaxyCluster']: - response += galaxycluster_to_entity(c) - if 'Tag' in event_json['Event']: - for t in event_json['Event']['Tag']: - # ignore all misp-galaxies - if t['name'].startswith('misp-galaxy'): - continue - response += Hashtag(t['name']) - return response - - def on_terminate(self): - """This method gets called when transform execution is prematurely terminated. It is only applicable for local - transforms. It can be excluded if you don't need it.""" - pass - - -# @EnableDebugWindow -class ObjectToAttributes(Transform): - """"Expands an object to its attributes""" - input_type = MISPObject - description = 'Expands an Obect to Attributes' - - def do_transform(self, request, response, config): - maltego_object = request.entity - misp = get_misp_connection(config) - event_json = misp.get_event(maltego_object.event_id) - for o in event_json['Event']['Object']: - if o['uuid'] == maltego_object.uuid: - for entity in object_to_attributes(o): - if entity: - response += entity - - return response diff --git a/build/lib/MISP_maltego/transforms/galaxytoevent.py b/build/lib/MISP_maltego/transforms/galaxytoevent.py deleted file mode 100644 index 8bf105a..0000000 --- a/build/lib/MISP_maltego/transforms/galaxytoevent.py +++ /dev/null @@ -1,63 +0,0 @@ -from canari.maltego.transform import Transform -# from canari.framework import EnableDebugWindow -from MISP_maltego.transforms.common.entities import MISPEvent, MISPGalaxy -from MISP_maltego.transforms.common.util import get_misp_connection, galaxycluster_to_entity, get_galaxy_cluster -from canari.maltego.message import UIMessageType, UIMessage - - -__author__ = 'Christophe Vandeplas' -__copyright__ = 'Copyright 2018, MISP_maltego Project' -__credits__ = [] - -__license__ = 'AGPLv3' -__version__ = '0.1' -__maintainer__ = 'Christophe Vandeplas' -__email__ = 'christophe@vandeplas.com' -__status__ = 'Development' - - -# @EnableDebugWindow -class GalaxyToEvents(Transform): - """Expands a Galaxy to multiple MISP Events.""" - - # The transform input entity type. - input_type = MISPGalaxy - - def do_transform(self, request, response, config): - maltego_misp_galaxy = request.entity - misp = get_misp_connection(config) - if maltego_misp_galaxy.tag_name: - tag_name = maltego_misp_galaxy.tag_name - else: - tag_name = maltego_misp_galaxy.value - events_json = misp.search(controller='events', tags=tag_name, withAttachments=False) - for e in events_json['response']: - response += MISPEvent(e['Event']['id'], uuid=e['Event']['uuid'], info=e['Event']['info']) - return response - - def on_terminate(self): - """This method gets called when transform execution is prematurely terminated. It is only applicable for local - transforms. It can be excluded if you don't need it.""" - pass - - -# @EnableDebugWindow -class GalaxyToRelations(Transform): - """Expans a Galaxy to related Galaxies and Clusters""" - input_type = MISPGalaxy - - def do_transform(self, request, response, config): - maltego_misp_galaxy = request.entity - - # # FIXME if not found, send message to user to update, while noting local galaxies are not supported yet - current_cluster = get_galaxy_cluster(maltego_misp_galaxy.uuid) - if not current_cluster: - response += UIMessage("Galaxy Cluster UUID not in local mapping. Please update local cache; or non-public UUID", type=UIMessageType.Inform) - return response - - if 'related' in current_cluster: - for related in current_cluster['related']: - related_cluster = get_galaxy_cluster(related['dest-uuid']) - if related_cluster: - response += galaxycluster_to_entity(related_cluster, link_label=related['type']) - return response