From 108cae1051c6cdd993fa26241309746b4c6cd4d1 Mon Sep 17 00:00:00 2001 From: Christophe Vandeplas Date: Fri, 24 May 2019 17:06:07 +0300 Subject: [PATCH] new: [transform] new object to relations transform + reverse relations --- publish_to_pip.sh | 3 +- setup.py | 2 +- .../transforms/attributetoevent.py | 2 +- src/MISP_maltego/transforms/common/util.py | 39 ++++++++++++------- .../transforms/eventtoattributes.py | 26 ++++++++++++- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/publish_to_pip.sh b/publish_to_pip.sh index 62756bf..3b87c40 100644 --- a/publish_to_pip.sh +++ b/publish_to_pip.sh @@ -1,3 +1,4 @@ #!/bin/bash python3 setup.py sdist bdist_wheel -twine upload dist/* \ No newline at end of file +twine upload dist/* +rm -Rf build diff --git a/setup.py b/setup.py index e194cff..159b47c 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from setuptools import setup, find_packages setup( name='MISP_maltego', author='Christophe Vandeplas', - version='1.3', + version='1.3.2', author_email='christophe@vandeplas.com', maintainer='Christophe Vandeplas', url='https://github.com/MISP/MISP-maltego', diff --git a/src/MISP_maltego/transforms/attributetoevent.py b/src/MISP_maltego/transforms/attributetoevent.py index 703d896..a9756cf 100644 --- a/src/MISP_maltego/transforms/attributetoevent.py +++ b/src/MISP_maltego/transforms/attributetoevent.py @@ -91,7 +91,7 @@ class AttributeToEvent(Transform): if not tag_name: tag_name = request.entity.value events_json = misp.search(controller='events', tags=tag_name, withAttachments=False) - # FIXME make it work with object to event + # standard Entities else: events_json = misp.search(controller='events', values=request.entity.value, withAttachments=False) diff --git a/src/MISP_maltego/transforms/common/util.py b/src/MISP_maltego/transforms/common/util.py index dd401e7..285ccb9 100644 --- a/src/MISP_maltego/transforms/common/util.py +++ b/src/MISP_maltego/transforms/common/util.py @@ -229,7 +229,7 @@ def attribute_to_entity(a, link_label=None, event_tags=[], only_self=False): # LATER : relationships from attributes - not yet supported by MISP yet, but there are references in the datamodel -def object_to_entity(o, link_label=None): +def object_to_entity(o, link_label=None, link_direction=LinkDirection.InputToOutput): # Generate a human readable display-name: # - find the first RequiredOneOf that exists # - if none, use the first RequiredField @@ -277,6 +277,7 @@ def object_to_entity(o, link_label=None): description=o.get('description'), comment=o.get('comment'), link_label=link_label, + link_direction=link_direction, bookmark=Bookmark.Green ) @@ -293,19 +294,29 @@ def object_to_attributes(o, e): for item in attribute_to_entity(a): yield item - # process relationships between objects and attributes - if 'ObjectReference' in o: - for ref in o['ObjectReference']: - # the reference is an Object - if ref.get('Object'): - # get the full object in the event, as our objectReference included does not contain everything we need - sub_object = get_object_in_event(ref['Object']['uuid'], e) - yield object_to_entity(sub_object, link_label=ref['relationship_type']) - # the reference is an Attribute - if ref.get('Attribute'): - ref['Attribute']['event_id'] = ref['event_id'] # LATER remove this ugly workaround - object can't be requested directly from MISP using the uuid, and to find a full object we need the event_id - for item in attribute_to_entity(ref['Attribute'], link_label=ref['relationship_type']): - yield item + +def object_to_relations(o, e): + # process forward and reverse references, so just loop over all the objects of the event + if 'Object' in e['Event']: + for eo in e['Event']['Object']: + if 'ObjectReference' in eo: + for ref in eo['ObjectReference']: + # we have found original object. Expand to the related object and attributes + if eo['uuid'] == o['uuid']: + # the reference is an Object + if ref.get('Object'): + # get the full object in the event, as our objectReference included does not contain everything we need + sub_object = get_object_in_event(ref['Object']['uuid'], e) + yield object_to_entity(sub_object, link_label=ref['relationship_type']) + # the reference is an Attribute + if ref.get('Attribute'): + ref['Attribute']['event_id'] = ref['event_id'] # LATER remove this ugly workaround - object can't be requested directly from MISP using the uuid, and to find a full object we need the event_id + for item in attribute_to_entity(ref['Attribute'], link_label=ref['relationship_type']): + yield item + + # reverse-lookup - this is another objects relating the original object + if ref['referenced_uuid'] == o['uuid']: + yield object_to_entity(eo, link_label=ref['relationship_type'], link_direction=LinkDirection.OutputToInput) def get_object_in_event(uuid, e): diff --git a/src/MISP_maltego/transforms/eventtoattributes.py b/src/MISP_maltego/transforms/eventtoattributes.py index 4828276..591e255 100644 --- a/src/MISP_maltego/transforms/eventtoattributes.py +++ b/src/MISP_maltego/transforms/eventtoattributes.py @@ -2,7 +2,7 @@ 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, tag_matches_note_prefix +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, object_to_relations, tag_matches_note_prefix from canari.maltego.message import LinkStyle @@ -158,7 +158,7 @@ class EventToRelations(EventToTransform): class ObjectToAttributes(Transform): """"Expands an object to its attributes""" input_type = MISPObject - description = 'Expands an Obect to Attributes' + description = 'Expands an Object to Attributes' def do_transform(self, request, response, config): maltego_object = request.entity @@ -169,5 +169,27 @@ class ObjectToAttributes(Transform): for entity in object_to_attributes(o, event_json): if entity: response += entity + for entity in object_to_relations(o, event_json): + if entity: + response += entity + + return response + + +# @EnableDebugWindow +class ObjectToRelations(Transform): + """Expands an object to the relations of the object""" + input_type = MISPObject + description = 'Expands an Object to Relations' + + 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_relations(o, event_json): + if entity: + response += entity return response