mirror of https://github.com/MISP/MISP-maltego
new: [entities] Split MISPGalaxy: Threat Actor, Attack Technique , Software
parent
dd7c8e2460
commit
eb80120d2d
|
@ -19,8 +19,10 @@ These instructions have been tested on Ubuntu 18.04 LTS, but should be similar o
|
|||
MISP-Maltego tries to use as much as possible the default Paterva entities, or the most popular from the community. It however comes with a few custom entities:
|
||||
* **MISPEvent**: A representation of an *Event* on MISP, containing *Attributes* (MISP) / *Entities* (Maltego)
|
||||
* **MISPObject**: A way to group associated attributes in a structured way.
|
||||
* **MISPGalaxy**: A *Tag* containing much more metadata. Please refer to the [MISP Galaxy
|
||||
](https://github.com/MISP/misp-galaxy) for more information. **MITRE ATT&CK** is for example completely available through MISPGalaxy entities (see use-cases for an example)
|
||||
* **MISPGalaxy**: A *Tag* containing much more metadata. Please refer to the [MISP Galaxy](https://github.com/MISP/misp-galaxy) for more information. **MITRE ATT&CK** is for example completely available through MISPGalaxy entities (see use-cases for an example)
|
||||
* **Attack Technique**: Attack patterns or techniques, see [MITRE ATT&CK](https://attack.mitre.org/techniques/enterprise/) for more information.
|
||||
* **Threat Actor**: Threat actor or intrusion sets.
|
||||
* **Software**: Software is a generic term for custom or commercial code, operating system utilities, open-source software, or other tools used to conduct behavior modeled in ATT&CK.
|
||||
|
||||
# Use Cases
|
||||
## Transform on existing data
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 379 KiB After Width: | Height: | Size: 80 KiB |
2
setup.py
2
setup.py
|
@ -6,7 +6,7 @@ setup(
|
|||
name='MISP_maltego',
|
||||
author='Christophe Vandeplas',
|
||||
# also update version in util.py
|
||||
version='1.3.7',
|
||||
version='1.4.0',
|
||||
author_email='christophe@vandeplas.com',
|
||||
maintainer='Christophe Vandeplas',
|
||||
url='https://github.com/MISP/MISP-maltego',
|
||||
|
|
Binary file not shown.
|
@ -13,7 +13,10 @@ __status__ = 'Development'
|
|||
__all__ = [
|
||||
'MISPEvent',
|
||||
'MISPObject',
|
||||
'MISPGalaxy'
|
||||
'MISPGalaxy',
|
||||
'ThreatActor',
|
||||
'Software',
|
||||
'AttackTechnique'
|
||||
]
|
||||
|
||||
|
||||
|
@ -55,3 +58,18 @@ class MISPGalaxy(Entity):
|
|||
cluster_value = StringEntityField('value', display_name='Value', matching_rule=MatchingRule.Loose)
|
||||
synonyms = StringEntityField('synonyms', display_name='Synonyms', matching_rule=MatchingRule.Loose)
|
||||
tag_name = StringEntityField('tag_name', display_name='Tag')
|
||||
|
||||
|
||||
class ThreatActor(MISPGalaxy):
|
||||
_category_ = 'MISP'
|
||||
_namespace_ = 'misp'
|
||||
|
||||
|
||||
class Software(MISPGalaxy):
|
||||
_category_ = 'MISP'
|
||||
_namespace_ = 'misp'
|
||||
|
||||
|
||||
class AttackTechnique(MISPGalaxy):
|
||||
_category_ = 'MISP'
|
||||
_namespace_ = 'misp'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from canari.maltego.entities import Hash, Domain, IPv4Address, URL, DNSName, AS, Website, NSRecord, PhoneNumber, EmailAddress, File, Person, Hashtag, Location, Company, Alias, Port, Twitter
|
||||
from canari.maltego.message import Label, LinkStyle, MaltegoException, Bookmark, LinkDirection, UIMessage, UIMessageType
|
||||
from distutils.version import StrictVersion
|
||||
from MISP_maltego.transforms.common.entities import MISPEvent, MISPObject, MISPGalaxy
|
||||
from MISP_maltego.transforms.common.entities import MISPEvent, MISPObject, MISPGalaxy, ThreatActor, Software, AttackTechnique
|
||||
from pymisp import ExpandedPyMISP as PyMISP
|
||||
import json
|
||||
import os
|
||||
|
@ -12,7 +12,7 @@ import time
|
|||
|
||||
# FIXME from galaxy 'to MISP Event' is confusing
|
||||
|
||||
__version__ = '1.3.7' # also update version in setup.py
|
||||
__version__ = '1.4.0' # also update version in setup.py
|
||||
|
||||
mapping_misp_to_maltego = {
|
||||
'AS': [AS],
|
||||
|
@ -82,6 +82,40 @@ mapping_galaxy_icon = {
|
|||
"user-secret": "threat_actor",
|
||||
}
|
||||
|
||||
mapping_galaxy_type = {
|
||||
# 'amitt-misinformation-pattern': '',
|
||||
'android': Software,
|
||||
'backdoor': Software,
|
||||
'banker': Software,
|
||||
'botnet': Software,
|
||||
# 'branded-vulnerability': '',
|
||||
# 'cert-eu-govsector': '',
|
||||
'cloud-security': AttackTechnique,
|
||||
'exploit-kit': Software,
|
||||
'financial-fraud': AttackTechnique,
|
||||
'guidelines': AttackTechnique,
|
||||
'malpedia': Software,
|
||||
'microsoft-activity-group': ThreatActor,
|
||||
'mitre-attack-pattern': AttackTechnique,
|
||||
# 'mitre-course-of-action': '',
|
||||
'mitre-intrusion-set': ThreatActor,
|
||||
'mitre-malware': Software,
|
||||
'mitre-tool': Software,
|
||||
# 'preventive-measure': '',
|
||||
'ransomware': Software,
|
||||
'rat': Software,
|
||||
# 'region': '',
|
||||
# 'sector': '',
|
||||
'social-dark-patterns': AttackTechnique,
|
||||
'stealer': Software,
|
||||
'surveillance-vendor': ThreatActor,
|
||||
# 'target-information': '',
|
||||
'tds': Software,
|
||||
'threat-actor': ThreatActor,
|
||||
'tool': Software
|
||||
}
|
||||
|
||||
|
||||
tag_note_prefixes = ['tlp:', 'PAP:', 'de-vs:', 'euci:', 'fr-classif:', 'nato:']
|
||||
|
||||
misp_connection = None
|
||||
|
@ -399,15 +433,20 @@ def galaxycluster_to_entity(c, link_label=None, link_direction=LinkDirection.Inp
|
|||
synonyms = ''
|
||||
|
||||
galaxy_cluster = get_galaxy_cluster(c['uuid'])
|
||||
icon_url = None
|
||||
if 'icon' in galaxy_cluster: # map the 'icon' name from the cluster to the icon filename of the intelligence-icons repository
|
||||
try:
|
||||
icon_url = mapping_galaxy_icon[galaxy_cluster['icon']]
|
||||
except Exception:
|
||||
# it's not in our mapping, just ignore and leave the default Galaxy icon
|
||||
pass
|
||||
# map the 'icon' name from the cluster to the icon filename of the intelligence-icons repository
|
||||
try:
|
||||
icon_url = mapping_galaxy_icon[galaxy_cluster['icon']]
|
||||
except KeyError:
|
||||
icon_url = None
|
||||
# it's not in our mapping, just ignore and leave the default Galaxy icon
|
||||
pass
|
||||
|
||||
return MISPGalaxy(
|
||||
# create the right sub-galaxy: ThreatActor, Software, AttackTechnique, ... or MISPGalaxy
|
||||
try:
|
||||
galaxy_type = mapping_galaxy_type[galaxy_cluster['type']]
|
||||
except KeyError:
|
||||
galaxy_type = MISPGalaxy
|
||||
return galaxy_type(
|
||||
'{}\n{}'.format(c['type'], c['value']),
|
||||
uuid=c['uuid'],
|
||||
description=c.get('description'),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.entities import MISPEvent, MISPGalaxy, ThreatActor, Software, AttackTechnique
|
||||
from MISP_maltego.transforms.common.util import check_update, get_misp_connection, galaxycluster_to_entity, get_galaxy_cluster, get_galaxies_relating, search_galaxy_cluster, mapping_galaxy_icon
|
||||
from canari.maltego.message import UIMessageType, UIMessage, LinkDirection
|
||||
|
||||
|
@ -16,16 +16,6 @@ __email__ = 'christophe@vandeplas.com'
|
|||
__status__ = 'Development'
|
||||
|
||||
|
||||
class GalaxyTo(Transform):
|
||||
input_type = None
|
||||
|
||||
def __init__(self):
|
||||
self.request = None
|
||||
self.response = None
|
||||
self.config = None
|
||||
self.misp = None
|
||||
|
||||
|
||||
# @EnableDebugWindow
|
||||
class GalaxyToEvents(Transform):
|
||||
"""Expands a Galaxy to multiple MISP Events."""
|
||||
|
@ -48,14 +38,14 @@ class GalaxyToEvents(Transform):
|
|||
|
||||
|
||||
# @EnableDebugWindow
|
||||
class GalaxyToRelations(Transform):
|
||||
"""Expans a Galaxy to related Galaxies and Clusters"""
|
||||
input_type = MISPGalaxy
|
||||
class GalaxyToTransform(Transform):
|
||||
input_type = None
|
||||
|
||||
def do_transform(self, request, response, config):
|
||||
def do_transform(self, request, response, config, type_filter=MISPGalaxy):
|
||||
response += check_update(config)
|
||||
maltego_misp_galaxy = request.entity
|
||||
|
||||
current_cluster = None
|
||||
if maltego_misp_galaxy.uuid:
|
||||
current_cluster = get_galaxy_cluster(uuid=maltego_misp_galaxy.uuid)
|
||||
elif maltego_misp_galaxy.tag_name:
|
||||
|
@ -63,7 +53,7 @@ class GalaxyToRelations(Transform):
|
|||
elif maltego_misp_galaxy.name:
|
||||
current_cluster = get_galaxy_cluster(tag=maltego_misp_galaxy.name)
|
||||
|
||||
if not current_cluster:
|
||||
if not current_cluster and maltego_misp_galaxy.name != '-':
|
||||
# maybe the user is searching for a cluster based on a substring.
|
||||
# Search in the list for those that match and return galaxy entities
|
||||
potential_clusters = search_galaxy_cluster(maltego_misp_galaxy.name)
|
||||
|
@ -77,8 +67,8 @@ class GalaxyToRelations(Transform):
|
|||
response += UIMessage("Galaxy Cluster UUID not in local mapping. Please update local cache; non-public UUID are not supported yet.", type=UIMessageType.Inform)
|
||||
return response
|
||||
c = current_cluster
|
||||
# update existing object
|
||||
|
||||
# update existing object
|
||||
galaxy_cluster = get_galaxy_cluster(c['uuid'])
|
||||
icon_url = None
|
||||
if 'icon' in galaxy_cluster: # map the 'icon' name from the cluster to the icon filename of the intelligence-icons repository
|
||||
|
@ -100,12 +90,15 @@ class GalaxyToRelations(Transform):
|
|||
request.entity.tag_name = c['tag_name']
|
||||
request.entity.icon_url = icon_url
|
||||
# response += request.entity
|
||||
|
||||
# find related objects
|
||||
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'])
|
||||
new_entity = galaxycluster_to_entity(related_cluster, link_label=related['type'])
|
||||
if isinstance(new_entity, type_filter):
|
||||
response += new_entity
|
||||
# find objects that are relating to this one
|
||||
for related in get_galaxies_relating(current_cluster['uuid']):
|
||||
related_link_label = ''
|
||||
|
@ -113,5 +106,39 @@ class GalaxyToRelations(Transform):
|
|||
if rel_in_rel['dest-uuid'] == current_cluster['uuid']:
|
||||
related_link_label = rel_in_rel['type']
|
||||
break
|
||||
response += galaxycluster_to_entity(related, link_label=related_link_label, link_direction=LinkDirection.OutputToInput)
|
||||
new_entity = galaxycluster_to_entity(related, link_label=related_link_label, link_direction=LinkDirection.OutputToInput)
|
||||
if isinstance(new_entity, type_filter):
|
||||
response += new_entity
|
||||
return response
|
||||
|
||||
|
||||
class GalaxyToRelations(GalaxyToTransform):
|
||||
"""Expands a Galaxy to related Galaxies and Clusters"""
|
||||
input_type = MISPGalaxy
|
||||
|
||||
def do_transform(self, request, response, config, type_filter=MISPGalaxy):
|
||||
return super().do_transform(request, response, config, type_filter)
|
||||
|
||||
|
||||
class GalaxyToSoftware(GalaxyToTransform):
|
||||
"""Expands a Galaxy to related Software/Tool Galaxies"""
|
||||
input_type = MISPGalaxy
|
||||
|
||||
def do_transform(self, request, response, config, type_filter=Software):
|
||||
return super().do_transform(request, response, config, type_filter)
|
||||
|
||||
|
||||
class GalaxyToThreatActor(GalaxyToTransform):
|
||||
"""Expands a Galaxy to related ThreatActor Galaxies"""
|
||||
input_type = MISPGalaxy
|
||||
|
||||
def do_transform(self, request, response, config, type_filter=ThreatActor):
|
||||
return super().do_transform(request, response, config, type_filter)
|
||||
|
||||
|
||||
class GalaxyToAttackTechnique(GalaxyToTransform):
|
||||
"""Expands a Galaxy to related Attack Techniques Galaxies"""
|
||||
input_type = MISPGalaxy
|
||||
|
||||
def do_transform(self, request, response, config, type_filter=AttackTechnique):
|
||||
return super().do_transform(request, response, config, type_filter)
|
||||
|
|
Loading…
Reference in New Issue