mirror of https://github.com/MISP/misp-modules
new: add sigmf module to expand a sigmf recording object template
parent
d23f116e7b
commit
5e2957b13f
|
@ -0,0 +1,121 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import base64
|
||||
import json
|
||||
import tempfile
|
||||
import logging
|
||||
import sys
|
||||
from pymisp import MISPObject, MISPEvent
|
||||
from sigmf import SigMFFile
|
||||
|
||||
log = logging.getLogger("sigmf-expand")
|
||||
log.setLevel(logging.DEBUG)
|
||||
sh = logging.StreamHandler(sys.stdout)
|
||||
sh.setLevel(logging.DEBUG)
|
||||
fmt = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
sh.setFormatter(fmt)
|
||||
log.addHandler(sh)
|
||||
|
||||
misperrors = {'error': 'Error'}
|
||||
mispattributes = {'input': ['sigmf-recording'], 'output': [
|
||||
'MISP objects'], 'format': 'misp_standard'}
|
||||
moduleinfo = {'version': '0.1', 'author': 'Luciano Righetti',
|
||||
'description': 'Expand a SigMF Recording object into a SigMF Expanded Recording object.',
|
||||
'module-type': ['expansion']}
|
||||
|
||||
|
||||
def handler(q=False):
|
||||
request = json.loads(q)
|
||||
object = request.get("object")
|
||||
if not object:
|
||||
return {"error": "No object provided"}
|
||||
|
||||
if 'Attribute' not in object:
|
||||
return {"error": "Empty Attribute list"}
|
||||
|
||||
for attribute in object['Attribute']:
|
||||
if attribute['object_relation'] == 'SigMF-data':
|
||||
sigmf_data_attr = attribute
|
||||
|
||||
if attribute['object_relation'] == 'SigMF-meta':
|
||||
sigmf_meta_attr = attribute
|
||||
|
||||
if sigmf_meta_attr is None:
|
||||
return {"error": "No SigMF-data attribute"}
|
||||
|
||||
if sigmf_data_attr is None:
|
||||
return {"error": "No SigMF-meta attribute"}
|
||||
|
||||
try:
|
||||
sigmf_meta = base64.b64decode(sigmf_meta_attr['data']).decode('utf-8')
|
||||
sigmf_meta = json.loads(sigmf_meta)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
return {"error": "Provided .sigmf-meta is not a valid JSON string"}
|
||||
|
||||
# write temp data file to disk
|
||||
sigmf_data_file = tempfile.NamedTemporaryFile(suffix='.sigmf-data')
|
||||
sigmf_data_bin = base64.b64decode(sigmf_data_attr['data'])
|
||||
with open(sigmf_data_file.name, 'wb') as f:
|
||||
f.write(sigmf_data_bin)
|
||||
f.close()
|
||||
|
||||
try:
|
||||
recording = SigMFFile(
|
||||
metadata=sigmf_meta,
|
||||
data_file=sigmf_data_file.name
|
||||
)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
return {"error": "Provided .sigmf-meta and .sigmf-data is not a valid SigMF file"}
|
||||
|
||||
event = MISPEvent()
|
||||
expanded_sigmf = MISPObject('sigmf-expanded-recording')
|
||||
|
||||
if 'core:author' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'author', **{'type': 'text', 'value': sigmf_meta['global']['core:author']})
|
||||
if 'core:datatype' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'datatype', **{'type': 'text', 'value': sigmf_meta['global']['core:datatype']})
|
||||
if 'core:description' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'description', **{'type': 'text', 'value': sigmf_meta['global']['core:description']})
|
||||
if 'core:license' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'license', **{'type': 'text', 'value': sigmf_meta['global']['core:license']})
|
||||
if 'core:num_channels' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'num_channels', **{'type': 'counter', 'value': sigmf_meta['global']['core:num_channels']})
|
||||
if 'core:recorder' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'recorder', **{'type': 'text', 'value': sigmf_meta['global']['core:recorder']})
|
||||
if 'core:sample_rate' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'sample_rate', **{'type': 'float', 'value': sigmf_meta['global']['core:sample_rate']})
|
||||
if 'core:sha512' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'sha512', **{'type': 'text', 'value': sigmf_meta['global']['core:sha512']})
|
||||
if 'core:version' in sigmf_meta['global']:
|
||||
expanded_sigmf.add_attribute(
|
||||
'version', **{'type': 'text', 'value': sigmf_meta['global']['core:version']})
|
||||
|
||||
# TODO: geolocation (GeoJSON)
|
||||
|
||||
# add reference to original SigMF Recording object
|
||||
expanded_sigmf.add_reference(object['uuid'], "expands")
|
||||
|
||||
event.add_object(expanded_sigmf)
|
||||
event = json.loads(event.to_json())
|
||||
|
||||
return {"results": {'Object': event['Object']}}
|
||||
|
||||
|
||||
def introspection():
|
||||
return mispattributes
|
||||
|
||||
|
||||
def version():
|
||||
return moduleinfo
|
Loading…
Reference in New Issue