mirror of https://github.com/MISP/misp-modules
Submit malware samples
_submit now includes malware samples (zipped content from misp) _import checks when no vti_results are returned + bugfixpull/70/head
parent
5624104b77
commit
3253d92b42
|
@ -6,7 +6,6 @@ Submit sample to VMRay.
|
|||
Submit a sample to VMRay
|
||||
|
||||
TODO:
|
||||
# Deal with malicious samples (ZIP file, 'infected')
|
||||
# Deal with archive submissions
|
||||
|
||||
'''
|
||||
|
@ -15,12 +14,13 @@ import json
|
|||
import base64
|
||||
|
||||
import io
|
||||
import zipfile
|
||||
|
||||
from ._vmray.vmray_rest_api import VMRayRESTAPI
|
||||
|
||||
misperrors = {'error': 'Error'}
|
||||
mispattributes = {'input': ['attachment'], 'output': ['text', 'sha1', 'sha256', 'md5', 'link']}
|
||||
moduleinfo = {'version': '0.1', 'author': 'Koen Van Impe',
|
||||
mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['text', 'sha1', 'sha256', 'md5', 'link']}
|
||||
moduleinfo = {'version': '0.2', 'author': 'Koen Van Impe',
|
||||
'description': 'Submit a sample to VMRay',
|
||||
'module-type': ['expansion']}
|
||||
moduleconfig = ['apikey', 'url', 'shareable', 'do_not_reanalyze', 'do_not_include_vmrayjobids']
|
||||
|
@ -38,8 +38,23 @@ def handler(q=False):
|
|||
|
||||
try:
|
||||
data = request.get("data")
|
||||
attachment = request.get("attachment")
|
||||
data = base64.b64decode(data)
|
||||
if 'malware-sample' in request:
|
||||
# malicious samples are encrypted with zip (password infected) and then base64 encoded
|
||||
sample_filename = request.get("malware-sample").split("|",1)[0]
|
||||
data = base64.b64decode(data)
|
||||
fl = io.BytesIO(data)
|
||||
zf = zipfile.ZipFile(fl)
|
||||
sample_hashname = zf.namelist()[0]
|
||||
data = zf.read(sample_hashname,b"infected")
|
||||
zf.close()
|
||||
elif 'attachment' in request:
|
||||
# All attachments get base64 encoded
|
||||
sample_filename = request.get("attachment")
|
||||
data = base64.b64decode(data)
|
||||
|
||||
else:
|
||||
misperrors['error'] = "No malware sample or attachment supplied"
|
||||
return misperrors
|
||||
except:
|
||||
misperrors['error'] = "Unable to process submited sample data"
|
||||
return misperrors
|
||||
|
@ -74,10 +89,10 @@ def handler(q=False):
|
|||
do_not_include_vmrayjobids = False
|
||||
include_vmrayjobids = not do_not_include_vmrayjobids
|
||||
|
||||
if data and attachment:
|
||||
if data and sample_filename:
|
||||
args = {}
|
||||
args["shareable"] = shareable
|
||||
args["sample_file"] = {'data': io.BytesIO(data), 'filename': attachment}
|
||||
args["sample_file"] = {'data': io.BytesIO(data), 'filename': sample_filename}
|
||||
args["reanalyze"] = reanalyze
|
||||
|
||||
try:
|
||||
|
|
|
@ -84,6 +84,7 @@ def handler(q=False):
|
|||
# Get all information on the sample, returns a set of finished analyze jobs
|
||||
data = vmrayGetInfoAnalysis(api, sample_id)
|
||||
if data["data"]:
|
||||
vti_patterns_found = False
|
||||
for analysis in data["data"]:
|
||||
analysis_id = analysis["analysis_id"]
|
||||
|
||||
|
@ -93,17 +94,23 @@ def handler(q=False):
|
|||
|
||||
if analysis_data:
|
||||
p = vmrayVtiPatterns(analysis_data["vti_patterns"])
|
||||
if p:
|
||||
if include_analysisid:
|
||||
url1 = "https://cloud.vmray.com/user/analysis/view?from_sample_id=%u" % sample_id
|
||||
url2 = "&id=%u" % analysis_id
|
||||
url3 = "&sub=%2Freport%2Foverview.html"
|
||||
p["results"].append({"values": url1 + url2 + url3, "types": "link"})
|
||||
if p and len(p["results"]) > 0:
|
||||
vti_patterns_found = True
|
||||
vmray_results = {'results': vmray_results["results"] + p["results"]}
|
||||
|
||||
if include_analysisid:
|
||||
a_id = {'results': []}
|
||||
url1 = "https://cloud.vmray.com/user/analysis/view?from_sample_id=%u" % sample_id
|
||||
url2 = "&id=%u" % analysis_id
|
||||
url3 = "&sub=%2Freport%2Foverview.html"
|
||||
a_id["results"].append({ "values": url1 + url2 + url3, "types": "link" })
|
||||
vmray_results = {'results': vmray_results["results"] + a_id["results"] }
|
||||
# Clean up (remove doubles)
|
||||
vmray_results = vmrayCleanup(vmray_results)
|
||||
return vmray_results
|
||||
if vti_patterns_found:
|
||||
vmray_results = vmrayCleanup(vmray_results)
|
||||
return vmray_results
|
||||
else:
|
||||
misperrors['error'] = "No vti_results returned or jobs not finished"
|
||||
return misperrors
|
||||
else:
|
||||
misperrors['error'] = "Unable to fetch sample id %u" % (sample_id)
|
||||
return misperrors
|
||||
|
@ -172,6 +179,8 @@ def vmrayVtiPatterns(vti_patterns):
|
|||
content = vmrayGeneric(pattern)
|
||||
elif only_network_info is False and pattern["category"] == "_process" and pattern["operation"] == "_install_ipc_endpoint":
|
||||
content = vmrayGeneric(pattern, "mutex", 1)
|
||||
elif only_network_info is False and pattern["category"] == "_process" and pattern["operation"] == "_crashed_process":
|
||||
content = vmrayGeneric(pattern)
|
||||
|
||||
elif only_network_info is False and pattern["category"] == "_anti_analysis" and pattern["operation"] == "_delay_execution":
|
||||
content = vmrayGeneric(pattern)
|
||||
|
@ -240,9 +249,11 @@ def vmrayGeneric(el, attr="", attrpos=1):
|
|||
if content:
|
||||
if attr:
|
||||
content_split = content.split("\"")
|
||||
content_split[attrpos] = vmraySanitizeInput(content_split[attrpos])
|
||||
r["values"].append(content_split[attrpos])
|
||||
r["types"] = [attr]
|
||||
# Attributes are between open " and close "; so use >
|
||||
if len(content_split) > attrpos:
|
||||
content_split[attrpos] = vmraySanitizeInput(content_split[attrpos])
|
||||
r["values"].append(content_split[attrpos])
|
||||
r["types"] = [attr]
|
||||
|
||||
# Adding the value also as text to get the extra description,
|
||||
# but this is pretty useless for "url"
|
||||
|
|
Loading…
Reference in New Issue