Preliminary version of the file uploader

pull/2/merge
Raphaël Vinot 2015-08-04 16:24:55 +02:00
parent 58bfd30a23
commit bef354ac44
3 changed files with 94 additions and 44 deletions

View File

@ -1,43 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pymisp import PyMISP
from keys import priv
import argparse
import os
import glob
import base64
import json
import time
url = 'https://misppriv.circl.lu'
def init(url, key):
return PyMISP(url, key, True, 'json')
def upload_file(m, eid, path):
curevent = misp.get_event(eid)
j = curevent.json()
if j.get("Event"):
with open(path, "rb") as curfile:
j["Event"].update({"data": base64.b64encode(curfile.read())})
j["Event"]["timestamp"] = int(time.time())
out = misp.update_event(args.event, json.dumps(j))
print out, out.text
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Send malware sample to MISP.')
parser.add_argument("-u", "--upload", type=str, required=True, help="File or directory of files to upload.")
parser.add_argument("-e", "--event", type=int, help="Event to update with a sample (if none, create a new event).")
args = parser.parse_args()
misp = init(url, priv)
if os.path.isfile(args.upload):
upload_file(misp, args.event, args.upload)
elif os.path.isdir(args.upload):
for filename in glob.iglob(os.path.join(args.upload + '*')):
upload_file(misp, args.event, filename)

42
examples/upload.py Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pymisp import PyMISP
from keys import priv
import argparse
import os
import glob
url = 'https://misppriv.circl.lu'
def init(url, key):
return PyMISP(url, key, True, 'json')
def upload_files(m, eid, paths, distrib, ids, categ, info, analysis, threat):
out = m.upload_sample(eid, paths, distrib, ids, categ, info, analysis, threat)
print out, out.text
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Send malware sample to MISP.')
parser.add_argument("-u", "--upload", type=str, required=True, help="File or directory of files to upload.")
parser.add_argument("-e", "--event", type=int, help="Not supplying an event ID will cause MISP to create a single new event for all of the POSTed malware samples.")
parser.add_argument("-d", "--distrib", type=int, help="The distribution setting used for the attributes and for the newly created event, if relevant. [0-3].")
parser.add_argument("-ids", action='store_true', help="You can flag all attributes created during the transaction to be marked as \"to_ids\" or not.")
parser.add_argument("-c", "--categ", help="The category that will be assigned to the uploaded samples. Valid options are: Payload delivery, Artifacts dropped, Payload Installation, External Analysis.")
parser.add_argument("-i", "--info", help="Used to populate the event info field if no event ID supplied.")
parser.add_argument("-a", "--analysis", type=int, help="The analysis level of the newly created event, if applicatble. [0-2]")
parser.add_argument("-t", "--threat", type=int, help="The threat level ID of the newly created event, if applicatble. [0-3]")
args = parser.parse_args()
misp = init(url, priv)
files = []
if os.path.isfile(args.upload):
files = [args.upload]
elif os.path.isdir(args.upload):
files = [f for f in glob.iglob(os.path.join(args.upload + '*'))]
upload_files(misp, args.event, files, args.distrib, args.ids, args.categ, args.info, args.analysis, args.threat)

View File

@ -6,7 +6,8 @@
import json
import datetime
import requests
import os
import base64
class PyMISP(object):
"""
@ -117,6 +118,56 @@ class PyMISP(object):
session = self.__prepare_session()
return session.delete(self.rest.format(event_id))
# ######### Create/update events through the API #########
def _create_event(self, distribution, threat_level_id, analysis, info):
# Setup details of a new event
if distribution not in [0, 1, 2, 3]:
return False
if threat_level_id not in [0, 1, 2, 3]:
return False
if analysis not in [0, 1, 2]:
return False
return {'distribution': int(distribution), 'info': info,
'threat_level_id': int(threat_level_id), 'analysis': analysis}
def upload_sample(self, event_id, filepaths, distribution, to_ids, category,
info, analysis, threat_level_id):
to_post = {'request': {'files': []}}
if not isinstance(event_id, int):
# New event
postcontent = self._create_event(distribution, threat_level_id,
analysis, info)
if postcontent:
to_post['request'].update(postcontent)
else:
# invalid new event
return False
else:
to_post['request'].update({'event_id': int(event_id)})
if to_ids not in [True, False]:
return False
to_post['request'].update({'to_ids': to_ids})
if category not in ['Payload delivery', 'Artifacts dropped',
'Payload Installation', 'External Analysis']:
return False
to_post['request'].update({'category': category})
files = []
for path in filepaths:
if not os.path.isfile(path):
continue
with open(path, 'rb') as f:
files.append({'filename': os.path.basename(path),
'data': base64.b64encode(f.read())})
to_post['request']['files'] = files
session = self.__prepare_session()
return session.post(self.rest.format('upload_sample'), data=json.dumps(to_post))
# ######## REST Search #########
def __prepare_rest_search(self, values, not_values):