mirror of https://github.com/MISP/MISP-maltego
new: [transform] new object to relations transform + reverse relations
parent
98531ba854
commit
108cae1051
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
python3 setup.py sdist bdist_wheel
|
python3 setup.py sdist bdist_wheel
|
||||||
twine upload dist/*
|
twine upload dist/*
|
||||||
|
rm -Rf build
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -5,7 +5,7 @@ from setuptools import setup, find_packages
|
||||||
setup(
|
setup(
|
||||||
name='MISP_maltego',
|
name='MISP_maltego',
|
||||||
author='Christophe Vandeplas',
|
author='Christophe Vandeplas',
|
||||||
version='1.3',
|
version='1.3.2',
|
||||||
author_email='christophe@vandeplas.com',
|
author_email='christophe@vandeplas.com',
|
||||||
maintainer='Christophe Vandeplas',
|
maintainer='Christophe Vandeplas',
|
||||||
url='https://github.com/MISP/MISP-maltego',
|
url='https://github.com/MISP/MISP-maltego',
|
||||||
|
|
|
@ -91,7 +91,7 @@ class AttributeToEvent(Transform):
|
||||||
if not tag_name:
|
if not tag_name:
|
||||||
tag_name = request.entity.value
|
tag_name = request.entity.value
|
||||||
events_json = misp.search(controller='events', tags=tag_name, withAttachments=False)
|
events_json = misp.search(controller='events', tags=tag_name, withAttachments=False)
|
||||||
# FIXME make it work with object to event
|
|
||||||
# standard Entities
|
# standard Entities
|
||||||
else:
|
else:
|
||||||
events_json = misp.search(controller='events', values=request.entity.value, withAttachments=False)
|
events_json = misp.search(controller='events', values=request.entity.value, withAttachments=False)
|
||||||
|
|
|
@ -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
|
# 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:
|
# Generate a human readable display-name:
|
||||||
# - find the first RequiredOneOf that exists
|
# - find the first RequiredOneOf that exists
|
||||||
# - if none, use the first RequiredField
|
# - if none, use the first RequiredField
|
||||||
|
@ -277,6 +277,7 @@ def object_to_entity(o, link_label=None):
|
||||||
description=o.get('description'),
|
description=o.get('description'),
|
||||||
comment=o.get('comment'),
|
comment=o.get('comment'),
|
||||||
link_label=link_label,
|
link_label=link_label,
|
||||||
|
link_direction=link_direction,
|
||||||
bookmark=Bookmark.Green
|
bookmark=Bookmark.Green
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -293,19 +294,29 @@ def object_to_attributes(o, e):
|
||||||
for item in attribute_to_entity(a):
|
for item in attribute_to_entity(a):
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
# process relationships between objects and attributes
|
|
||||||
if 'ObjectReference' in o:
|
def object_to_relations(o, e):
|
||||||
for ref in o['ObjectReference']:
|
# process forward and reverse references, so just loop over all the objects of the event
|
||||||
# the reference is an Object
|
if 'Object' in e['Event']:
|
||||||
if ref.get('Object'):
|
for eo in e['Event']['Object']:
|
||||||
# get the full object in the event, as our objectReference included does not contain everything we need
|
if 'ObjectReference' in eo:
|
||||||
sub_object = get_object_in_event(ref['Object']['uuid'], e)
|
for ref in eo['ObjectReference']:
|
||||||
yield object_to_entity(sub_object, link_label=ref['relationship_type'])
|
# we have found original object. Expand to the related object and attributes
|
||||||
# the reference is an Attribute
|
if eo['uuid'] == o['uuid']:
|
||||||
if ref.get('Attribute'):
|
# the reference is an Object
|
||||||
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
|
if ref.get('Object'):
|
||||||
for item in attribute_to_entity(ref['Attribute'], link_label=ref['relationship_type']):
|
# get the full object in the event, as our objectReference included does not contain everything we need
|
||||||
yield item
|
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):
|
def get_object_in_event(uuid, e):
|
||||||
|
|
|
@ -2,7 +2,7 @@ from canari.maltego.entities import Hashtag
|
||||||
from canari.maltego.transform import Transform
|
from canari.maltego.transform import Transform
|
||||||
# from canari.framework import EnableDebugWindow
|
# from canari.framework import EnableDebugWindow
|
||||||
from MISP_maltego.transforms.common.entities import MISPEvent, MISPObject
|
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
|
from canari.maltego.message import LinkStyle
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ class EventToRelations(EventToTransform):
|
||||||
class ObjectToAttributes(Transform):
|
class ObjectToAttributes(Transform):
|
||||||
""""Expands an object to its attributes"""
|
""""Expands an object to its attributes"""
|
||||||
input_type = MISPObject
|
input_type = MISPObject
|
||||||
description = 'Expands an Obect to Attributes'
|
description = 'Expands an Object to Attributes'
|
||||||
|
|
||||||
def do_transform(self, request, response, config):
|
def do_transform(self, request, response, config):
|
||||||
maltego_object = request.entity
|
maltego_object = request.entity
|
||||||
|
@ -169,5 +169,27 @@ class ObjectToAttributes(Transform):
|
||||||
for entity in object_to_attributes(o, event_json):
|
for entity in object_to_attributes(o, event_json):
|
||||||
if entity:
|
if entity:
|
||||||
response += 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
|
return response
|
||||||
|
|
Loading…
Reference in New Issue