Merge pull request #168 from chrisr3d/goaml

GoAML import module & GoAML export updates
pull/169/head
Alexandre Dulaunoy 2018-03-02 11:39:23 +01:00 committed by GitHub
commit b1dd21fd06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 166 additions and 5 deletions

View File

@ -30,21 +30,21 @@ goAMLmapping = {'bank-account': {'bank-account': 't_account', 'institution-name'
'passport-number': 'passport_number', 'passport-country': 'passport_country',
'social-security-number': 'ssn', 'identity-card-number': 'id_number'},
'geolocation': {'geolocation': 'location', 'city': 'city', 'region': 'state',
'country': 'country-code', 'address': 'address', 'zipcode': 'zip'},
'country': 'country_code', 'address': 'address', 'zipcode': 'zip'},
'transaction': {'transaction': 'transaction', 'transaction-number': 'transactionnumber',
'date': 'date_transaction', 'location': 'transaction_location',
'transmode-code': 'transmode_code', 'amount': 'amount_local',
'transmode-comment': 'transmode_comment', 'date-posting': 'date_posting',
'teller': 'teller', 'authorized': 'authorized',
'text': 'transaction_description'},
'legal-enitty': {'legal-entity': 'entity', 'name': 'name', 'business': 'business',
'legal-entity': {'legal-entity': 'entity', 'name': 'name', 'business': 'business',
'commercial-name': 'commercial_name', 'phone-number': 'phone',
'legal-form': 'incorporation_legal_form',
'registration-number': 'incorporation_number'}}
referencesMapping = {'bank-account': {'aml_type': '{}_account', 'bracket': 't_{}'},
'person': {'transaction': {'aml_type': '{}_person', 'bracket': 't_{}'}, 'bank-account': {'aml_type': 't_person', 'bracket': 'signatory'}},
'legal-entity': {'transaction': {'aml_type': '{}_entity', 'bracket': 't_{}'}, 'bank-account': {'aml_type': 'entity'}},
'legal-entity': {'transaction': {'aml_type': '{}_entity', 'bracket': 't_{}'}, 'bank-account': {'aml_type': 't_entity'}},
'geolocation': {'aml_type': 'address', 'bracket': 'addresses'}}
class GoAmlGeneration(object):

View File

@ -1,4 +1,4 @@
from . import _vmray
__all__ = ['vmray_import', 'testimport', 'ocr', 'stiximport', 'cuckooimport',
__all__ = ['vmray_import', 'testimport', 'ocr', 'stiximport', 'cuckooimport', 'goamlimport',
'email_import', 'mispjson', 'openiocimport', 'threatanalyzer_import', 'csvimport']

View File

@ -0,0 +1,161 @@
import json, datetime, time, base64
import xml.etree.ElementTree as ET
from collections import defaultdict
from pymisp import MISPEvent, MISPObject
misperrors = {'error': 'Error'}
moduleinfo = {'version': 1, 'author': 'Christian Studer',
'description': 'Import from GoAML',
'module-type': ['import']}
moduleconfig = []
mispattributes = {'inputSource': ['file'], 'output': ['MISP objects']}
t_from_objects = {'nodes': ['from_person', 'from_account', 'from_entity'],
'leaves': ['from_funds_code', 'from_country']}
t_to_objects = {'nodes': ['to_person', 'to_account', 'to_entity'],
'leaves': ['to_funds_code', 'to_country']}
t_person_objects = {'nodes': ['addresses'],
'leaves': ['first_name', 'middle_name', 'last_name', 'gender', 'title', 'mothers_name', 'birthdate',
'passport_number', 'passport_country', 'id_number', 'birth_place', 'alias', 'nationality1']}
t_account_objects = {'nodes': ['signatory'],
'leaves': ['institution_name', 'institution_code', 'swift', 'branch', 'non_banking_insitution',
'account', 'currency_code', 'account_name', 'iban', 'client_number', 'opened', 'closed',
'personal_account_type', 'balance', 'date_balance', 'status_code', 'beneficiary',
'beneficiary_comment', 'comments']}
entity_objects = {'nodes': ['addresses'],
'leaves': ['name', 'commercial_name', 'incorporation_legal_form', 'incorporation_number', 'business', 'phone']}
goAMLobjects = {'report': {'nodes': ['reporting_person', 'location'],
'leaves': ['rentity_id', 'submission_code', 'report_code', 'submission_date', 'currency_code_local']},
'reporting_person': {'nodes': ['addresses'], 'leaves': ['first_name', 'middle_name', 'last_name', 'title']},
'location': {'nodes': [], 'leaves': ['address_type', 'address', 'city', 'zip', 'country_code', 'state']},
'transaction': {'nodes': ['t_from', 't_from_my_client', 't_to', 't_to_my_client'],
'leaves': ['transactionnumber', 'transaction_location', 'date_transaction',
'transmode_code', 'amount_local']},
't_from': t_from_objects, 't_from_my_client': t_from_objects,
't_to': t_to_objects, 't_to_my_client': t_to_objects,
'addresses': {'nodes': ['address'], 'leaves': []},
'address': {'nodes': [], 'leaves': ['address_type', 'address', 'city', 'zip', 'country_code', 'state']},
'from_person': t_person_objects, 'to_person': t_person_objects, 't_person': t_person_objects,
'from_account': t_account_objects, 'to_account': t_account_objects,
'signatory': {'nodes': ['t_person'], 'leaves': []},
'from_entity': entity_objects, 'to_entity': entity_objects,
}
t_account_mapping = {'misp_name': 'bank-account', 'institution_name': 'institution-name', 'institution_code': 'institution-code',
'iban': 'iban', 'swift': 'swift', 'branch': 'branch', 'non_banking_institution': 'non-bank-institution',
'account': 'account', 'currency_code': 'currency-code', 'account_name': 'account-name',
'client_number': 'client-number', 'personal_account_type': 'personal-account-type', 'opened': 'opened',
'closed': 'closed', 'balance': 'balance', 'status_code': 'status-code', 'beneficiary': 'beneficiary',
'beneficiary_comment': 'beneficiary-comment', 'comments': 'comments'}
t_person_mapping = {'misp_name': 'person', 'comments': 'text', 'first_name': 'first-name', 'middle_name': 'middle-name',
'last_name': 'last-name', 'title': 'title', 'mothers_name': 'mothers-name', 'alias': 'alias',
'birthdate': 'date-of-birth', 'birth_place': 'place-of-birth', 'gender': 'gender','nationality1': 'nationality',
'passport_number': 'passport-number', 'passport_country': 'passport-country', 'ssn': 'social-security-number',
'id_number': 'identity-card-number'}
location_mapping = {'misp_name': 'geolocation', 'city': 'city', 'state': 'region', 'country_code': 'country', 'address': 'address',
'zip': 'zipcode'}
t_entity_mapping = {'misp_name': 'legal-entity', 'name': 'name', 'business': 'business', 'commercial_name': 'commercial-name',
'phone': 'phone-number', 'incorporation_legal_form': 'legal-form', 'incorporation_number': 'registration-number'}
goAMLmapping = {'from_account': t_account_mapping, 'to_account': t_account_mapping, 't_person': t_person_mapping,
'from_person': t_person_mapping, 'to_person': t_person_mapping, 'reporting_person': t_person_mapping,
'from_entity': t_entity_mapping, 'to_entity': t_entity_mapping,
'location': location_mapping, 'address': location_mapping,
'transaction': {'misp_name': 'transaction', 'transactionnumber': 'transaction-number', 'date_transaction': 'date',
'transaction_location': 'location', 'transmode_code': 'transmode-code', 'amount_local': 'amount',
'transmode_comment': 'transmode-comment', 'date_posting': 'date-posting', 'teller': 'teller',
'authorized': 'authorized', 'transaction_description': 'text'}}
nodes_to_ignore = ['addresses', 'signatory']
class GoAmlParser():
def __init__(self):
self.misp_event = MISPEvent()
def read_xml(self, data):
self.tree = ET.fromstring(data)
def parse_xml(self):
self.first_itteration()
for t in self.tree.findall('transaction'):
self.itterate(t, 'transaction')
def first_itteration(self):
submission_date = self.tree.find('submission_date').text.split('+')[0]
self.misp_event.timestamp = int(time.mktime(time.strptime(submission_date, "%Y-%m-%dT%H:%M:%S")))
for node in goAMLobjects['report']['nodes']:
element = self.tree.find(node)
if element is not None:
self.itterate(element, element.tag)
def itterate(self, tree, aml_type):
objects = goAMLobjects[aml_type]
if aml_type not in nodes_to_ignore:
try:
mapping = goAMLmapping[aml_type]
misp_object = MISPObject(name=mapping['misp_name'])
for leaf in objects['leaves']:
element = tree.find(leaf)
if element is not None:
object_relation = mapping[element.tag]
attribute = {'object_relation': object_relation, 'value': element.text}
misp_object.add_attribute(**attribute)
if aml_type == 'transaction':
for node in objects['nodes']:
element = tree.find(node)
if element is not None:
self.fill_transaction(element, element.tag, misp_object)
self.misp_event.add_object(misp_object)
except KeyError:
pass
for node in objects['nodes']:
element = tree.find(node)
if element is not None:
self.itterate(element, element.tag)
@staticmethod
def fill_transaction(element, tag, misp_object):
if 't_from' in tag:
from_funds = element.find('from_funds_code').text
from_funds_attribute = {'object_relation': 'from-funds-code', 'value': from_funds}
misp_object.add_attribute(**from_funds_attribute)
from_country = element.find('from_country').text
from_country_attribute = {'object_relation': 'from-country', 'value': from_country}
misp_object.add_attribute(**from_country_attribute)
if 't_to' in tag:
to_funds = element.find('to_funds_code').text
to_funds_attribute = {'object_relation': 'to-funds-code', 'value': to_funds}
misp_object.add_attribute(**to_funds_attribute)
to_country = element.find('to_country').text
to_country_attribute = {'object_relation': 'to-country', 'value': to_country}
misp_object.add_attribute(**to_country_attribute)
def handler(q=False):
if q is False:
return False
request = json.loads(q)
if request.get('data'):
data = base64.b64decode(request['data']).decode('utf-8')
else:
misperrors['error'] = "Unsupported attributes type"
return misperrors
aml_parser = GoAmlParser()
try:
aml_parser.read_xml(data)
except:
misperrors['error'] = "Impossible to read XML data"
return misperrors
aml_parser.parse_xml()
r = {'results': [obj.to_json() for obj in aml_parser.misp_event.objects]}
return r
def introspection():
return mispattributes
def version():
moduleinfo['config'] = moduleconfig
return moduleinfo

View File

@ -1 +1 @@
<report><rentity_id>2510</rentity_id><submission_code>E</submission_code><report_code>STR</report_code><submission_date>2018-02-22T08:34:16+00:00</submission_date><currency_code_local>EUR</currency_code_local><transaction><transactionnumber>TW00000901</transactionnumber><transaction_location>1 Manners Street Wellington</transaction_location><transmode_code>BG</transmode_code><date_transaction>2015-12-01T10:03:00</date_transaction><amount_local>12345</amount_local><transaction_description>when it transacts</transaction_description><t_from><from_funds_code>E</from_funds_code><from_account><status_code>A</status_code><personal_account_type>A</personal_account_type><currency_code>EUR</currency_code><account>31032027088</account><swift>ATTBVI</swift><institution_name>The bank</institution_name><signatory><t_person><last_name>Nick</last_name><first_name>Pitt</first_name><title>Sir</title><birthdate>1993-09-25</birthdate><birth_place>Mulhouse, France</birth_place><gender>Male</gender><addresses><address><city>Paris</city><country-code>France</country-code></address></addresses></t_person></signatory></from_account><from_country>FRA</from_country></t_from><t_to_my_client><to_funds_code>K</to_funds_code><to_person><last_name>Michel</last_name><first_name>Jean</first_name><title>Himself</title><gender>Prefer not to say</gender><addresses><address><city>Luxembourg</city><country-code>Luxembourg</country-code></address></addresses></to_person><to_country>LUX</to_country></t_to_my_client></transaction></report>
<report><rentity_id>2510</rentity_id><submission_code>E</submission_code><report_code>STR</report_code><submission_date>2018-02-22T08:34:16+00:00</submission_date><currency_code_local>EUR</currency_code_local><transaction><transactionnumber>TW00000901</transactionnumber><transaction_location>1 Manners Street Wellington</transaction_location><transmode_code>BG</transmode_code><date_transaction>2015-12-01T10:03:00</date_transaction><amount_local>12345</amount_local><transaction_description>when it transacts</transaction_description><t_from><from_funds_code>E</from_funds_code><from_account><status_code>A</status_code><personal_account_type>A</personal_account_type><currency_code>EUR</currency_code><account>31032027088</account><swift>ATTBVI</swift><institution_name>The bank</institution_name><signatory><t_person><last_name>Nick</last_name><first_name>Pitt</first_name><title>Sir</title><birthdate>1993-09-25</birthdate><birth_place>Mulhouse, France</birth_place><gender>Male</gender><addresses><address><city>Paris</city><country_code>France</country_code></address></addresses></t_person></signatory></from_account><from_country>FRA</from_country></t_from><t_to_my_client><to_funds_code>K</to_funds_code><to_person><last_name>Michel</last_name><first_name>Jean</first_name><title>Himself</title><gender>Prefer not to say</gender><addresses><address><city>Luxembourg</city><country_code>Luxembourg</country_code></address></addresses></to_person><to_country>LUX</to_country></t_to_my_client></transaction></report>