-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b317da1
commit 2ec6377
Showing
2 changed files
with
305 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# Disclaimer this code is not maintained by core devs | ||
# pymisp is known to break api on updates. | ||
# So you need it? You fix it! | ||
|
||
import os | ||
import json | ||
import logging | ||
|
||
from lib.cuckoo.common.config import Config | ||
from lib.cuckoo.common.constants import CUCKOO_ROOT | ||
|
||
try: | ||
from pymisp import PyMISP | ||
from pymisp import logger as pymisp_logger | ||
|
||
pymisp_logger.setLevel(logging.ERROR) | ||
HAVE_MISP = True | ||
except ImportError: | ||
print("Missed pymisp dependency. Run: poetry run pip install pymisp==2.4.168") | ||
HAVE_MISP = False | ||
|
||
log = logging.getLogger() | ||
|
||
external_cfg = Config("externalservices") | ||
misp_url = "" | ||
MISP_HASH_LOOKUP = False | ||
|
||
if HAVE_MISP: | ||
misp_url = external_cfg.misp.url | ||
misp = PyMISP(misp_url, external_cfg.misp.apikey, False, "json") | ||
MISP_HASH_LOOKUP = external_cfg.misp.hash_lookup | ||
|
||
|
||
def misp_hash_lookup(sha256: str, task_id: str, file_info: dict): | ||
|
||
if not MISP_HASH_LOOKUP: | ||
return | ||
|
||
# Initialize MISP Variables | ||
threat_actor_tag = "" | ||
threat_actor = "Not Applicable" | ||
threat_actor_list = [] | ||
threat_actor_dict = {} | ||
event_link = [] | ||
link_list = [] | ||
event_tag = "" | ||
tag_dict = {} | ||
tag = "" | ||
related_events_dict = {} | ||
galaxy_cluster_dict = {} | ||
|
||
# Search MISP for any events with attributes having the same hash as the submitted sample | ||
response = misp.search("attributes", value=sha256, return_format="json", pythonify=True) | ||
|
||
# For exporting of MISP Attribute and MISP Event JSON File | ||
attribute_json_response = misp.search("attributes", value=sha256, return_format="json", includeCorrelations=1) | ||
event_json_response = misp.get_event(response[0].event_id, pythonify=False) | ||
try: | ||
analysis_path = os.path.join(CUCKOO_ROOT, "storage", "analyses", task_id) | ||
attribute_json = json.dumps(attribute_json_response, indent=4) | ||
with open(os.path.join(analysis_path, "misp_attribute.json"), "w") as outfile: | ||
outfile.write(attribute_json) | ||
event_json = json.dumps(event_json_response, indent=4) | ||
with open(os.path.join(analysis_path, "misp_event.json"), "w") as outfile: | ||
outfile.write(event_json) | ||
except Exception as e: | ||
log.error("Exporting of MISP JSON Files have been skipped: " + e) | ||
|
||
# Retrieve desired information regarding the event if there is a relevant response | ||
if response: | ||
event = misp.get_event(response[0].event_id, pythonify=True) | ||
event_link = f"{misp_url}/events/view/" + str(response[0].event_id) | ||
galaxy_link = f"{misp_url}/galaxy_clusters/view/" | ||
search_tag_link = f"{misp_url}/events/index/searchtag:" | ||
ids_links = [ | ||
(f"{misp_url}/events/nids/snort/download/{response[0].event_id}"), | ||
(f"{misp_url}/events/nids/suricata/download/{response[0].event_id}"), | ||
] | ||
event_info = str(event).split("info=")[1].rsplit(")", 1)[0] | ||
|
||
log.debug("Submitted samples is related to MISP event: %s", str(event)) | ||
for attribute in event["Attribute"]: | ||
if "type=link" in str(attribute): | ||
link_list = [value for key, value in attribute.items() if key == "value"] | ||
|
||
# Get descriptions for Galaxy Clusters that match associated Tags | ||
for galaxy in event["Galaxy"]: | ||
for key, value in galaxy.items(): | ||
galaxy_cluster_dict = { | ||
cluster["value"].title(): [cluster["id"], cluster["description"]] for cluster in value if key == "GalaxyCluster" | ||
} | ||
|
||
for tag in event["Tag"]: | ||
event_tag_dict = {} | ||
event_tag = "" | ||
# Iterate through every tag to get the tag key and value for display in web UI | ||
for key, value in tag.items(): | ||
if any(pattern in str(tag) for pattern in ("threat-actor", "intrusion-set", "group")): | ||
threat_actor_tag = str(tag) | ||
threat_actor = threat_actor_tag.split('="')[1].split('")>')[0] | ||
threat_actor_list.append(threat_actor) | ||
# Filter out irrelevant tags | ||
elif key == "id" and any(pattern not in str(tag) for pattern in ("workflow", "tlp", "type", "osint", "OSINT")): | ||
# e.g. mitre-attack-pattern | ||
event_tag_name = str(tag).split("name=")[1].split('")>')[0].split(":")[1].split('="')[0].title() | ||
# e.g. Symmetric Cryptography - T1573.001 | ||
event_tag = str(tag).split("name=")[1].split('")>')[0].split(":")[1].split('="')[1].title() | ||
if event_tag in galaxy_cluster_dict: | ||
event_tag_dict[event_tag] = [value, galaxy_cluster_dict[event_tag][1]] | ||
else: | ||
event_tag_dict[event_tag] = [value, 0] | ||
if event_tag_name not in tag_dict.keys(): | ||
tag_dict[event_tag_name] = event_tag_dict | ||
else: | ||
# e.g. 'Mitre-Enterprise-Attack-Intrusion-Set': {'Dragonok - G0017': ['1099', '...'], 'Winnti Group - G0044': ['1107', '...']} | ||
tag_dict[event_tag_name].update(event_tag_dict) | ||
# Get a list of MISP event/s related to the current MISP event (if any) | ||
related_events = event["RelatedEvent"] | ||
for related_event in related_events: | ||
for key, value in related_event.items(): | ||
related_event_dict = {} | ||
dict_id = misp_url + "/events/view/" + str(value["id"]) | ||
related_event_dict[dict_id] = value["info"] | ||
related_events_dict.update(related_event_dict) | ||
|
||
# initialize list of threat actors | ||
all_threat_actors = [] | ||
all_intrusion_sets = [] | ||
all_enterprise_attack_intrusion_sets = [] | ||
all_microsoft_activity_groups = [] | ||
|
||
try: | ||
# Search for threat actor description (id 59 --> misp threat actor galaxy) | ||
all_threat_actors = misp.search_galaxy_clusters(59) | ||
# Search for intrusion set description (id 35 --> misp intrusion set galaxy) | ||
all_intrusion_sets = misp.search_galaxy_clusters(35) | ||
# Search for enterprise attack intrusion set description (id 26 --> enterprise attack intrusion set galaxy) | ||
all_enterprise_attack_intrusion_sets = misp.search_galaxy_clusters(26) | ||
# Search for microsoft activity groups description (id 20 --> microsoft activity groups galaxy) | ||
all_microsoft_activity_groups = misp.search_galaxy_clusters(20) | ||
# CURRENTLY USELESS BECAUSE NO ASSOCIATION WITH CURRENT EVENTS | ||
# # Search for 360.net threat actors description (id 1 --> 360.net threat actor galaxy) | ||
# all_360net_threat_actors = misp.search_galaxy_clusters(1) | ||
except Exception as e: | ||
log.error("Could not access MISP Galaxy Information: %s", str(e)) | ||
|
||
all_galaxies = all_threat_actors + all_intrusion_sets + all_enterprise_attack_intrusion_sets + all_microsoft_activity_groups | ||
|
||
# Loop through list of threat actor(s) to retrieve their description(s) | ||
for threat_actor in threat_actor_list: | ||
# this line will ensure that threat actors appear even if they do not have related description in MISP | ||
threat_actor_dict[threat_actor] = [0, 0] | ||
for galaxy_cluster in all_galaxies: | ||
if galaxy_cluster["GalaxyCluster"]["value"] == threat_actor: | ||
# e.g. "threat_actor" : { "Sofacy" : [ "The Sofacy Group is ..." , "9926" ] } | ||
threat_actor_dict[threat_actor] = [ | ||
galaxy_cluster["GalaxyCluster"]["description"], | ||
galaxy_cluster["GalaxyCluster"]["id"], | ||
] | ||
|
||
|
||
file_info.setdefault("misp", {}) | ||
file_info["misp"] = { | ||
"threat_actor": threat_actor_dict, | ||
"event_link": event_link, | ||
"event_info": event_info, | ||
"event_tags": tag_dict, | ||
"galaxy_link": galaxy_link, | ||
"search_tag_link": search_tag_link, | ||
"ids_links": ids_links, | ||
"links": link_list, | ||
"related_events": related_events_dict, | ||
"url": misp_url, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
{% load key_tags %} | ||
|
||
{% if file.misp.event_link %} | ||
<div class="card-header"> | ||
<center><a class="accordion-toggle" data-toggle="collapse" aria-expanded="false" href="#misp_info"><i class="fas fa-lightbulb"></i> MISP Threat Intelligence</a></center> | ||
</div> | ||
|
||
<div class="collapse" id="misp_info"> | ||
<div class="card card-body"> | ||
{% if file.misp.event_info %} | ||
<div class="column center"> | ||
<a class="btn btn-secondary btn-sm" href='{% url "mispjson" id "attribute" %}' role="button" data-bs-toggle="tooltip" title="Download MISP Attribute JSON File"><span class="fas fa-download"></span> Download MISP Attribute JSON File</a> | ||
<a class="btn btn-secondary btn-sm" href='{% url "mispjson" id "event" %}' role="button" data-bs-toggle="tooltip" title="Download MISP Event JSON File"><span class="fas fa-download"></span> Download MISP Event JSON File</a> | ||
{% if file.misp.ids_links %} | ||
<a class="btn btn-secondary btn-sm" href='{{file.misp.ids_links.0}}' role="button" data-bs-toggle="tooltip" title="Download Snort IDS Signatures"><span class="fas fa-download"></span> Download Snort IDS Signatures</a> | ||
<a class="btn btn-secondary btn-sm" href='{{file.misp.ids_links.1}}' role="button" data-bs-toggle="tooltip" title="Download Suricata IDS Signatures"><span class="fas fa-download"></span> Download Suricata IDS Signatures</a> | ||
{% endif %} | ||
</div> | ||
<h1></h1> | ||
<h4><a href="{{file.misp.event_link}}" target="_blank" ><b><span class="fas fa-calendar-check"></span> {{file.misp.event_info}}</b></a></h4> | ||
{% endif %} | ||
|
||
<table class="table table-striped table-bordered"> | ||
{% if file.misp.related_events %} | ||
<tr> | ||
<th><span class="fas fa-calendar-plus"></span> Related Events [{{file.misp.related_events|length}}]</th> | ||
<td> | ||
<ul> | ||
{% for event_link, event_info in file.misp.related_events.items %} | ||
<li><a href="{{event_link}}" target="_blank">{{event_info}}</a></li> | ||
{% endfor %} | ||
</ul> | ||
</td> | ||
</tr> | ||
{% endif %} | ||
{% if file.misp.threat_actor %} | ||
<tr> | ||
<th><span class="fas fa-user-secret"></span>Threat Actor(s) [{{file.misp.threat_actor|length}}]</th> | ||
<td style="word-wrap: break-word;"> | ||
<ul> | ||
{% for threat_actor_name, threat_actor_value in file.misp.threat_actor.items %} | ||
<li><b><u>{{threat_actor_name}}</u></b> | ||
{% if threat_actor_value.1 != 0 %} | ||
{% if file.misp.galaxy_link %} | ||
<a href="{{file.misp.galaxy_link}}{{threat_actor_value.1}}" target="_blank" style="color: #e74c3c">[View MISP Threat Actor Information Here]</a><br>{{threat_actor_value.0}}<br><br> | ||
{% else %} | ||
<a href="{{file.misp.url}}galaxy_clusters/view/{{threat_actor_value.1}}" target="_blank" style="color: #e74c3c">[View MISP Threat Actor Information Here]</a><br>{{threat_actor_value.0}}<br><br> | ||
{% endif %} | ||
{% else %} | ||
<br><br> | ||
{% endif %} | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
</td> | ||
</tr> | ||
{% endif %} | ||
{% if file.misp.event_tags %} | ||
{% for tag_name, tag_value in file.misp.event_tags.items %} | ||
<tr> | ||
{% if tag_name == "Topic" %} | ||
<th><span class="fas fa-info-circle"></span> Topic(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Malware-Category" %} | ||
<th><span class="fas fa-virus"></span> Malware Categorie(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Mitre-Enterprise-Attack-Malware" %} | ||
<th><span class="fas fa-virus"></span> MITRE Enterprise Attack Malware [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Mitre-Malware" %} | ||
<th><span class="fas fa-virus"></span> MITRE Malware [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Tool" %} | ||
<th><span class="fas fa-screwdriver-wrench"></span> Tool(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Incident-Classification" %} | ||
<th><span class="fas fa-virus"></span> Incident Classification(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Mitre-Enterprise-Attack-Attack-Pattern" %} | ||
<th><span class="fas fa-triangle-exclamation"></span> MITRE Enterprise Attack Pattern(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Mitre-Attack-Pattern" %} | ||
<th><span class="fas fa-triangle-exclamation"></span> MITRE Attack Pattern(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Rat" %} | ||
<th><span class="fas fa-screwdriver-wrench"></span> Remote Access Tool(s) [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Confidence-In-Analytic-Judgment" %} | ||
<th><span class="fas fa-eye"></span> Confidence in Analytic Judgment</th> | ||
{% elif tag_name == "Sector" %} | ||
<th><span class="fas fa-building"></span> Sectors Involved [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Country" %} | ||
<th><span class="fas fa-flag"></span> Countries [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Target-Information" %} | ||
<th><span class="fas fa-bullseye"></span> Target(s) Information [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Malpedia" %} | ||
<th><span class="fas fa-globe"></span> Malpedia Archives Information [{{tag_value|length}}]</th> | ||
{% elif tag_name == "Lifetime" %} | ||
<th><span class="fas fa-clock"></span> Lifetime</th> | ||
{% elif tag_name == "Certainty" %} | ||
<th><span class="fas fa-star-half-stroke"></span> Certainty</th> | ||
{% elif tag_name == "Backdoor" %} | ||
<th><span class="fas fa-door-open"></span> Backdoor(s) [{{tag_value|length}}]</th> | ||
{% else %} | ||
<th>{{tag_name}}</th> | ||
{% endif %} | ||
<td> | ||
<ul> | ||
{% for event_tag, event_tag_value in tag_value.items %} | ||
{% if 'str' in event_tag_value|gettype %} | ||
<li><a href="{{file.misp.search_tag_link}}{{event_tag_value}}" target="_blank">{{event_tag}}</a></li> | ||
{% else %} | ||
{% if 'int' in event_tag_value.1|gettype %} | ||
<li><a href="{{file.misp.search_tag_link}}{{event_tag_value.0}}" target="_blank">{{event_tag}}</a></li> | ||
{% else %} | ||
<li><a href="{{file.misp.search_tag_link}}{{event_tag_value.0}}" target="_blank" title="{{event_tag_value.1}}">{{event_tag}}</a></li> | ||
{% endif %} | ||
{% endif %} | ||
{% endfor %} | ||
</ul> | ||
</td> | ||
</tr> | ||
{% endfor %} | ||
{% endif %} | ||
{% if file.misp.links %} | ||
<tr> | ||
<th><span class="fas fa-external-link-alt"></span>External Analysis Link(s) [{{file.misp.links|length}}]</th> | ||
<td> | ||
<ul> | ||
{% for link in file.misp.links %} | ||
<li><a href="{{link}}" target="_blank">{{link}}</a></li> | ||
{% endfor %} | ||
</ul> | ||
</td> | ||
</tr> | ||
{% endif %} | ||
</table> | ||
</div> | ||
</div> | ||
{% endif %} |