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 Submit a sample to VMRay
TODO: TODO:
# Deal with malicious samples (ZIP file, 'infected')
# Deal with archive submissions # Deal with archive submissions
''' '''
@ -15,12 +14,13 @@ import json
import base64 import base64
import io import io
import zipfile
from ._vmray.vmray_rest_api import VMRayRESTAPI from ._vmray.vmray_rest_api import VMRayRESTAPI
misperrors = {'error': 'Error'} misperrors = {'error': 'Error'}
mispattributes = {'input': ['attachment'], 'output': ['text', 'sha1', 'sha256', 'md5', 'link']} mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['text', 'sha1', 'sha256', 'md5', 'link']}
moduleinfo = {'version': '0.1', 'author': 'Koen Van Impe', moduleinfo = {'version': '0.2', 'author': 'Koen Van Impe',
'description': 'Submit a sample to VMRay', 'description': 'Submit a sample to VMRay',
'module-type': ['expansion']} 'module-type': ['expansion']}
moduleconfig = ['apikey', 'url', 'shareable', 'do_not_reanalyze', 'do_not_include_vmrayjobids'] moduleconfig = ['apikey', 'url', 'shareable', 'do_not_reanalyze', 'do_not_include_vmrayjobids']
@ -38,8 +38,23 @@ def handler(q=False):
try: try:
data = request.get("data") data = request.get("data")
attachment = request.get("attachment") if 'malware-sample' in request:
data = base64.b64decode(data) # 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: except:
misperrors['error'] = "Unable to process submited sample data" misperrors['error'] = "Unable to process submited sample data"
return misperrors return misperrors
@ -74,10 +89,10 @@ def handler(q=False):
do_not_include_vmrayjobids = False do_not_include_vmrayjobids = False
include_vmrayjobids = not do_not_include_vmrayjobids include_vmrayjobids = not do_not_include_vmrayjobids
if data and attachment: if data and sample_filename:
args = {} args = {}
args["shareable"] = shareable 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 args["reanalyze"] = reanalyze
try: try:

View File

@ -84,6 +84,7 @@ def handler(q=False):
# Get all information on the sample, returns a set of finished analyze jobs # Get all information on the sample, returns a set of finished analyze jobs
data = vmrayGetInfoAnalysis(api, sample_id) data = vmrayGetInfoAnalysis(api, sample_id)
if data["data"]: if data["data"]:
vti_patterns_found = False
for analysis in data["data"]: for analysis in data["data"]:
analysis_id = analysis["analysis_id"] analysis_id = analysis["analysis_id"]
@ -93,17 +94,23 @@ def handler(q=False):
if analysis_data: if analysis_data:
p = vmrayVtiPatterns(analysis_data["vti_patterns"]) p = vmrayVtiPatterns(analysis_data["vti_patterns"])
if p: if p and len(p["results"]) > 0:
if include_analysisid: vti_patterns_found = True
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"})
vmray_results = {'results': vmray_results["results"] + p["results"]} 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) # Clean up (remove doubles)
vmray_results = vmrayCleanup(vmray_results) if vti_patterns_found:
return vmray_results vmray_results = vmrayCleanup(vmray_results)
return vmray_results
else:
misperrors['error'] = "No vti_results returned or jobs not finished"
return misperrors
else: else:
misperrors['error'] = "Unable to fetch sample id %u" % (sample_id) misperrors['error'] = "Unable to fetch sample id %u" % (sample_id)
return misperrors return misperrors
@ -172,6 +179,8 @@ def vmrayVtiPatterns(vti_patterns):
content = vmrayGeneric(pattern) content = vmrayGeneric(pattern)
elif only_network_info is False and pattern["category"] == "_process" and pattern["operation"] == "_install_ipc_endpoint": elif only_network_info is False and pattern["category"] == "_process" and pattern["operation"] == "_install_ipc_endpoint":
content = vmrayGeneric(pattern, "mutex", 1) 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": elif only_network_info is False and pattern["category"] == "_anti_analysis" and pattern["operation"] == "_delay_execution":
content = vmrayGeneric(pattern) content = vmrayGeneric(pattern)
@ -240,9 +249,11 @@ def vmrayGeneric(el, attr="", attrpos=1):
if content: if content:
if attr: if attr:
content_split = content.split("\"") content_split = content.split("\"")
content_split[attrpos] = vmraySanitizeInput(content_split[attrpos]) # Attributes are between open " and close "; so use >
r["values"].append(content_split[attrpos]) if len(content_split) > attrpos:
r["types"] = [attr] 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, # Adding the value also as text to get the extra description,
# but this is pretty useless for "url" # but this is pretty useless for "url"