misp-modules/misp_modules/modules/expansion/malwarebazaar.py

68 lines
3.2 KiB
Python

import json
import requests
from . import check_input_attribute, checking_error, standard_error_message
from pymisp import MISPEvent, MISPObject
mispattributes = {'input': ['md5', 'sha1', 'sha256'],
'format': 'misp_standard'}
moduleinfo = {
'version': '0.1',
'author': 'Christian Studer',
'description': 'Query Malware Bazaar to get additional information about the input hash.',
'module-type': ['expansion', 'hover'],
'name': 'Malware Bazaar Lookup',
'logo': '',
'requirements': [],
'features': "The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to.\n\nThe module is using the new format of modules able to return object since the result is one or multiple MISP object(s).",
'references': ['https://bazaar.abuse.ch/'],
'input': 'A hash attribute (md5, sha1 or sha256).',
'output': 'File object(s) related to the input attribute found on MALWAREbazaar databases.',
}
moduleconfig = []
def parse_response(response):
mapping = {'file_name': {'type': 'filename', 'object_relation': 'filename'},
'file_size': {'type': 'size-in-bytes', 'object_relation': 'size-in-bytes'},
'file_type_mime': {'type': 'mime-type', 'object_relation': 'mimetype'},
'md5_hash': {'type': 'md5', 'object_relation': 'md5'},
'sha1_hash': {'type': 'sha1', 'object_relation': 'sha1'},
'sha256_hash': {'type': 'sha256', 'object_relation': 'sha256'},
'ssdeep': {'type': 'ssdeep', 'object_relation': 'ssdeep'}}
misp_event = MISPEvent()
for data in response:
misp_object = MISPObject('file')
for feature, attribute in mapping.items():
if feature in data:
misp_attribute = {'value': data[feature]}
misp_attribute.update(attribute)
misp_object.add_attribute(**misp_attribute)
misp_event.add_object(**misp_object)
return {'results': {'Object': [json.loads(misp_object.to_json()) for misp_object in misp_event.objects]}}
def handler(q=False):
if q is False:
return False
request = json.loads(q)
if not request.get('attribute') or not check_input_attribute(request['attribute'], requirements=('type', 'value')):
return {'error': f'{standard_error_message}, {checking_error} that is the hash to submit to Malware Bazaar.'}
attribute = request['attribute']
if attribute['type'] not in mispattributes['input']:
return {'error': 'Unsupported attribute type.'}
url = 'https://mb-api.abuse.ch/api/v1/'
response = requests.post(url, data={'query': 'get_info', 'hash': attribute['value']}).json()
query_status = response['query_status']
if query_status == 'ok':
return parse_response(response['data'])
return {'error': 'Hash not found on MALWAREbazzar' if query_status == 'hash_not_found' else f'Problem encountered during the query: {query_status}'}
def introspection():
return mispattributes
def version():
moduleinfo['config'] = moduleconfig
return moduleinfo