Submit malware samples

_submit now includes malware samples (zipped content from misp)
_import checks when no vti_results are returned + bugfix
pull/70/head
Koen Van Impe 2016-11-18 18:23:52 +01:00
parent 5624104b77
commit 3253d92b42
2 changed files with 45 additions and 19 deletions

View File

@ -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:

View File

@ -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"