Malware triage with MISP - Dynamic malware analysis¶
Introduction¶
- UUID: 8bada769-763a-46c3-a9b2-6b4808a47d36
- Started from issue 3
- State: Published : demo version with output
- Purpose: This playbook extends the results retrieved with static malware analysis in the malware triage playbook and does the dynamic malware analysis with one or more malware sandboxes.
- The results are stored in a MISP report and sent to Mattermost.
- Tags: [ "malware", "triage", "sandbox", "incidentresponse", "ir", "dfir" ]
- External resources: VMRay, Hybrid-Analysis, VirusTotal, Mattermost
- Target audience: SOC, CSIRT, CTI
- Notes:
- First run the malware triage playbook for static analysis,
- Then run this playbook for dynamic analysis
Playbook¶
- Malware triage with MISP - Dynamic malware analysis
- Introduction
- Preparation
- PR:1 Initialise environment
- PR:2 Verify MISP modules
- PR:3 Load helper functions
- PR:4 Set helper variables
- PR:5 Setup MISP event link
- PR:6 Load the file objects
- Investigate
- IN:1 Submit to VMRay
- IN:2 Submit to Hybrid-Analysis
- IN:3 Submit to VirusTotal
- IN:4 Create MISP report for investigation
- Summary
- EN:1 MISP indicators
- EN:2 Print the dynamic malware analysis report
- EN:3 Create the summary of the playbook
- EN:4 Send a summary to Mattermost
- EN:5 End of the playbook
- External references
- Technical details
Preparation¶
PR:1 Initialise environment¶
This section initialises the playbook environment and loads the required Python libraries.
The credentials for MISP (API key) and other services are loaded from the file keys.py
in the directory vault. A PyMISP object is created to interact with MISP and the active MISP server is displayed. By printing out the server name you know that it's possible to connect to MISP. In case of a problem PyMISP will indicate the error with PyMISPError: Unable to connect to MISP
.
The contents of the keys.py
file should contain at least :
misp_url="<MISP URL>" # The URL to our MISP server
misp_key="<MISP API KEY>" # The MISP API key
misp_verifycert=<True or False> # Ignore certificate errors
vmray_apikey=<KEY> # VMRay API key
hybridanalysis_apikey=<KEY> # Hybrid-analysis key
virustotal_apikey=<KEY> # VirusTotal key
# Initialise Python environment
import urllib3
import sys
import json
from pyfaup.faup import Faup
from prettytable import PrettyTable, MARKDOWN
from IPython.display import Image, display, display_markdown, HTML
from datetime import date
import requests
import uuid
#from uuid import uuid4
from pymisp import *
from pymisp.tools import GenericObjectGenerator
from pymisp.tools import make_binary_objects
import os
import time
import pefile
from datetime import datetime
import io
import zipfile
import base64
# Load the credentials
sys.path.insert(0, "../vault/")
from keys import *
if misp_verifycert is False:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
print("The \033[92mPython libraries\033[90m are loaded and the \033[92mcredentials\033[90m are read from the keys file.")
# Create the PyMISP object
misp = PyMISP(misp_url, misp_key, misp_verifycert)
print("I will use the MISP server \033[92m{}\033[90m for this playbook.\n\n".format(misp_url))
# Create headers for specific cases
misp_headers = {"Authorization": misp_key, "Content-Type": "application/json", "Accept": "application/json"}
The version of PyMISP recommended by the MISP instance (2.4.176) is newer than the one you're using now (2.4.173). Please upgrade PyMISP.
The Python libraries are loaded and the credentials are read from the keys file. I will use the MISP server https://misp.demo.cudeso.be/ for this playbook.
PR:2 Verify MISP modules¶
This playbook uses the MISP modules to obtain additional correlation or enrichment information. MISP modules are autonomous modules that can be used to extend MISP for new services such as expansion, import and export. The modules are written in Python 3 following a simple API interface. The objective is to ease the extensions of MISP functionalities without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration.
In the next cell we check if we have access to the MISP module server and if the required modules are enabled.
# Where can we find the local MISP Module server? You can leave this to the default setting in most cases.
misp_modules_url = "http://127.0.0.1:6666"
# How long do we wait between queries when using the MISP modules (API rate limiting of external service such as VirusTotal)
misp_modules_wait = 3
# Initiliasation
misp_modules = {}
misp_modules_headers = {
"Content-Type": "application/json",
"Accept": "application/json"
}
misp_modules_in_use = ["vmray_import"]
# Code block to query the MISP module server and check if our modules are enabled
res = requests.get("{}/modules".format(misp_modules_url), headers=misp_modules_headers)
for module in res.json():
for module_requested in misp_modules_in_use:
if module.get("name", False) == module_requested:
misp_modules[module_requested] = {"enabled": True, "input": module.get("mispattributes").get("input")}
print("Found the \033[92m{}\033[90m MISP module (Accepted input: {}).".format(module_requested, misp_modules[module_requested]["input"]))
print("\n")
Found the vmray_import MISP module (Accepted input: None).
PR:3 Load helper functions¶
The next cell contains helper functions that are used in this playbook.
Instead of distributing helper functions as separate Python files this playbook includes all the required code as one code cell. This makes portability of playbooks between instances easier. The downside is that functions defined in this playbook need to be defined again in other playbooks, which is not optimal for code re-use. For this iteration of playbooks it is chosen to include the code in the playbook (more portability), but you can easily create one "helper" file that contains all the helper code and then import that file in each playbook (for example by adding to the previous cell from helpers import *
). Note that the graphical workflow image is included as an external image. A missing image would not influence the further progress of the playbook.
def sandbox_calculate_risk_score(ratio):
'''
Calculate risk score and return the tag
'''
if ratio > 0:
if ratio >= 75:
tag = "misp:threat-level=\"high-risk\""
elif ratio >= 50:
tag = "misp:threat-level=\"medium-risk\""
#elif detection_ratio_perc >= 25:
else:
tag = "misp:threat-level=\"low-risk\""
else:
tag = "misp:threat-level=\"no-risk\""
return tag
PR:4 Set helper variables¶
This cell contains helper variables that are used in this playbook. Their usage is explained in the next steps of the playbook.
samples
: a dictionary of the objects that are created when the playbook progressessubmission_tags
: tags that are used when uploading samples to the sandbox
# Dictionary to store playbook results
samples = {}
# Tags to add to the malware submission
submission_tags = ["MISP", "playbook", "malwaretriage"]
# Helper variables
misp_event = False
summary = ""
PR:5 Setup MISP event link¶
This playbook does not create a new MISP event. It relies on an existing event and loads the file objects from that event. Ideally you start your investigation with a static analysis of the sample through the MISP playbook Malware Triage. Then, if the static analysis did not provide sufficient information, you can use malware sandboxes for dynamic analysis.
In the next cell, provide the MISP event ID or UUID in the variable event_link
.
# Provide an event ID or an event UUID
event_link = "97c61f93-a8e7-43a2-807a-1a7fe170f4db"
# Get the MISP event
misp_event = misp.get_event(event_link, pythonify=True)
if not "errors" in misp_event:
print("Fetched event \033[92m{}\033[90m with title \033[92m{}\033[90m.".format(event_link, misp_event.info))
print("Continue with the playbook.\n")
else:
print("Unable to get event with identifier \033[91m{}\033[90m".format(event_link))
print("It's not possibel to continue with the playbook.\n")
Fetched event 97c61f93-a8e7-43a2-807a-1a7fe170f4db with title Malware triage for incident in L2/L3. Continue with the playbook.
PR:6 Load file objects¶
Instead of loading samples from disk, the playbook loads the samples via the MISP file objects, from the event you identified earlier in event_link
(and now stored in misp_event
).
print("Searching for files in event {} {}".format(misp_event.info, misp_event.id))
for event_object in misp_event.Object:
if event_object.name == "file":
print("Found file object ...")
for attr in event_object.Attribute:
if attr.object_relation == "malware-sample":
print(" As malware-sample ...")
malware_sample = True
key = attr.value.split("|")[0]
print(" File \033[92m{}\033[90m with UUID {}".format(key, attr.uuid))
samples[key] = {}
samples[key]["fileobject"] = event_object
samples[key]["fileobject_uuid"] = event_object.uuid
for attribute in event_object.Attribute:
if attribute.object_relation == "md5":
samples[key]["md5"] = attribute.value
print(" MD5: \033[92m{}\033[90m".format(samples[key]["md5"]))
if attribute.object_relation == "sha256":
samples[key]["sha256"] = attribute.value
print(" SHA256: \033[92m{}\033[90m".format(samples[key]["sha256"]))
samples[key]["data"] = attr.data
# Prepare dictionary for the sandboxes
samples[key]["hybrid-analysis"] = {}
samples[key]["vmray"] = {}
samples[key]["virustotal"] = {}
print("\n")
for key, sample in samples.items():
print("Obtaining data for \033[92m{}\033[90m".format(key))
zf = zipfile.ZipFile(sample["data"])
sample_hashname = zf.namelist()[0]
data = zf.read(sample_hashname, b"infected")
zf.close()
sample["submitdata"] = data
print(" Got {} bytes".format(len(data)))
print("\n")
for key, sample in samples.items():
if len(sample["submitdata"]) > 0:
print("File \033[92m{}\033[90m is ready to be submitted to sandboxes".format(key))
Searching for files in event Malware triage for incident in L2/L3 3138 Found file object ... As malware-sample ... File 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run with UUID 7d7339c5-e616-4b05-87fa-aa2e2654a966 MD5: 7c9da2a2c29c0411e614322a02bc43fa SHA256: 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 Obtaining data for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Got 115256 bytes File 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run is ready to be submitted to sandboxes
Investigate¶
This section starts the investigation by submitting the samples to sandboxes and consists of two steps:
- First submit the sample to the sandbox so that the analysis jobs can start;
- And afterwards, once the analysis jobs have finished, collect the results.
Depending on your preference you can first execute all the submit sections and later, when the jobs have finished, come back and get collect the results.
Before submitting a sample to a sandbox make sure that you are allowed to share it outside your organisation. When in doubt, use PAP - Permissible Actions Protocol to describe where you can use the information. Also see the post on How to Support Defenders with the Permissible Actions Protocol.
IN:1 Submit to VMRay¶
The first sandbox is VMRay. There are a number of configuration settings for the submission:
- Share the hash with VirusTotal (set
vmray_shareable
to True) - Use reputation analysis (
vmray_enable_reputation
) - You can ignore specific objects from being imported in the MISP event (with
vmray_ignore_objects
). This is for example useful to ignore the list of processes if you do not have detection capabilities to track process creation - Include the sandbox signatures (with
vmray_signatures_in_report
). In VMRay, the signatures are part of the sb-sandbox object and can be quite comprehensive. For quick and easy-to-read reports it's advised to ignore them.
The number and type of jobs executed for analysis depend on your VMRay configuration. Submitted files create new jobs according to the default Jobrules of the sample type. The parameter vmray_jobrule_entries
can be used to specify alternative Jobrules. If you leave the variable to False, your default VMRay configuration is used.
# Share the hash with VirusTotal
#vmray_shareable = True
vmray_shareable = False
# Do reputation analysis
vmray_enable_reputation = True
# ignore these objects when importing the results
vmray_ignore_objects = ["process"]
# Include signatures in report?
vmray_signatures_in_report = False
# VMRay headers
vmray_headers = {
"accept": "application/json",
"Authorization": "api_key {}".format(vmray_apikey)
}
# Job rules
# Example: ["vmray:win10:def:adobe_reader-8", "vmray:win10:def:adobe_reader-6"]
# {"Windows PE (x86-32)": ["vmray:win10_64_th2:def:exe", "vmray:win7_32_sp1:def:exe"], "PDF Document": ["vmray:win10_64_th2-pdf:def:adobe-reader-64-DC-2018.011.20038"]}
vmray_jobrule_entries = False
Submit¶
Execute the next cell to sumit the samples to VMRay. This will output
- VMRay jobs
- Submission ID
- Sample ID
# Code block to submit sample to VMRay
for key, sample in samples.items():
print("Submit \033[92m{}\033[90m to VMRay.".format(key))
tags = ""
for tag in submission_tags:
tags = "{}{},".format(tags, tag)
submit_parameters = {
"tags": tags[:-1],
"shareable": vmray_shareable,
"enable_reputation": vmray_enable_reputation
}
if vmray_jobrule_entries:
submit_parameters["jobrule_entries"] = vmray_jobrule_entries
submit_file = {"sample_file": (key, io.BytesIO(sample["submitdata"]))}
response = requests.post("{}/rest/sample/submit".format(vmray_url), headers=vmray_headers, files=submit_file, data=submit_parameters)
if response.status_code == 200:
if response.json().get("result") == "ok":
response_json = response.json().get("data", {})
jobs = response_json.get("jobs", [])
if len(jobs) > 0:
print(" VMRay jobs")
for job in jobs:
print(" {} \033[92m{}\033[90m {}".format(job["job_type"], job["job_id"], job["job_vm_name"]))
submissions = response_json.get("submissions", [])
if len(submissions) > 0:
print(" VMRay submissions")
samples[key]["vmray"]["submissions"] = []
for submission in submissions:
print(" \033[92m{}\033[90m".format(submission["submission_id"]))
samples[key]["vmray"]["submissions"].append(submission["submission_id"])
vmray_samples = response_json.get("samples", [])
if len(vmray_samples) > 0:
print(" VMRay samples")
samples[key]["vmray"]["samples"] = []
for vmray_sample in vmray_samples:
print(" \033[92m{}\033[90m".format(vmray_sample["sample_id"]))
samples[key]["vmray"]["samples"].append(vmray_sample["sample_id"])
print("Successfully submitted malware sample.")
else:
print("Failed to submit malware sample. Status Code: \033[91m{}\033[90m {}".format(response.status_code, response.json().get("result")))
print(response.text)
Submit 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run to VMRay. VMRay submissions 13873809 VMRay samples 12102735 Successfully submitted malware sample.
Collect results¶
Analysing a sample in a sandbox takes time. Execute the next cell to collect the results. The playbook checks if all jobs for your sample are finished. Once they are finished, it will get the results and use the MISP VMRay import module to import the sandbox results into the MISP event.
# Collect the VMRay results
for key, sample in samples.items():
print("Process VMRay \033[92m{}\033[90m".format(key))
report_md = ""
# First check the submission is finished
submission_finished = False
for vmray_submission in sample["vmray"]["submissions"]:
response = requests.get("{}/rest/submission/{}".format(vmray_url, vmray_submission), headers=vmray_headers)
if response.status_code == 200:
submission_finished_status = response.json()["data"].get("submission_finished", "")
if not submission_finished_status:
print(" Not all jobs for submission \033[91m{}\033[90m have finished. Please try again later.".format(vmray_submission))
continue
else:
submission_finished = True
else:
print(" Unable to get submission \033[91m{}\033[90m status.".format(vmray_submission))
print(response.text)
# Jobs are finished, collect the results
if submission_finished:
print(" Submission \033[92m{}\033[90m is finished".format(sample["vmray"]["submissions"]))
for vmray_sample in sample["vmray"]["samples"]:
response = requests.get("{}/rest/sample/{}".format(vmray_url, vmray_sample), headers=vmray_headers)
if response.status_code == 200:
if response.json().get("result") == "ok":
response_json = response.json().get("data", {})
print(" Working on sample \033[92m{}\033[90m".format(vmray_sample))
samples[key]["vmray"]["sample_classifications"] = response_json.get("sample_classifications", [])
samples[key]["vmray"]["sample_highest_vti_score"] = response_json.get("sample_highest_vti_score", False)
samples[key]["vmray"]["sample_highest_vti_severity"] = response_json.get("sample_highest_vti_severity", False)
samples[key]["vmray"]["sample_severity"] = response_json.get("sample_severity", False)
samples[key]["vmray"]["sample_threat_names"] = response_json.get("sample_threat_names", [])
samples[key]["vmray"]["sample_verdict"] = response_json.get("sample_verdict", False)
samples[key]["vmray"]["sample_vti_score"] = response_json.get("sample_vti_score", False)
attribute = MISPAttribute()
attribute.value = response_json.get("sample_webif_url")
attribute.to_ids = False
attribute.category = "External analysis"
attribute.type = "link"
attribute.disable_correlation = True
attribute.comment = "Analysis with VMRay"
attribute_misp = misp.add_attribute(misp_event.uuid, attribute, pythonify=True)
if not "errors" in attribute_misp:
misp.add_object_reference(sample["fileobject"].add_reference(attribute_misp.uuid, "related-to"))
print(" Added link for {}".format(attribute.comment))
sample_vti_score = samples[key]["vmray"].get("sample_vti_score", 0)
if sample_vti_score:
tag = sandbox_calculate_risk_score(samples[key]["vmray"].get("sample_vti_score", 0))
if len(tag) > 0:
misp.tag(attribute_misp.uuid, tag)
report_md += "VMRay report: [{}]({})\n\n".format(response_json.get("sample_webif_url"), response_json.get("sample_webif_url"))
report_md += "- Verdict: **{}**\n".format(samples[key]["vmray"]["sample_verdict"])
report_md += "- Severity: **{}**\n".format(samples[key]["vmray"]["sample_severity"])
report_md += "- VTI score: **{}**\n".format(samples[key]["vmray"]["sample_vti_score"])
report_md += "- Highest severity: {}\n".format(samples[key]["vmray"]["sample_highest_vti_severity"])
report_md += "- Highest VTI score: {}\n".format(samples[key]["vmray"]["sample_highest_vti_score"])
if len(samples[key]["vmray"]["sample_classifications"]) > 0:
report_md += "#### Classifications\n"
for el in samples[key]["vmray"]["sample_classifications"]:
report_md += "- **{}**\n".format(el)
if len(samples[key]["vmray"]["sample_threat_names"]) > 0:
report_md += "#### Threat names\n"
for el in samples[key]["vmray"]["sample_threat_names"]:
report_md += "- **{}**\n".format(el)
#################################################################
# Now use the MISP VMRay import module
module_data = {
"module": "vmray_import",
"event_id": misp_event.id,
"config": {
"apikey": vmray_apikey,
"url": vmray_url,
"Sample ID": vmray_sample,
"Artifacts": "0",
"VTI": "1",
"IOCs": "1",
"Analysis Details": "0",
},
"data": ""
}
print(" Importing VMRay results")
module_comment = "From VMRay import for {}".format(key)
module_signatures = []
module_result = requests.post("{}/query".format(misp_modules_url), headers=misp_modules_headers, json=module_data)
if "results" in module_result.json() and len(module_result.json()["results"]) > 0:
module_result_json = module_result.json()["results"]
for misp_attribute in module_result_json.get("Attribute", []):
misp_attribute["comment"] = "{}{}".format(module_comment, misp_attribute.get("comment", ""))
created_attribute = misp.add_attribute(misp_event.uuid, misp_attribute, pythonify=True)
if not "errors" in created_attribute:
print(" Got {} \033[92m{}\033[90m".format(misp_attribute["type"], misp_attribute["value"]))
misp.add_object_reference(sample.get("fileobject").add_reference(created_attribute.uuid, "related-to"))
else:
print(" Unable to add {} \033[92m{}\033[90m to MISP event".format(misp_attribute["type"], misp_attribute["value"]))
for misp_object in module_result_json.get("Object", []):
if misp_object["name"] in vmray_ignore_objects:
continue
misp_object["comment"] = "{}{}".format(module_comment, misp_object.get("comment", ""))
if len(misp_object["Attribute"]) > 0:
created_object = misp.add_object(misp_event.uuid, misp_object, pythonify=True)
if not "errors" in created_object:
print(" Got \033[92m{}\033[90m ".format(misp_object["name"]))
misp.add_object_reference(sample.get("fileobject").add_reference(created_object.uuid, "related-to"))
if vmray_signatures_in_report:
if misp_object["name"] == "sb-signature":
for attribute in misp_object.get("Attribute", []):
if attribute.get("object_relation") == "signature":
module_signatures.append(attribute.get("value"))
else:
print(" Unable to add \033[92m{}\033[90m to MISP event".format(misp_object["name"]))
if len(module_signatures) > 0:
report_md += "#### Signatures\n"
for el in module_signatures:
report_md += "- {}\n".format(el)
print(" Finished sample")
samples[key]["vmray"]["report_md"] = report_md
Process VMRay 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Submission [13873809] is finished Working on sample 12102735 Added link for Analysis with VMRay Importing VMRay results Got sandbox-report Got sandbox-report Got sandbox-report Got sandbox-report Got sandbox-report Got sandbox-report Got sb-signature Got file Got file Got file Got registry-key Got file Got file Got file Got file Got file Finished sample
IN:2 Submit to Hybrid-Analysis¶
You can also submit the sample to Hybrid-Analysis.
When you submit a sample to Hybrid-Analysis you have to specify the environment in which the sandbox needs to execute the sample. The comment section lists the available IDs for environment_id
. Additionaly you can specify if you want to share sample with third parties (no_share_third_party
), if you want to allow community access (allow_community_access
) and if you want to use the hash lookup feature (no_hash_lookup
).
# Available environments ID:
# 400: 'Mac Catalina 64 bit (x86)',
# 310: 'Linux (Ubuntu 20.04, 64 bit)',
# 300: 'Linux (Ubuntu 16.04, 64 bit)',
# 200: 'Android Static Analysis',
# 160: 'Windows 10 64 bit',
# 140: 'Windows 11 64 bit',
# 120: 'Windows 7 64 bit',
# 110: 'Windows 7 32 bit (HWP Support)',
# 100: 'Windows 7 32 bit'
hybrid_environment_id = "120"
# When set to 'true', the sample is never shared with any third party. Default: true
hybrid_no_share_third_party = "true"
# When set to 'true', the sample will be available for the community. Default: true (Note: when 'no_share_third_party' is set to 'false', it won't be possible to set different value than 'true')
hybrid_allow_community_access = "false"
# Hash lookup
hybrid_no_hash_lookup = "false"
# Hybrid-analysis headers
hybridanalayis_headers = {
"accept": "application/json",
"api-key": hybridanalysis_apikey
}
Submit¶
Execute the next cell to sumit the samples to Hybrid-Analysis. This will output the Analysis ID.
# Code block to submit to Hybrid-Analysis
if hybrid_environment_id in ["400", "310", "300", "200", "160", "140", "120", "110", "100"]:
for key, sample in samples.items():
print("Submit \033[92m{}\033[90m".format(key))
tags = ""
for tag in submission_tags:
tags = "{} #{}".format(tags, tag)
submit_parameters = {
"environment_id": hybrid_environment_id,
"comment": tags,
"allow_community_access": hybrid_allow_community_access,
"no_share_third_party": hybrid_no_share_third_party,
"no_hash_lookup": hybrid_no_hash_lookup
}
submit_file = {"file": (key, io.BytesIO(sample["submitdata"]))}
url = "https://www.hybrid-analysis.com/api/v2/submit/file"
response = requests.post(url, headers=hybridanalayis_headers, files=submit_file, data=submit_parameters)
if response.status_code == 201:
analysis_id = response.json()["job_id"]
samples[key]["hybrid-analysis"]["job_id"] = analysis_id
print("Successfully submitted malware sample. Analysis ID: \033[92m{}\033[90m".format(analysis_id))
else:
print("Failed to submit malware sample. Status Code: \033[91m{}\033[90m".format(response.status_code))
print(response.text)
else:
print("Failed to submit malware sample. Not a valid environment_id: \033[91m{}\033[90m".format(environment_id))
Submit 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Successfully submitted malware sample. Analysis ID: 654e2ff21b36c7c9e2016289
Collect results¶
Execute the next cell to collect the results. The playbook will display the analysis state and only collect the results if all jobs are finished.
# Collect results from hybrid-analysis
for key, sample in samples.items():
if samples[key]["hybrid-analysis"].get("job_id", False):
state = False
job_id = samples[key]["hybrid-analysis"]["job_id"]
url = "https://www.hybrid-analysis.com/api/v2/"
response = requests.get("{}report/{}/summary".format(url, job_id), headers=hybridanalayis_headers)
samples[key]["hybrid-analysis"]["state"] = "Unknown"
if response.status_code == 200:
state = response.json().get("state", False)
samples[key]["hybrid-analysis"]["state"] = state
if state:
print("Status for {} ({}): \033[92m{}\033[90m".format(key, job_id, samples[key]["hybrid-analysis"]["state"]))
if samples[key]["hybrid-analysis"]["state"] == "SUCCESS":
print("Process \033[92m{}\033[90m".format(key))
response_json = response.json()
samples[key]["hybrid-analysis"]["classification_tags"] = response_json.get("classification_tags", "")
samples[key]["hybrid-analysis"]["type"] = response_json.get("type", "")
samples[key]["hybrid-analysis"]["threat_score"] = response_json.get("threat_score", 0)
samples[key]["hybrid-analysis"]["threat_level"] = response_json.get("threat_level", 0)
samples[key]["hybrid-analysis"]["verdict"] = response_json.get("verdict", "")
attribute = MISPAttribute()
hybrid_link = "https://www.hybrid-analysis.com/sample/{}/{}".format(response_json.get("sha256"), job_id)
attribute.value = hybrid_link
attribute.to_ids = False
attribute.category = "External analysis"
attribute.type = "link"
attribute.disable_correlation = True
attribute.comment = "Analysis with Hybrid-analysis"
attribute_misp = misp.add_attribute(misp_event.uuid, attribute, pythonify=True)
if not "errors" in attribute_misp:
misp.add_object_reference(sample["fileobject"].add_reference(attribute_misp.uuid, "related-to"))
print(" Added link for {}".format(attribute.comment))
threat_score = samples[key]["hybrid-analysis"].get("threat_score", 0)
if threat_score is None:
threat_score = 0
tag = sandbox_calculate_risk_score(threat_score)
if len(tag) > 0:
misp.tag(attribute_misp.uuid, tag)
attck_id = []
for mitre_attcks in response_json.get("mitre_attcks", []):
attck_id_descr = "{} : {} - {}".format(mitre_attcks.get("attck_id", ""), mitre_attcks.get("tactic", ""), mitre_attcks.get("technique", ""))
if attck_id_descr not in attck_id:
attck_id.append(attck_id_descr)
tag = "misp-galaxy:mitre-attack-pattern=\"{} - {}\"".format(mitre_attcks.get("technique", ""), mitre_attcks.get("attck_id", ""))
misp.tag(misp_event.uuid, tag)
print(" Tag event with {}".format(tag))
samples[key]["hybrid-analysis"]["mitre_attcks"] = attck_id
signatures = []
for signature in response_json.get("signatures", []):
if not (signature.get("category", False) == "General"):
signature_descr = "{} - {} (ATT&CK: {})".format(signature.get("category", ""), signature.get("name", ""), signature.get("attck_id", ""))
if signature_descr not in signatures:
signatures.append(signature_descr)
samples[key]["hybrid-analysis"]["signatures"] = signatures
report_md = ""
report_md += "Hybrid-Analysis report: [{}]({})\n\n".format(hybrid_link, hybrid_link)
report_md += "- Verdict: **{}**\n".format(samples[key]["hybrid-analysis"]["verdict"])
report_md += "- Threat score: **{}**\n".format(samples[key]["hybrid-analysis"]["threat_score"])
report_md += "- Threat level: **{}**\n".format(samples[key]["hybrid-analysis"]["threat_score"])
report_md += "- Type: **{}**\n".format(samples[key]["hybrid-analysis"]["type"])
if len(samples[key]["hybrid-analysis"]["classification_tags"]) > 0:
report_md += "#### Tags\n"
for el in samples[key]["hybrid-analysis"]["classification_tags"]:
report_md += "- **{}**\n".format(el)
if len(samples[key]["hybrid-analysis"]["mitre_attcks"]) > 0:
report_md += "#### MITRE ATT&CK\n"
for el in samples[key]["hybrid-analysis"]["mitre_attcks"]:
report_md += "- {}\n".format(el)
if len(samples[key]["hybrid-analysis"]["signatures"]) > 0:
report_md += "#### Signatures\n"
for el in samples[key]["hybrid-analysis"]["signatures"]:
report_md += "- {}\n".format(el)
print(" Finished sample")
samples[key]["hybrid-analysis"]["report_md"] = report_md
else:
print(" Not all jobs for submission \033[91m{}\033[90m have finished. Please try again later.".format(job_id))
Status for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run (654e2ff21b36c7c9e2016289): SUCCESS Process 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Added link for Analysis with Hybrid-analysis Tag event with misp-galaxy:mitre-attack-pattern="Native API - T1106" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task/Job - T1053" Tag event with misp-galaxy:mitre-attack-pattern="Windows Command Shell - T1059.003" Tag event with misp-galaxy:mitre-attack-pattern="Shared Modules - T1129" Tag event with misp-galaxy:mitre-attack-pattern="Malicious File - T1204.002" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task - T1053.005" Tag event with misp-galaxy:mitre-attack-pattern="Inter-Process Communication - T1559" Tag event with misp-galaxy:mitre-attack-pattern="Component Object Model - T1559.001" Tag event with misp-galaxy:mitre-attack-pattern="Component Object Model Hijacking - T1546.015" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task/Job - T1053" Tag event with misp-galaxy:mitre-attack-pattern="Registry Run Keys / Startup Folder - T1547.001" Tag event with misp-galaxy:mitre-attack-pattern="DLL Search Order Hijacking - T1574.001" Tag event with misp-galaxy:mitre-attack-pattern="Boot or Logon Autostart Execution - T1547" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task - T1053.005" Tag event with misp-galaxy:mitre-attack-pattern="DLL Side-Loading - T1574.002" Tag event with misp-galaxy:mitre-attack-pattern="AppInit DLLs - T1546.010" Tag event with misp-galaxy:mitre-attack-pattern="Dynamic-link Library Injection - T1055.001" Tag event with misp-galaxy:mitre-attack-pattern="Thread Execution Hijacking - T1055.003" Tag event with misp-galaxy:mitre-attack-pattern="Component Object Model Hijacking - T1546.015" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task/Job - T1053" Tag event with misp-galaxy:mitre-attack-pattern="Registry Run Keys / Startup Folder - T1547.001" Tag event with misp-galaxy:mitre-attack-pattern="DLL Search Order Hijacking - T1574.001" Tag event with misp-galaxy:mitre-attack-pattern="Process Injection - T1055" Tag event with misp-galaxy:mitre-attack-pattern="Boot or Logon Autostart Execution - T1547" Tag event with misp-galaxy:mitre-attack-pattern="Extra Window Memory Injection - T1055.011" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Task - T1053.005" Tag event with misp-galaxy:mitre-attack-pattern="DLL Side-Loading - T1574.002" Tag event with misp-galaxy:mitre-attack-pattern="AppInit DLLs - T1546.010" Tag event with misp-galaxy:mitre-attack-pattern="Timestomp - T1070.006" Tag event with misp-galaxy:mitre-attack-pattern="Modify Registry - T1112" Tag event with misp-galaxy:mitre-attack-pattern="Dynamic-link Library Injection - T1055.001" Tag event with misp-galaxy:mitre-attack-pattern="Thread Execution Hijacking - T1055.003" Tag event with misp-galaxy:mitre-attack-pattern="DLL Search Order Hijacking - T1574.001" Tag event with misp-galaxy:mitre-attack-pattern="Obfuscated Files or Information - T1027" Tag event with misp-galaxy:mitre-attack-pattern="Software Packing - T1027.002" Tag event with misp-galaxy:mitre-attack-pattern="Process Injection - T1055" Tag event with misp-galaxy:mitre-attack-pattern="File Deletion - T1070.004" Tag event with misp-galaxy:mitre-attack-pattern="Time Based Evasion - T1497.003" Tag event with misp-galaxy:mitre-attack-pattern="Extra Window Memory Injection - T1055.011" Tag event with misp-galaxy:mitre-attack-pattern="DLL Side-Loading - T1574.002" Tag event with misp-galaxy:mitre-attack-pattern="Indicator Removal from Tools - T1027.005" Tag event with misp-galaxy:mitre-attack-pattern="Deobfuscate/Decode Files or Information - T1140" Tag event with misp-galaxy:mitre-attack-pattern="Execution Guardrails - T1480" Tag event with misp-galaxy:mitre-attack-pattern="Query Registry - T1012" Tag event with misp-galaxy:mitre-attack-pattern="Application Window Discovery - T1010" Tag event with misp-galaxy:mitre-attack-pattern="File and Directory Discovery - T1083" Tag event with misp-galaxy:mitre-attack-pattern="System Information Discovery - T1082" Tag event with misp-galaxy:mitre-attack-pattern="System Location Discovery - T1614" Tag event with misp-galaxy:mitre-attack-pattern="Process Discovery - T1057" Tag event with misp-galaxy:mitre-attack-pattern="System Network Configuration Discovery - T1016" Tag event with misp-galaxy:mitre-attack-pattern="System Language Discovery - T1614.001" Tag event with misp-galaxy:mitre-attack-pattern="System Service Discovery - T1007" Tag event with misp-galaxy:mitre-attack-pattern="System Owner/User Discovery - T1033" Tag event with misp-galaxy:mitre-attack-pattern="Time Based Evasion - T1497.003" Tag event with misp-galaxy:mitre-attack-pattern="System Time Discovery - T1124" Tag event with misp-galaxy:mitre-attack-pattern="Lateral Tool Transfer - T1570" Tag event with misp-galaxy:mitre-attack-pattern="Local Data Staging - T1074.001" Tag event with misp-galaxy:mitre-attack-pattern="Application Layer Protocol - T1071" Tag event with misp-galaxy:mitre-attack-pattern="Ingress Tool Transfer - T1105" Tag event with misp-galaxy:mitre-attack-pattern="Symmetric Cryptography - T1573.001" Tag event with misp-galaxy:mitre-attack-pattern="Scheduled Transfer - T1029" Tag event with misp-galaxy:mitre-attack-pattern="Service Stop - T1489" Finished sample
IN:3 Submit to VirusTotal¶
You can also submit the sample to VirusTotal. There are no configuration options for this sandbox.
Submit¶
Execute the next cell to sumit the samples to VirusTotal. This will output the Analysis ID.
vt_headers = {
"accept": "application/json",
"x-apikey": virustotal_apikey
}
vt_url = "https://www.virustotal.com/api/v3/files"
for key, sample in samples.items():
print("Submit \033[92m{}\033[90m".format(key))
submit_file = {"file": (key, io.BytesIO(sample["submitdata"]))}
response = requests.post(vt_url, headers=vt_headers, files=submit_file, data=submit_parameters)
if response.status_code == 200:
analysis_id = response.json()["data"]["id"]
samples[key]["virustotal"]["analysis_id"] = analysis_id
print("Successfully submitted malware sample. Analysis ID: \033[92m{}\033[90m".format(analysis_id))
else:
print("Failed to submit malware sample. Status Code: \033[91m{}\033[90m".format(response.status_code))
print(response.text)
Submit 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Successfully submitted malware sample. Analysis ID: N2M5ZGEyYTJjMjljMDQxMWU2MTQzMjJhMDJiYzQzZmE6MTY5OTcwMDcwNw==
Collect results¶
Execute the next cell to collect the results. The playbook will display the analysis state and only collect the results if all jobs are finished.
# Collect results from VirusTotal
for key, sample in samples.items():
if samples[key]["virustotal"].get("analysis_id", False):
analysis_id = samples[key]["virustotal"]["analysis_id"]
vt_url = "https://www.virustotal.com/api/v3/analyses/"
result = requests.get("{}{}".format(vt_url, analysis_id), headers=vt_headers)
vt_status = False
if result.status_code == 200:
if "data" in result.json() and len(result.json()["data"]) > 0:
result_json = result.json()["data"]["attributes"]
status = result_json.get("status", [])
if status == "completed":
vt_status = True
if vt_status:
print("Process \033[92m{}\033[90m".format(key))
report_md = ""
vt_link = "https://www.virustotal.com/gui/file/{}".format(sample["sha256"])
report_md += "VirusTotal report: [{}]({})\n\n".format(vt_link, vt_link)
stats = result_json.get("stats", False)
if stats:
samples[key]["virustotal"]["harmless"] = stats.get("harmless", 0)
samples[key]["virustotal"]["type-unsupported"] = stats.get("type-unsupported", 0)
samples[key]["virustotal"]["suspicious"] = stats.get("suspicious", 0)
samples[key]["virustotal"]["confirmed-timeout"] = stats.get("confirmed-timeout", 0)
samples[key]["virustotal"]["timeout"] = stats.get("timeout", 0)
samples[key]["virustotal"]["failure"] = stats.get("failure", 0)
samples[key]["virustotal"]["malicious"] = stats.get("malicious", 0)
samples[key]["virustotal"]["undetected"] = stats.get("undetected", 0)
report_md += "#### Statistics\n"
report_md += "- Malicious : **{}**\n".format(samples[key]["virustotal"]["malicious"])
report_md += "- Suspicious : **{}**\n".format(samples[key]["virustotal"]["suspicious"])
report_md += "- Harmless : **{}**\n".format(samples[key]["virustotal"]["harmless"])
av_results = result_json.get("results", False)
if av_results:
av_results_detail = []
for av_result in av_results:
if av_results[av_result].get("result", "") not in av_results_detail:
av_results_detail.append(av_results[av_result].get("result"))
samples[key]["virustotal"]["results"] = av_results_detail
if len(samples[key]["virustotal"]["results"]) > 0:
report_md += "#### AV results\n"
for el in samples[key]["virustotal"]["results"]:
report_md += "- {}\n".format(el)
attribute = MISPAttribute()
attribute.value = vt_link
attribute.to_ids = False
attribute.category = "External analysis"
attribute.type = "link"
attribute.disable_correlation = True
attribute.comment = "Analysis with VirusTotal"
attribute_misp = misp.add_attribute(misp_event.uuid, attribute, pythonify=True)
if not "errors" in attribute_misp:
misp.add_object_reference(sample["fileobject"].add_reference(attribute_misp.uuid, "related-to"))
print(" Added link for {}".format(attribute.comment))
print(" Finished sample")
samples[key]["virustotal"]["report_md"] = report_md
else:
print(" Not all jobs for analysis \033[91m{}\033[90m have finished. Please try again later.".format(analysis_id))
else:
print(" Error while getting analysis \033[91m{}\033[90m.".format(analysis_id))
Process 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run Added link for Analysis with VirusTotal Finished sample
IN:4 Create MISP report for investigation¶
Create a report with the results of the dynamic malware analysis.
summary_iv = "## Investigation report\n\n"
current_date = datetime.now()
formatted_date = current_date.strftime("%Y-%m-%d")
at_least_one_sandbox = False
for key, sample in samples.items():
summary_iv += "## Analysis for {}\n".format(key)
summary_iv += "- Date: **{}**\n".format(formatted_date)
summary_iv += "- MISP event: **{}** ({})\n".format(misp_event.info, misp_event.id)
summary_iv += "### File details\n"
summary_iv += " - MD5: {}\n".format(sample["md5"])
summary_iv += " - SHA256: {}\n".format(sample["sha256"])
if len(sample["vmray"].get("report_md", "")) > 0:
summary_iv += "### VMRay\n"
summary_iv += sample["vmray"]["report_md"]
at_least_one_sandbox = True
else:
print("There are no \033[91mVMRay results\033[90m.")
summary_iv += "\n\n"
if len(sample["hybrid-analysis"].get("report_md", "")) > 0:
summary_iv += "### Hybrid-Analysis\n"
summary_iv += sample["hybrid-analysis"]["report_md"]
at_least_one_sandbox = True
else:
print("There are no \033[91mHybrid-Analysis results\033[90m.")
summary_iv += "\n\n"
if len(sample["virustotal"].get("report_md", "")) > 0:
summary_iv += "### VirusTotal\n"
summary_iv += sample["virustotal"]["report_md"]
at_least_one_sandbox = True
else:
print("There are no \033[91mVirusTotal results\033[90m.")
summary_iv += "\n\n"
event_title = "Dynamic malware analysis - sandboxes"
if at_least_one_sandbox:
print("Creating MISP report \033[92m{}\033[90m".format(event_title))
chunk_size = 61500
for i in range(0, len(summary_iv), chunk_size):
chunk = summary_iv[i:i + chunk_size]
event_report = MISPEventReport()
event_title_edit = event_title
if i > 0:
event_title_edit = "{} ({} > {})".format(event_title, i, i + chunk_size)
event_report.name = event_title_edit
event_report.content = chunk
result = misp.add_event_report(misp_event.id, event_report)
if "EventReport" in result:
print(" Report ID: \033[92m{}\033[90m".format(result.get("EventReport", []).get("id", 0)))
else:
print("Failed to create report for \033[91m{}\033[90m.".format(event_title))
else:
print("Failed to create report for \033[91m{}\033[90m.".format(event_title))
Creating MISP report Dynamic malware analysis - sandboxes Report ID: 799
Closure¶
In this closure or end step we create a summary of the actions that were performed by the playbook. The summary is printed in the playbook and can also be send to a chat channel.
EN:1 MISP indicators¶
The next section first queries MISP for the indicators added to the MISP event that is linked to the execution of this playbook.
The indicators are stored in the variable indicator_table
(table format) and indicator_raw_list
(in raw format) which is used in a later section to create the playbook summary.
In order to avoid too generic indicators, such as files temporarily created by processes, you can ignore all filename indicators that contain .tmp with the setting ignore_filename_with_tmp
.
# Ignore filenames with ".tmp"
ignore_filename_with_tmp = True
# Get all the indicators for our event and store this is in a table. We can also use this for the summary.
print("Searching for indicators ...")
indicator_search = misp.search("attributes", uuid=misp_event.uuid, to_ids=True, pythonify=True)
indicator_raw_list = []
indicator_table = PrettyTable()
if len(indicator_search) > 0:
indicator_table.field_names = ["Type", "Category", "Indicator", "Comment"]
indicator_table.align["Type"] = "l"
indicator_table.align["Category"] = "l"
indicator_table.align["Indicator"] = "l"
indicator_table.align["Comment"] = "l"
indicator_table.border = True
if ignore_filename_with_tmp:
print("Ignoring filenames that contain .tmp")
for indicator in indicator_search:
if indicator.value not in indicator_raw_list:
if ignore_filename_with_tmp and indicator.type == "filename" and ".tmp" in indicator.value:
continue
else:
comment = indicator.comment
if hasattr(indicator, 'object_relation'):
object_ind = misp.get_object(indicator.object_id, pythonify=True)
comment = "From '{}' object {} {}".format(object_ind.name, object_ind.comment.lower(), comment.lower())
indicator_table.add_row([indicator.type, indicator.category, indicator.value, comment])
indicator_raw_list.append(indicator.value)
print("Got \033[92m{}\033[90m indicator(s) from the event \033[92m{}\033[90m ({}).\n".format(len(indicator_raw_list), misp_event.info, misp_event.id))
else:
print("\033[93mNo indicators found in the event \033[92m{}\033[90m ({})".format(misp_event.info, misp_event.id))
Searching for indicators ... Ignoring filenames that contain .tmp Got 62 indicator(s) from the event Malware triage for incident in L2/L3 (3138).
Raw list of MISP indicators¶
The indicators are now stored in indicator_search
(as Python objects) and indicator_raw_list
(in raw format, only the indicators). Execute the next cell to display them in a table format. The table is also included in the summary sent to Mattermost and TheHive.
if len(indicator_raw_list) > 0:
print(indicator_table.get_string(sortby="Type"))
print("\n\nIndicator list in raw format:")
print("---------------------------------------------------")
for el in indicator_raw_list:
print("{}".format(el))
print("---------------------------------------------------")
+----------------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ | Type | Category | Indicator | Comment | +----------------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ | authentihash | Payload delivery | b91eed3087eb869ce43d4bcabbaad79060841dc4ab7c3db2b98a1f8fca04bba0 | From 'pe' object | | domain | Network activity | time.windows.com | From 'domain-ip' object from virustotal_public for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 | | filename | Payload delivery | 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | From 'file' object | | filename | Payload delivery | 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run.exe | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: read, access | | filename | Payload delivery | fzievdd.exe | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: access, create, write | | filename | Payload delivery | mjzvmtn.dll | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: write, access, create | | filename | Payload delivery | rimimqj.dll | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: write, access, create | | filename | Payload delivery | ssshsob.exe | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: access, create, write | | filename | Payload delivery | xmiurbe.exe | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: access, create, write | | imphash | Payload delivery | 7aa54ce8454f118e02c919266ff521f2 | From 'pe' object | | ip-dst | Network activity | 192.229.211.108 | From 'domain-ip' object from virustotal_public for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 | | ip-dst | Network activity | 20.99.184.37 | From 'domain-ip' object from virustotal_public for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 | | ip-dst | Network activity | 51.145.123.29 | From 'domain-ip' object from virustotal_public for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 | | malware-sample | Payload delivery | 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run|7c9da2a2c29c0411e614322a02bc43fa | From 'file' object | | md5 | Payload delivery | 00c90b434055885fea10efdaa92e02bb | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | 12648870b189c2a8c307c1448fc8c5c4 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | 18832ac624c03eba91201260e25330cc | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | 279477c2f6761efd7e430d6085effb23 | From 'pe-section' object | | md5 | Payload delivery | 2c9d5a1a1066abd409068cd9bd0b64fd | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | 3af3865a886d50bb9b9b95a5de7afe43 | From 'pe-section' object | | md5 | Payload delivery | 739cecc519d887b6a272092f2cbd452c | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | 7c9da2a2c29c0411e614322a02bc43fa | From 'file' object | | md5 | Payload delivery | d33d91653cdcd0ed4f0ff73e513b6231 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | md5 | Payload delivery | d3b17d7f60d308473257174163c0ddc8 | From 'pe-section' object | | md5 | Payload delivery | f3ef8f5f50c383f611fe5405132ed9cb | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | regkey | Persistence mechanism | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs | From 'registry-key' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run operations: write, access | | sha1 | Payload delivery | 0b58c6c50cf4efe42c16bb33e5ab77da7d30c933 | From 'pe-section' object | | sha1 | Payload delivery | 155bce06d6c11cb1a79ea83b28c4eac83ec6747a | From 'file' object | | sha1 | Payload delivery | 3c79f884308bd6cf8439aaad147d39559b1fb9f4 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | 40da6bc629d3d56548da6027e7af3bfda22e0138 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | 62bc855db92be6907cfe6d2f484f5b681c24e954 | From 'pe-section' object | | sha1 | Payload delivery | 8a25c0f51ab59f138f7a2d6eec3b02a0f1cfee2c | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | 95519daae5d00c3e71c77e609830f8158e3ce2a0 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | ab6b042e28f3f6d7fa9f5422969e2bc3f45734ca | From 'pe-section' object | | sha1 | Payload delivery | adef7330416b5421d380cc6ab83a62c0c78efe5e | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | be6b290f3cb1066ab0a95e23c8e1c52b35dcbd70 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha1 | Payload delivery | c6c14cf0ced531e3accaa44e269bfcdb03a1e32d | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | 2bf73ba779299149c517fa3ededafba120758735924d3a870c888b079733c563 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | 52acf49676be14af1e163b42eb95a0bd505180afe18f8992cb688f899b5c9421 | From 'pe-section' object | | sha256 | Payload delivery | 7343d852beeb90cade016c633736b8054704fc3d101c56b6afe7f1ca4fd0818c | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | 84b878b84057bbcd42bd690df724602444855e2b6a43a2408f678a97d732160a | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 | From 'file' object | | sha256 | Payload delivery | 9a4396535137366f70e521daab62792d52379a7e4336e170ae73ab921a9ea6eb | From 'pe-section' object | | sha256 | Payload delivery | c44000d2a2fe81723c0ea163affb3f7262b0a5f1bdd318d43529a5dcdb91c03c | From 'pe-section' object | | sha256 | Payload delivery | d33331efb749682e30a81900a4021215d798f7ec2a0f971755fdab1a0be9abf0 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | e3db46032386876c667cdf45d69c1d9c9024085b3ca8aae4d70d4e764e6e9138 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | e592f51952bd1c03ddeac626560d06fb34db30bf4f2da19818da07302ee8576c | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha256 | Payload delivery | f9a3a334eda062abcbb68dcd83b6c6fa7180495b23973fe01e640c2a244d4e2c | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | sha512 | Payload delivery | 0e4ca2b4bedadb669a9409428ecd6951b61ac51c612a9b5dbff08e7ca9eae9b3752b27ca7376d13f4537290a2350d8b6549f08853bb4af2e9cd6ed052ff31d0e | From 'pe-section' object | | sha512 | Payload delivery | 107c9158b729d61aa56523767810f2bf5b50e7b5173e01b540806fc97a35aab341704492eb9289fd06d9b05058c98f1efbb82927c916451d7dee27e11abef5c2 | From 'pe-section' object | | sha512 | Payload delivery | 8d6dc72eda5994100300c8b7c9b78b09d5bae0b003657fb9ee8ed29d5c8168d52563bab631e07eae5476c7d6e0177415ca0ab7a55402673cb36851ce1abd2c87 | From 'file' object | | sha512 | Payload delivery | fa3b3c4f5421b33ed896127121249abe7105b6339b833b159a004cb57c49e2033ba10304db788789b8cff9e2a5dc44535b6a92d53a953fb6a107b08488b76f1c | From 'pe-section' object | | ssdeep | Payload delivery | 3072:6igRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCE:Vw/IFwDox+UGg5XzlCE | From 'pe-section' object | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQ6:yw/IFwDox+UGg5XzlCQ6 | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQG:yw/IFwDox+UGg5XzlCQG | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQO:yw/IFwDox+UGg5XzlCQO | From 'file' object | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQS:yw/IFwDox+UGg5XzlCQS | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQT:yw/IFwDox+UGg5XzlCQT | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQV:yw/IFwDox+UGg5XzlCQV | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQY:yw/IFwDox+UGg5XzlCQY | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 384:oqiiPzvxc/i0kG9WV+wG2aWgVrEjMVxCKWJBD2Z8c3c5uJzuLQ:oqiavYimMGRTtE0CKWJB6fs5uq | From 'file' object from vmray import for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run | | ssdeep | Payload delivery | 48:iulcDSzlFkvGc8D4avldieYeP4xMAmnZPvXBs+vujqakP9yMB:i8c25Fk+1DBvJgxMLZLvj0MB | From 'pe-section' object | +----------------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ Indicator list in raw format: --------------------------------------------------- 3af3865a886d50bb9b9b95a5de7afe43 0b58c6c50cf4efe42c16bb33e5ab77da7d30c933 9a4396535137366f70e521daab62792d52379a7e4336e170ae73ab921a9ea6eb fa3b3c4f5421b33ed896127121249abe7105b6339b833b159a004cb57c49e2033ba10304db788789b8cff9e2a5dc44535b6a92d53a953fb6a107b08488b76f1c 3072:6igRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCE:Vw/IFwDox+UGg5XzlCE 279477c2f6761efd7e430d6085effb23 ab6b042e28f3f6d7fa9f5422969e2bc3f45734ca c44000d2a2fe81723c0ea163affb3f7262b0a5f1bdd318d43529a5dcdb91c03c 0e4ca2b4bedadb669a9409428ecd6951b61ac51c612a9b5dbff08e7ca9eae9b3752b27ca7376d13f4537290a2350d8b6549f08853bb4af2e9cd6ed052ff31d0e 48:iulcDSzlFkvGc8D4avldieYeP4xMAmnZPvXBs+vujqakP9yMB:i8c25Fk+1DBvJgxMLZLvj0MB d3b17d7f60d308473257174163c0ddc8 62bc855db92be6907cfe6d2f484f5b681c24e954 52acf49676be14af1e163b42eb95a0bd505180afe18f8992cb688f899b5c9421 107c9158b729d61aa56523767810f2bf5b50e7b5173e01b540806fc97a35aab341704492eb9289fd06d9b05058c98f1efbb82927c916451d7dee27e11abef5c2 7aa54ce8454f118e02c919266ff521f2 b91eed3087eb869ce43d4bcabbaad79060841dc4ab7c3db2b98a1f8fca04bba0 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run 7c9da2a2c29c0411e614322a02bc43fa 155bce06d6c11cb1a79ea83b28c4eac83ec6747a 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 8d6dc72eda5994100300c8b7c9b78b09d5bae0b003657fb9ee8ed29d5c8168d52563bab631e07eae5476c7d6e0177415ca0ab7a55402673cb36851ce1abd2c87 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run|7c9da2a2c29c0411e614322a02bc43fa 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQO:yw/IFwDox+UGg5XzlCQO time.windows.com 192.229.211.108 20.99.184.37 51.145.123.29 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run.exe 12648870b189c2a8c307c1448fc8c5c4 3c79f884308bd6cf8439aaad147d39559b1fb9f4 d33331efb749682e30a81900a4021215d798f7ec2a0f971755fdab1a0be9abf0 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQG:yw/IFwDox+UGg5XzlCQG ssshsob.exe 00c90b434055885fea10efdaa92e02bb 8a25c0f51ab59f138f7a2d6eec3b02a0f1cfee2c 2bf73ba779299149c517fa3ededafba120758735924d3a870c888b079733c563 384:oqiiPzvxc/i0kG9WV+wG2aWgVrEjMVxCKWJBD2Z8c3c5uJzuLQ:oqiavYimMGRTtE0CKWJB6fs5uq mjzvmtn.dll rimimqj.dll HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs 739cecc519d887b6a272092f2cbd452c adef7330416b5421d380cc6ab83a62c0c78efe5e e592f51952bd1c03ddeac626560d06fb34db30bf4f2da19818da07302ee8576c 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQ6:yw/IFwDox+UGg5XzlCQ6 xmiurbe.exe 2c9d5a1a1066abd409068cd9bd0b64fd 95519daae5d00c3e71c77e609830f8158e3ce2a0 e3db46032386876c667cdf45d69c1d9c9024085b3ca8aae4d70d4e764e6e9138 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQV:yw/IFwDox+UGg5XzlCQV fzievdd.exe f3ef8f5f50c383f611fe5405132ed9cb be6b290f3cb1066ab0a95e23c8e1c52b35dcbd70 84b878b84057bbcd42bd690df724602444855e2b6a43a2408f678a97d732160a 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQT:yw/IFwDox+UGg5XzlCQT 18832ac624c03eba91201260e25330cc c6c14cf0ced531e3accaa44e269bfcdb03a1e32d f9a3a334eda062abcbb68dcd83b6c6fa7180495b23973fe01e640c2a244d4e2c 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQY:yw/IFwDox+UGg5XzlCQY d33d91653cdcd0ed4f0ff73e513b6231 40da6bc629d3d56548da6027e7af3bfda22e0138 7343d852beeb90cade016c633736b8054704fc3d101c56b6afe7f1ca4fd0818c 3072:bigRqGiY/IA8wD5iZ4gKczBxGV6+UIXlaMA+uzlCQS:yw/IFwDox+UGg5XzlCQS ---------------------------------------------------
EN:2 Print the dynamic malware analysis report¶
Print the MISP report with the dynamic malware analysis results.
print(summary_iv)
# Or print with parsed markdown
# display_markdown(summary_iv, raw=True)
## Investigation report ## Analysis for 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4.do-not-run - Date: **2023-11-11** - MISP event: **Malware triage for incident in L2/L3** (3138) ### File details - MD5: 7c9da2a2c29c0411e614322a02bc43fa - SHA256: 8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4 ### VMRay VMRay report: [https://cloud.vmray.com/samples/12102735](https://cloud.vmray.com/samples/12102735) - Verdict: **malicious** - Severity: **malicious** - VTI score: **96** - Highest severity: malicious - Highest VTI score: 96 #### Threat names - **Mal/Generic-S** ### Hybrid-Analysis Hybrid-Analysis report: [https://www.hybrid-analysis.com/sample/8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4/654e2ff21b36c7c9e2016289](https://www.hybrid-analysis.com/sample/8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4/654e2ff21b36c7c9e2016289) - Verdict: **malicious** - Threat score: **100** - Threat level: **100** - Type: **MS-DOS executable PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows, MZ for MS-DOS** #### MITRE ATT&CK - T1106 : Execution - Native API - T1053 : Execution - Scheduled Task/Job - T1059.003 : Execution - Windows Command Shell - T1129 : Execution - Shared Modules - T1204.002 : Execution - Malicious File - T1053.005 : Execution - Scheduled Task - T1559 : Execution - Inter-Process Communication - T1559.001 : Execution - Component Object Model - T1546.015 : Persistence - Component Object Model Hijacking - T1053 : Persistence - Scheduled Task/Job - T1547.001 : Persistence - Registry Run Keys / Startup Folder - T1574.001 : Persistence - DLL Search Order Hijacking - T1547 : Persistence - Boot or Logon Autostart Execution - T1053.005 : Persistence - Scheduled Task - T1574.002 : Persistence - DLL Side-Loading - T1546.010 : Persistence - AppInit DLLs - T1055.001 : Privilege Escalation - Dynamic-link Library Injection - T1055.003 : Privilege Escalation - Thread Execution Hijacking - T1546.015 : Privilege Escalation - Component Object Model Hijacking - T1053 : Privilege Escalation - Scheduled Task/Job - T1547.001 : Privilege Escalation - Registry Run Keys / Startup Folder - T1574.001 : Privilege Escalation - DLL Search Order Hijacking - T1055 : Privilege Escalation - Process Injection - T1547 : Privilege Escalation - Boot or Logon Autostart Execution - T1055.011 : Privilege Escalation - Extra Window Memory Injection - T1053.005 : Privilege Escalation - Scheduled Task - T1574.002 : Privilege Escalation - DLL Side-Loading - T1546.010 : Privilege Escalation - AppInit DLLs - T1070.006 : Defense Evasion - Timestomp - T1112 : Defense Evasion - Modify Registry - T1055.001 : Defense Evasion - Dynamic-link Library Injection - T1055.003 : Defense Evasion - Thread Execution Hijacking - T1574.001 : Defense Evasion - DLL Search Order Hijacking - T1027 : Defense Evasion - Obfuscated Files or Information - T1027.002 : Defense Evasion - Software Packing - T1055 : Defense Evasion - Process Injection - T1070.004 : Defense Evasion - File Deletion - T1497.003 : Defense Evasion - Time Based Evasion - T1055.011 : Defense Evasion - Extra Window Memory Injection - T1574.002 : Defense Evasion - DLL Side-Loading - T1027.005 : Defense Evasion - Indicator Removal from Tools - T1140 : Defense Evasion - Deobfuscate/Decode Files or Information - T1480 : Defense Evasion - Execution Guardrails - T1012 : Discovery - Query Registry - T1010 : Discovery - Application Window Discovery - T1083 : Discovery - File and Directory Discovery - T1082 : Discovery - System Information Discovery - T1614 : Discovery - System Location Discovery - T1057 : Discovery - Process Discovery - T1016 : Discovery - System Network Configuration Discovery - T1614.001 : Discovery - System Language Discovery - T1007 : Discovery - System Service Discovery - T1033 : Discovery - System Owner/User Discovery - T1497.003 : Discovery - Time Based Evasion - T1124 : Discovery - System Time Discovery - T1570 : Lateral Movement - Lateral Tool Transfer - T1074.001 : Collection - Local Data Staging - T1071 : Command and Control - Application Layer Protocol - T1105 : Command and Control - Ingress Tool Transfer - T1573.001 : Command and Control - Symmetric Cryptography - T1029 : Exfiltration - Scheduled Transfer - T1489 : Impact - Service Stop #### Signatures - Unusual Characteristics - Matched Compiler/Packer signature (ATT&CK: T1027.002) - Unusual Characteristics - Reads the windows installation language (ATT&CK: T1614.001) - Installation/Persistence - Tries to access non-existent files (executable) (ATT&CK: T1083) - Installation/Persistence - Reads files (ATT&CK: T1083) - Installation/Persistence - Creates a thread in a self process (ATT&CK: T1055.003) - Installation/Persistence - Opens registry keys (ATT&CK: T1012) - Installation/Persistence - Dropped files (ATT&CK: T1105) - Installation/Persistence - Touches files (ATT&CK: T1083) - Installation/Persistence - Writes files (ATT&CK: None) - Installation/Persistence - Contains ability to load modules (API string) (ATT&CK: T1106) - Installation/Persistence - Contains ability to schedule tasks using COM objects (ATT&CK: T1053.005) - Installation/Persistence - Connects to LPC ports (ATT&CK: T1559) - Installation/Persistence - Queries registry keys (ATT&CK: T1012) - Installation/Persistence - Shows ability to use execution guardrails (ATT&CK: T1480) - Anti-Detection/Stealthyness - Contains ability to load/free library (API string) (ATT&CK: T1055.001) - Anti-Detection/Stealthyness - Found PE header in memory (ATT&CK: T1055) - Anti-Detection/Stealthyness - Contains ability to delay execution by waiting for signal/timeout (API string) (ATT&CK: None) - Anti-Detection/Stealthyness - Contains ability to modify registry key/value (API string) (ATT&CK: T1112) - Anti-Detection/Stealthyness - Calls an API typically used to load a resource in memory (ATT&CK: T1106) - Environment Awareness - Contains ability to retrieve open application windows (API string) (ATT&CK: T1010) - Environment Awareness - Contains ability to retrieve the OS information (API string) (ATT&CK: T1082) - Environment Awareness - Contains ability to retrieve file time (API string) (ATT&CK: T1070.006) - Environment Awareness - Calls an API typically used to retrieve local language (ATT&CK: T1614) - Environment Awareness - Contains ability to read software policies (ATT&CK: T1082) - Environment Awareness - Contains ability to retrieve information about the current system (API string) (ATT&CK: T1082) - Environment Awareness - Contains ability to perform scheduled transfer (API string) (ATT&CK: T1029) - Environment Awareness - Calls an API typically used to determine if process is running under WOW64 (ATT&CK: T1057) - Environment Awareness - Calls an API typically used to get system version information (ATT&CK: T1082) - Environment Awareness - Reads the active computer name (ATT&CK: T1082) - Environment Awareness - Contains ability to retrieve machine time (API string) (ATT&CK: T1124) - Environment Awareness - Calls an API typically used to get product type (ATT&CK: T1082) - Environment Awareness - Calls an API typically used to retrieve account information for specified SID (ATT&CK: T1033) - Environment Awareness - Queries TCP/IP interface details (ATT&CK: T1012) - Environment Awareness - Reads the cryptographic machine GUID (ATT&CK: T1082) - Spyware/Information Retrieval - Contains ability to retrieve file and directory information (API string) (ATT&CK: T1083) - Spyware/Information Retrieval - Contains ability to read files (API string) (ATT&CK: T1083) - Spyware/Information Retrieval - Contains ability to enumerate process and/or its information (API string) (ATT&CK: T1057) - Spyware/Information Retrieval - Contains ability to retrieve a module handle (API string) (ATT&CK: T1082) - Spyware/Information Retrieval - Contains ability to query network adapter information (API string) (ATT&CK: T1016) - Spyware/Information Retrieval - Contains ability to retrieve address of exported function from a DLL (API string) (ATT&CK: T1106) - Spyware/Information Retrieval - Contains ability to retrieve the fully qualified path of module (API string) (ATT&CK: T1106) - Spyware/Information Retrieval - Contains ability to retrieve usernames and/or user information (API string) (ATT&CK: T1033) - Spyware/Information Retrieval - Contains ability to retrieve the time elapsed since the system was started (API string) (ATT&CK: T1497.003) - Spyware/Information Retrieval - Contains ability to query registry keys (API string) (ATT&CK: T1012) - Spyware/Information Retrieval - Calls an API typically used for taking snapshot of the specified processes (ATT&CK: T1057) - Network Related - Found potential URL in binary/memory (ATT&CK: T1071) - Network Related - Found potential IP address in binary/memory (ATT&CK: T1071) - Cryptographic Related - Sample file has high entropy (likely encrypted/compressed content) (ATT&CK: T1027) - Cryptographic Related - Contains XOR operation loops [Stream disassembly] (ATT&CK: T1027.005) - Cryptographic Related - Shows ability to deobfuscate/decode files or information (ATT&CK: T1140) - Cryptographic Related - Shows ability to obfuscate file or information (ATT&CK: T1027) - Cryptographic Related - Shows ability to use encryption for command and control traffic (ATT&CK: T1573.001) - System Security - Contains ability to delete files/directories (API string) (ATT&CK: T1070.004) - System Security - Queries services related registry keys (ATT&CK: T1007) - System Security - Contains ability to terminate a process (API string) (ATT&CK: T1489) - System Security - Contains ability to write files (API string) (ATT&CK: T1105) - System Security - Opens the Kernel Security Device Driver (KsecDD) of Windows (ATT&CK: None) - Unusual Characteristics - CRC value set in PE header does not match actual value (ATT&CK: T1027) - Unusual Characteristics - Entrypoint in PE header is within an uncommon section (ATT&CK: T1027) - Unusual Characteristics - Imports suspicious APIs (ATT&CK: T1106) - Installation/Persistence - Modifies auto-execute functionality by setting/creating a value in the registry (ATT&CK: T1547.001) - Installation/Persistence - Writes a PE file header to disc (ATT&CK: T1105) - Installation/Persistence - Drops executable files (ATT&CK: T1105) - Anti-Reverse Engineering - PE file has unusual entropy sections (ATT&CK: T1027.002) - Anti-Reverse Engineering - PE file is packed with MPress Packer (ATT&CK: T1027.002) - Environment Awareness - Contains ability to retrieve a module handle (ATT&CK: T1082) - Network Related - Contains ability to query network adapter information (ATT&CK: T1016) - System Security - Writes registry keys (ATT&CK: T1112) - External Systems - Sample was identified as malicious by at least one Antivirus engine (ATT&CK: None) - Installation/Persistence - Found an indicator for a scheduled task trigger (ATT&CK: T1053) - Installation/Persistence - Loads the task scheduler COM API (ATT&CK: T1559.001) - Installation/Persistence - Modifies AppInit DLLs registry entries to achieve persistence (ATT&CK: T1546.010) - External Systems - Sample was identified as malicious by a large number of Antivirus engines (ATT&CK: None) - External Systems - Sample detected by CrowdStrike Static Analysis and ML with relatively high confidence (ATT&CK: None) - External Systems - Sample was identified as malicious by a trusted Antivirus engine (ATT&CK: None) ### VirusTotal VirusTotal report: [https://www.virustotal.com/gui/file/8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4](https://www.virustotal.com/gui/file/8eff35b85b7f9a95534f58fd38ddb6a4d7d9b799fb8b1ea650f898b0ecf702d4) #### Statistics - Malicious : **63** - Suspicious : **0** - Harmless : **0** #### AV results - W32.AIDetectMalware - Trojan.Win32.ShipUp.4!c - malicious (high confidence) - Gen:Variant.Zusy.481611 - Generic.mg.7c9da2a2c29c0411 - None - BehavesLike.Win32.Generic.cc - Generic.Malware.AI.DDS - Trojan.Kryptik.Win32.1265477 - Suspicious.Win32.Save.a - Trojan ( 0049c30b1 ) - TrojanDropper:Win32/ShipUp.889511d1 - win/malicious_confidence_100% (W) - Gen:NN.ZexaF.36792.hmraaaVOT2b - Trojan.Win32.Redirect.FR - ML.Attribute.HighConfidence - Win32/TrojanDropper.Gepys.AA - Malicious - Win.Malware.Cerbu-6912939-0 - HEUR:Trojan.Win32.ShipUp.gen - Trojan.Win32.ShipUp.kcaklx - Win32:Trojan-gen - Trojan.Win32.Gepys.ta - Trojan/W32.Shipup.115256 - Troj/Agent-BAES - Trojan.TR/Crypt.XPACK.xzlzu - Trojan.Redirect.147 - TROJ_AGENT_057726.TOMB - malicious.high.ml.score - Gen:Variant.Zusy.481611 (B) - Trojan.Dropper - Trojan/ShipUp.kf - Detected - TR/Crypt.XPACK.xzlzu - W32/S-28b406b2!Eldorado - Trojan/Win32.ShipUp - malware.kb.b.998 - Trojan.Win32.Agent.bot!s1 - TrojWare.Win32.Carberp.BA@7fquvi - Trojan.Zusy.D7594B - Trojan.Win.Z.Zusy.115256.BF - Trojan:Win32/SmokeLoader - Malicious (score: 100) - Trojan/Win32.Toga.R217139 - suspicious - GenericRXHE-EL!7C9DA2A2C29C - malware (ai score=89) - BScope.Trojan.Carberp.2013 - unsafe - Trj/Genetic.gen - Trojan.Win32.74795 - Dropper.Gepys!8.15D (TFE:5:geSfbHCvwnG) - Static AI - Malicious PE - W32/Gepys.AA!tr - malicious.6d6c11 - MALICIOUS
EN:3 Create the summary of the playbook¶
The next section creates a summary and stores the output in the variable summary
in Markdown format. It also stores an intro text in the variable intro
. These variables are later used when sending information to Mattermost or TheHive.
summary = "# MISP Playbook summary\nDynamic malware analysis with MISP event: **{}** ({}/events/view/{}). ".format(misp_event.info, misp_url, misp_event.id)
summary += "\n"
summary += summary_iv
summary += "\n"
intro = summary
summary += "## Indicators\n\n"
summary += "### Indicators table\n\n"
if len(indicator_raw_list) > 0:
indicator_table.set_style(MARKDOWN)
summary += indicator_table.get_string(sortby="Type")
summary += "\n\n\n"
summary += "### Indicators in **raw format**\n\n"
for indicator in indicator_raw_list:
summary += "{}\n\n".format(indicator)
summary += "\n"
else:
summary += "There are no indicators"
summary += "\n\n"
summary += "\n\n"
print("The \033[92msummary\033[90m of the playbook is available.\n")
The summary of the playbook is available.
EN:4 Send a summary to Mattermost¶
Now you can send the summary to Mattermost. You can send the summary in two ways by selecting one of the options for the variable send_to_mattermost_option
in the next cell.
- The default option where the entire summary is in the chat, or
- a short intro and the summary in a card
For this playbook we rely on a webhook in Mattermost. You can add a webhook by choosing the gear icon in Mattermost, then choose Integrations and then Incoming Webhooks. Set a channel for the webhook and lock the webhook to this channel with "Lock to this channel".
send_to_mattermost_option = "via a chat message"
#send_to_mattermost_option = "via a chat message with card"
message = False
if send_to_mattermost_option == "via a chat message":
message = {"username": mattermost_playbook_user, "text": summary}
elif send_to_mattermost_option == "via a chat message with card":
message = {"username": mattermost_playbook_user, "text": intro, "props": {"card": summary}}
if message:
r = requests.post(mattermost_hook, data=json.dumps(message))
r.raise_for_status()
if message and r.status_code == 200:
print("Summary is \033[92msent to Mattermost.\n")
else:
print("\033[91mFailed to sent summary\033[90m to Mattermost.\n")
Summary is sent to Mattermost.
EN:5 End of the playbook¶
print("\033[92m End of the playbook")
End of the playbook
External references¶
Technical details¶
Documentation¶
This playbook requires these Python libraries to exist in the environment where the playbook is executed. You can install them with pip install <library>
.
pyfaup
chardet
PrettyTable
ipywidgets
pefile
mwdblib
Colour codes¶
The output from Python displays some text in different colours. These are the colour codes
Red = '\033[91m'
Green = '\033[92m'
Blue = '\033[94m'
Cyan = '\033[96m'
White = '\033[97m'
Yellow = '\033[93m'
Magenta = '\033[95m'
Grey = '\033[90m'
Black = '\033[90m'
Default = '\033[99m'