Added files via upload

Init
v1
ebouillon 2016-02-20 16:58:38 +01:00
parent 279f5418d6
commit 620690f745
6 changed files with 337 additions and 0 deletions

174
MaltegoTransform.py Normal file
View File

@ -0,0 +1,174 @@
#!/usr/bin/python
#######################################################
# Maltego Python Local Transform Helper #
# Version 0.2 #
# #
# Local transform specification can be found at: #
# http://ctas.paterva.com/view/Specification #
# #
# For more help and other local transforms #
# try the forum or mail me: #
# #
# http://www.paterva.com/forum #
# #
# Andrew MacPherson [ andrew <<at>> Paterva.com ] #
# #
#######################################################
import sys
def u2a_ascii(text):
# takes care of "'ascii' codec can't encode character" errors
return text.encode('unicode-escape')
class MaltegoEntity(object):
value = "";
weight = 100;
displayInformation = None;
additionalFields = [];
iconURL = "";
entityType = "Phrase"
def __init__(self,eT=None,v=None):
if (eT is not None):
self.entityType = eT;
if (v is not None):
self.value = sanitise(v);
self.additionalFields = [];
self.displayInformation = None;
def setType(self,eT=None):
if (eT is not None):
self.entityType = eT;
def setValue(self,eV=None):
if (eV is not None):
self.value = sanitise(eV);
def setWeight(self,w=None):
if (w is not None):
self.weight = w;
def setDisplayInformation(self,di=None):
if (di is not None):
self.displayInformation = di;
def addAdditionalFields(self,fieldName=None,displayName=None,matchingRule=False,value=None):
self.additionalFields.append([sanitise(fieldName),sanitise(displayName),matchingRule,sanitise(value)]);
def setIconURL(self,iU=None):
if (iU is not None):
self.iconURL = iU;
def returnEntity(self):
print "<Entity Type=\"" + str(self.entityType) + "\">";
print "<Value>" + str(self.value) + "</Value>";
print "<Weight>" + str(self.weight) + "</Weight>";
if (self.displayInformation is not None):
print "<DisplayInformation><Label Name=\"\" Type=\"text/html\"><![CDATA[" + str(self.displayInformation) + "]]></Label></DisplayInformation>";
if (len(self.additionalFields) > 0):
print "<AdditionalFields>";
for i in range(len(self.additionalFields)):
if (str(self.additionalFields[i][2]) <> "strict"):
print "<Field Name=\"" + str(u2a_ascii(self.additionalFields[i][0])) + "\" DisplayName=\"" + str(u2a_ascii(self.additionalFields[i][1])) + "\">" + str(u2a_ascii(self.additionalFields[i][3])) + "</Field>";
else:
print "<Field MatchingRule=\"" + str(u2a_ascii(self.additionalFields[i][2])) + "\" Name=\"" + str(u2a_ascii(self.additionalFields[i][0])) + "\" DisplayName=\"" + str(u2a_ascii(self.additionalFields[i][1])) + "\">" + str(u2a_ascii(self.additionalFields[i][3])) + "</Field>";
print "</AdditionalFields>";
if (len(self.iconURL) > 0):
print "<IconURL>" + self.iconURL + "</IconURL>";
print "</Entity>";
class MaltegoTransform(object):
entities = []
exceptions = []
UIMessages = []
values = {};
def __init__(self):
values = {};
value = None;
def parseArguments(self,argv):
if (argv[1] is not None):
self.value = argv[1];
if (len(argv) > 2):
if (argv[2] is not None):
vars = argv[2].split('#');
for x in range(0,len(vars)):
vars_values = vars[x].split('=')
if (len(vars_values) == 2):
self.values[vars_values[0]] = vars_values[1];
def getValue(self):
if (self.value is not None):
return self.value;
def getVar(self,varName):
if (varName in self.values.keys()):
if (self.values[varName] is not None):
return self.values[varName];
def addEntity(self,enType,enValue):
me = MaltegoEntity(enType,enValue);
self.addEntityToMessage(me);
return self.entities[len(self.entities)-1];
def addEntityToMessage(self,maltegoEntity):
self.entities.append(maltegoEntity);
def addUIMessage(self,message,messageType="Inform"):
self.UIMessages.append([messageType,message]);
def addException(self,exceptionString):
self.exceptions.append(exceptionString);
def throwExceptions(self):
print "<MaltegoMessage>";
print "<MaltegoTransformExceptionMessage>";
print "<Exceptions>"
for i in range(len(self.exceptions)):
print "<Exception>" + self.exceptions[i] + "</Exception>";
print "</Exceptions>"
print "</MaltegoTransformExceptionMessage>";
print "</MaltegoMessage>";
exit();
def returnOutput(self):
print "<MaltegoMessage>";
print "<MaltegoTransformResponseMessage>";
print "<Entities>"
for i in range(len(self.entities)):
self.entities[i].returnEntity();
print "</Entities>"
print "<UIMessages>"
for i in range(len(self.UIMessages)):
print "<UIMessage MessageType=\"" + self.UIMessages[i][0] + "\">" + self.UIMessages[i][1] + "</UIMessage>";
print "</UIMessages>"
print "</MaltegoTransformResponseMessage>";
print "</MaltegoMessage>";
def writeSTDERR(self,msg):
sys.stderr.write(str(msg));
def heartbeat(self):
self.writeSTDERR("+");
def progress(self,percent):
self.writeSTDERR("%" + str(percent));
def debug(self,msg):
self.writeSTDERR("D:" + str(msg));
def sanitise(value):
replace_these = ["&",">","<"];
replace_with = ["&amp;","&gt;","&lt;"];
tempvalue = value;
for i in range(0,len(replace_these)):
tempvalue = tempvalue.replace(replace_these[i],replace_with[i]);
return tempvalue;

29
README Normal file
View File

@ -0,0 +1,29 @@
MISP-Maltego
Set of Maltego transforms to interface with a MISP instance.
Prerequisites:
- MISP instance API access
- PyMISP
INSTALL:
- Edit misp_util.py and set BASE_URL and API_KEY variables with your MISP base URL and MISP API key.
- Create symbolic links to misp_domain2event.py and misp_event2domain.py
$ for i in misp_email2event.py misp_email-subject2event.py misp_ip2event.py misp_hash2event.py ; do ln -s misp_domain2event.py $i; done
$ for i in misp_event2email.py misp_event2email-subject.py misp_event2hash.py misp_event2ip.py ; do ln -s misp_event2domain.py $i; done
- Import transforms in Maltego as follows (for instance):
misp_ip2event.py: [MISP] IP to Event / Returns MISPEvent entities containing the corresponding IP attribute
misp_domain2event.py: [MISP] Domain to Event / Returns MISPEvent entities containing the corresponding Domain attribute
misp_hash2event.py: [MISP] Hash to Event / Returns MISPEvent entities containing the corresponding Hash attribute
misp_ip2event.py: [MISP] Email address to Event / Returns MISPEvent entities containing the corresponding Email address attribute
misp_email-subject2event.py: [MISP] Email subject to Event / Returns MISPEvent entities containing the corresponding Email subject attribute
misp_event2ip.py: [MISP] Event to IP attribute / Returns the IP attributes belonging to an event
misp_event2domain.py: [MISP] Event to Domain attribute / Returns Domain attributes belonging to an event
misp_event2hash.py: [MISP] Event to Hash attribute / Returns Hash attributes belonging to an event
misp_event2email.py: [MISP] Event to Email address attribute / Returns Email address attributes belonging to an event
misp_event2email-subject.py: [MISP] Event to Email subject attribute / Returns Email subject attributes belonging to an event
misp_getEventInfo.py: [MISP] Get Event Info / Adorns the Event with Info as notes

29
misp_domain2event.py Normal file
View File

@ -0,0 +1,29 @@
#############################################
# MISP API Domain to Event
#
# Author: Emmanuel Bouillon
# Email: emmanuel.bouillon.sec@gmail.com
# Date: 24/11/2015
#############################################
import sys
from misp_util import *
from pymisp import PyMISP
import json
attribute2filter = {
'ip':'ip-src&&ip-dst', 'domain':'domain&&hostname',
'hash':'md5&&sha1&&sha256&&malware-sample',
'email':'email-src&&email-dst', 'email-subject': 'email-subject'
}
if __name__ == '__main__':
enValue = sys.argv[1]
enType = sys.argv[0].split('_')[-1].split('2')[0] #misp_enType2event.py
mt = MaltegoTransform()
mt.addUIMessage("[INFO] " + enType + " to MISP Event")
try:
retrieveEvents(mt, attribute2filter[enType], enValue)
except Exception as e:
mt.addUIMessage("[Error] " + str(e))
mt.returnOutput()

38
misp_event2domain.py Normal file
View File

@ -0,0 +1,38 @@
#############################################
# MISP API Domain to Event
#
# Author: Emmanuel Bouillon
# Email: emmanuel.bouillon.sec@gmail.com
# Date: 24/11/2015
#############################################
import sys
from misp_util import *
from pymisp import PyMISP
import json
type2attribute = {'domain':('domain','hostname'), 'hostname':('hostname'), 'hash':('md5','sha1','sha256') , 'ip':('ip-src','ip-dst'), 'email':('email-src','email-dst'), 'email-subject': ('email-subject')}
argType2enType = {'domain':'maltego.Domain', 'hostname':'maltego.Domain', 'hash':'maltego.Hash', 'ip':'maltego.IPv4Address', 'email':'maltego.EmailAddress', 'email-subject': 'maltego.Phrase'}
filename_pipe_hash_type = ('filename|md5', 'filename|sha1', 'filename|sha256', 'malware-sample')
if __name__ == '__main__':
event_id = sys.argv[1]
argType = sys.argv[0].split('.')[0].split('2')[1] # misp_event2argType.py
misp = init()
try:
event = misp.get_event(event_id)
event_json = event.json()
mt = MaltegoTransform()
for attribute in event_json['Event']["Attribute"]:
value = attribute["value"]
aType = attribute["type"]
if aType in type2attribute[argType]:
if aType in filename_pipe_hash_type:
h = value.split('|')[1].strip()
me = MaltegoEntity(argType2enType[argType], h)
mt.addEntityToMessage(me);
else:
me = MaltegoEntity(argType2enType[argType], value)
mt.addEntityToMessage(me);
except Exception as e:
mt.addUIMessage("[ERROR] " + str(e))
mt.returnOutput()

30
misp_getEventInfo.py Normal file
View File

@ -0,0 +1,30 @@
#############################################
# MISP API Domain to Event
#
# Author: Emmanuel Bouillon
# Email: emmanuel.bouillon.sec@gmail.com
# Date: 24/11/2015
#############################################
import sys
from misp_util import *
from pymisp import PyMISP
import json
if __name__ == '__main__':
m = init()
mt = MaltegoTransform()
event_id = sys.argv[1]
try:
event = m.get_event(event_id)
event_json = event.json()
eid = event_json['Event']['id']
einfo = event_json['Event']['info']
eorgc = event_json['Event']['orgc']
me = MaltegoEntity('maltego.MISPEvent',eid);
me.addAdditionalFields('EventLink', 'EventLink', False, BASE_URL + '/events/view/' + eid )
me.addAdditionalFields('Org', 'Org', False, eorgc)
me.addAdditionalFields('notes#', 'notes', False, eorgc + ": " + einfo)
mt.addEntityToMessage(me);
except Exception as e:
mt.addUIMessage("[ERROR] " + str(e))
mt.returnOutput()

37
misp_util.py Normal file
View File

@ -0,0 +1,37 @@
#############################################
# MISP API miscellaneous functions.
#
# Author: Emmanuel Bouillon
# Email: emmanuel.bouillon.sec@gmail.com
# Date: 24/11/2015
#############################################
# MISP BASE URL
BASE_URL = '<MISP_BASE_URL>'
# API KEY
API_KEY = '<YOUR_API_KEY>'
# MISP_VERIFYCERT
MISP_VERIFYCERT = True
# pyMISP DEBUG
MISP_DEBUG = False
from pymisp import PyMISP
from MaltegoTransform import *
def init():
return PyMISP(BASE_URL, API_KEY, MISP_VERIFYCERT, 'json', MISP_DEBUG)
def retrieveEvents(mt, enFilter, enValue):
misp = init()
result = misp.search(values = enValue, type_attribute = enFilter)
for e in result['response']:
eid = e['Event']['id']
einfo = e['Event']['info']
eorgc = e['Event']['orgc']
me = MaltegoEntity('maltego.MISPEvent',eid);
me.addAdditionalFields('EventLink', 'EventLink', False, BASE_URL + '/events/view/' + eid )
me.addAdditionalFields('Org', 'Org', False, eorgc)
me.addAdditionalFields('notes#', 'notes', False, eorgc + ": " + einfo)
mt.addEntityToMessage(me);
return