diff --git a/analyzers/RecordedFuture/README.md b/analyzers/RecordedFuture/README.md new file mode 100644 index 000000000..d95c1b1f0 --- /dev/null +++ b/analyzers/RecordedFuture/README.md @@ -0,0 +1,27 @@ +This analyzer will return Recorded Future Intelligence for the following datatypes: +* ip +* domain +* fqdn +* hash +* url + +Enriched observables can display: +* Risk Summary: Risk Score, Criticality, and link to the Intelligence Card +* Recorded Future AI Insights + +![](assets/RecordedFutureAnalyzerReport.jpg) + +* Risk Rules and Evidence Details + +![](assets/RiskRulesReport.jpg) + +* Technical & Insikt Group Research Links + +![](assets/LinksReport.jpg) + +* Related Threat Actors +* Related Attack Vectors +* Malware Family / Category +* Related IPs +* Related Domains +* Related Hashes \ No newline at end of file diff --git a/analyzers/RecordedFuture/RecordedFuture.json b/analyzers/RecordedFuture/RecordedFuture.json new file mode 100644 index 000000000..2bf27be95 --- /dev/null +++ b/analyzers/RecordedFuture/RecordedFuture.json @@ -0,0 +1,27 @@ +{ + "name": "RecordedFuture", + "version": "2.0", + "author": "Recorded Future", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "license": "AGPL-V3", + "dataTypeList": ["ip", "domain", "fqdn", "hash", "url"], + "description": "Enrich IP, Domain, FQDN, URL, or Hash with Recorded Future context: Risk Score, Risk Details, AI Insights, Links, Threat Actor, Attack Vector, Malware Category / Family, and Related Entities (IPs, Domains, and Hashes)", + "command": "RecordedFuture/recordedfuture.py", + "baseConfig": "RecordedFuture", + "configurationItems": [ + { + "name": "key", + "description": "API Token", + "type": "string", + "multi": false, + "required": true + } + ], + "registration_required": true, + "subscription_required": true, + "service_homepage": "https://www.recordedfuture.com/", + "service_logo": { + "path": "assets/recordedfuture-logo.png", + "caption": "logo" + } +} \ No newline at end of file diff --git a/analyzers/RecordedFuture/RecordedFuture_risk.json b/analyzers/RecordedFuture/RecordedFuture_risk.json deleted file mode 100644 index ea64739fb..000000000 --- a/analyzers/RecordedFuture/RecordedFuture_risk.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "RecordedFuture_risk", - "version": "1.0", - "author": "KAPSCH-CDC", - "url": "https://github.com/kapschcdc/Cortex-Analyzers", - "license": "AGPL-V3", - "description": "Get the latest risk data from RecordedFuture for a hash, domain or an IP address.", - "dataTypeList": ["domain", "ip", "hash"], - "command": "RecordedFuture/recordedfuture.py", - "baseConfig": "RecordedFuture", - "configurationItems": [ - { - "name": "key", - "description": "API key for RecordedFuture", - "type": "string", - "multi": false, - "required": true - } - ] -} diff --git a/analyzers/RecordedFuture/assets/LinksReport.jpg b/analyzers/RecordedFuture/assets/LinksReport.jpg new file mode 100644 index 000000000..ba7d222ec Binary files /dev/null and b/analyzers/RecordedFuture/assets/LinksReport.jpg differ diff --git a/analyzers/RecordedFuture/assets/RecordedFutureAnalyzerReport.jpg b/analyzers/RecordedFuture/assets/RecordedFutureAnalyzerReport.jpg new file mode 100644 index 000000000..1a84f1a96 Binary files /dev/null and b/analyzers/RecordedFuture/assets/RecordedFutureAnalyzerReport.jpg differ diff --git a/analyzers/RecordedFuture/assets/RiskRulesReport.jpg b/analyzers/RecordedFuture/assets/RiskRulesReport.jpg new file mode 100644 index 000000000..c844b7d4a Binary files /dev/null and b/analyzers/RecordedFuture/assets/RiskRulesReport.jpg differ diff --git a/analyzers/RecordedFuture/assets/recordedfuture-logo.png b/analyzers/RecordedFuture/assets/recordedfuture-logo.png new file mode 100644 index 000000000..2da3ffadd Binary files /dev/null and b/analyzers/RecordedFuture/assets/recordedfuture-logo.png differ diff --git a/analyzers/RecordedFuture/recordedfuture.py b/analyzers/RecordedFuture/recordedfuture.py index 418a0402e..65d6c2726 100755 --- a/analyzers/RecordedFuture/recordedfuture.py +++ b/analyzers/RecordedFuture/recordedfuture.py @@ -1,56 +1,463 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +""" +##################################### TERMS OF USE ########################################### +# The following code is provided for demonstration purpose only, and should not be used # +# without independent verification. Recorded Future makes no representations or warranties, # +# express, implied, statutory, or otherwise, regarding any aspect of this code or of the # +# information it may retrieve, and provides it both strictly “as-is” and without assuming # +# responsibility for any information it may retrieve. Recorded Future shall not be liable # +# for, and you assume all risk of using, the foregoing. By using this code, Customer # +# represents that it is solely responsible for having all necessary licenses, permissions, # +# rights, and/or consents to connect to third party APIs, and that it is solely responsible # +# for having all necessary licenses, permissions, rights, and/or consents to any data # +# accessed from any third party API. # +############################################################################################## +""" + +import json +import urllib.error +import urllib.request +from urllib.parse import urlencode, quote_plus from cortexutils.analyzer import Analyzer -import urllib.request -import json +APP_VERSION = "2.0" +APP_ID = "ps-thehive-analyzer/{}".format(APP_VERSION) +IP_DATA_TYPE = "ip" +DOMAIN_DATA_TYPE = "domain" +FQDN_DATA_TYPE = "fqdn" +HASH_DATA_TYPE = "hash" +RF_API = "https://api.recordedfuture.com/v2/" +URL_DATA_TYPE = "url" +DEFAULT_LINKS_MAP = { + 'Links_Threat_Actors': ["No Threat Actor Links Found"], + 'Links_Tools_Malware': ["No Malware Links Found"], + 'Links_TTPs_Mitre': ["No MITRE ATT&CK TTP Links Found"], + 'Links_TTPs_Attack_Vector': ["No Attack Vector Links Found"], + 'Links_Indicators_IP': ["No IP Address Links Found"], + 'Links_Indicators_Domain': ["No Domain Links Found"], + 'Links_Indicators_URL': ["No URL Links Found"], + 'Links_Indicators_Hash': ["No Hash Links Found"], + 'Links_Detection_Malware_Sig': ["No Malware Signature Links Found"], + 'Links_Victims_Org': ["No Victim Organization Links Found"], + 'Links_Victims_IP': ["No Victim IP Address Links Found"], + 'Links_Exploit_Vuln': ["No Vulnerability Links Found"], +} + + +class RecordedFuture(Analyzer): + """Recorded Future Analyzer class used for observable enrichment and to format the report.""" -class RecordedFutureAnalyzer(Analyzer): def __init__(self): Analyzer.__init__(self) - self.recordedfuture_key = self.get_param('config.key', None, 'Missing RecordedFuture API key') - self.proxies = self.get_param('config.proxy', None) + self.api_key = self.get_param("config.key", None, "Recorded Future token is missing") + + def lookup_observable(self, observable, data_type): + """Query the Recorded Future API for entity enrichment. + + Return Risk, Links, Related Entities, Intelligence Card link, and Counts. + + Args: + observable (string): Case observable to enrich with Recorded Future + data_type (string): the observable's data type + + Returns: + dict: the Recorded Future JSON response from observable lookup + """ + # if analyzer is ran on a URL observable, encode url string before sending to API + if data_type == URL_DATA_TYPE: + observable = quote_plus(observable) + # if observable is a fqdn in TheHive, use the Recorded Future domain endpoint + elif data_type == FQDN_DATA_TYPE: + data_type = DOMAIN_DATA_TYPE + + # URL to query Recorded Future API + params = {'fields': 'aiInsights,counts,entity,intelCard,links,relatedEntities,risk'} + url = RF_API + ("%s/%s?%s") % (data_type, observable, urlencode(params)) + + token = self.api_key + headers = {'X-RFToken': token, 'User-Agent': APP_ID} + req = urllib.request.Request(url, None, headers) + + json_response = {} + try: + with urllib.request.urlopen(req) as res: + json_response = json.loads(res.read().decode("utf-8")) + except urllib.error.HTTPError as e: + self.error("HTTP Error reason: " + e.reason) + except IOError as e: + self.error(str(e)) + + return json_response + + def add_related_entities(self, related_entities, entities_list): + """ + Add related entities to the analyzer report if they contain 5 or more co-occurrences. + + Args: + related_entities (list): related entities returned from the API query + entities_list (list): append entities to this list if they pass the check + """ + for related in related_entities: + if int(related['count']) > 4: + entities_list.append(related['entity']['name']) + + def format_related_entities(self, json_response, dict_report): + """ + Get related entities from the JSON response and format into the report. + + Args: + json_response (dict): API response containing entity context + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with related entities + """ + # Initializing List variables used to store the wanted information + malwareCategory = [] + relatedHash = [] + relatedIpAddress = [] + relatedThreatActor = [] + relatedInternetDomainName = [] + relatedMalware = [] + relatedAttackVector = [] + + try: + for relatedEntity in json_response['data']['relatedEntities']: + if relatedEntity['type'] == "RelatedMalwareCategory": + self.add_related_entities(relatedEntity['entities'], malwareCategory) + if relatedEntity['type'] == "RelatedHash": + self.add_related_entities(relatedEntity['entities'], relatedHash) + if relatedEntity['type'] == "RelatedIpAddress": + self.add_related_entities(relatedEntity['entities'], relatedIpAddress) + if relatedEntity['type'] == "RelatedThreatActor": + self.add_related_entities(relatedEntity['entities'], relatedThreatActor) + if relatedEntity['type'] == "RelatedInternetDomainName": + self.add_related_entities(relatedEntity['entities'], relatedInternetDomainName) + if relatedEntity['type'] == "RelatedMalware": + self.add_related_entities(relatedEntity['entities'], relatedMalware) + if relatedEntity['type'] == "RelatedAttackVector": + self.add_related_entities(relatedEntity['entities'], relatedAttackVector) + except KeyError: + pass + + if not relatedThreatActor: + relatedThreatActor.append("No Related Threat Actor Found") + if not malwareCategory: + malwareCategory.append("No Malware Category Found") + if not relatedHash: + relatedHash.append("No Related Hashes Found") + if not relatedIpAddress: + relatedIpAddress.append("No Related IP Addresses Found") + if not relatedInternetDomainName: + relatedInternetDomainName.append("No Related Domain Names Found") + if not relatedMalware: + relatedMalware.append("No Malware Family Found") + if not relatedAttackVector: + relatedAttackVector.append("No Related Attack Vector Found") + + dict_report['Malware_Category'] = malwareCategory + dict_report['Malware_Family'] = relatedMalware + dict_report['Threat_Actor'] = relatedThreatActor + dict_report['Related_Hashes'] = relatedHash + dict_report['Related_IPs'] = relatedIpAddress + dict_report['Related_Domains'] = relatedInternetDomainName + dict_report['Attack_Vector'] = relatedAttackVector + + return dict_report + + def add_link_to_list(self, entities, links): + """ + Add Linked entity to the provided links list if it is not a duplicate. + + Args: + entities (list): the list of linked entities to be added + links (list): append entities to this list if they are unique + """ + for entity in entities: + if entity['name'] not in links: + links.append(entity['name']) + + def add_actors_tools_ttps(self, section_lists, dict_report): + """ + Parse Actors, Tools & TTPs from links and format into the report. + + Args: + section_lists (list): entity lists under links Actors, Tools & TTPs sections + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with Actors, Tools & TTPs + """ + linksThreatActors = dict_report.get('Links_Threat_Actors', []) + linksToolsMalware = dict_report.get('Links_Tools_Malware', []) + linksTTPsMitre = dict_report.get('Links_TTPs_Mitre', []) + linksTTPsAttackVector = dict_report.get('Links_TTPs_Attack_Vector', []) + + for section_list in section_lists: + type_name = section_list.get('type', {}).get('name') + + if type_name == "Threat Actor": + self.add_link_to_list(section_list['entities'], linksThreatActors) + elif type_name == "Malware": + self.add_link_to_list(section_list['entities'], linksToolsMalware) + elif type_name == "MitreAttackIdentifier": + self.add_link_to_list(section_list['entities'], linksTTPsMitre) + elif type_name == "AttackVector": + self.add_link_to_list(section_list['entities'], linksTTPsAttackVector) + + dict_report['Links_Threat_Actors'] = linksThreatActors + dict_report['Links_Tools_Malware'] = linksToolsMalware + dict_report['Links_TTPs_Mitre'] = linksTTPsMitre + dict_report['Links_TTPs_Attack_Vector'] = linksTTPsAttackVector + + return dict_report + + def add_indicators_detection_rules(self, section_lists, dict_report): + """ + Parse Indicators & Detection Rules from links and format into the report. + + Args: + section_lists (list): entity lists under links Indicators & Detection Rules sections + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with Indicators & Detection Rules + """ + linksIndicatorsIP = dict_report.get('Links_Indicators_IP', []) + linksIndicatorsDomain = dict_report.get('Links_Indicators_Domain', []) + linksIndicatorsURL = dict_report.get('Links_Indicators_URL', []) + linksIndicatorsHash = dict_report.get('Links_Indicators_Hash', []) + linksDetectionMalwareSig = dict_report.get('Links_Detection_Malware_Sig', []) + + for section_list in section_lists: + type_name = section_list.get('type', {}).get('name') + + if type_name == "IpAddress": + self.add_link_to_list(section_list['entities'], linksIndicatorsIP) + elif type_name == "InternetDomainName": + self.add_link_to_list(section_list['entities'], linksIndicatorsDomain) + elif type_name == "URL": + self.add_link_to_list(section_list['entities'], linksIndicatorsURL) + elif type_name == "Hash": + self.add_link_to_list(section_list['entities'], linksIndicatorsHash) + elif type_name == "MalwareSignature": + self.add_link_to_list(section_list['entities'], linksDetectionMalwareSig) + + dict_report['Links_Indicators_IP'] = linksIndicatorsIP + dict_report['Links_Indicators_Domain'] = linksIndicatorsDomain + dict_report['Links_Indicators_URL'] = linksIndicatorsURL + dict_report['Links_Indicators_Hash'] = linksIndicatorsHash + dict_report['Links_Detection_Malware_Sig'] = linksDetectionMalwareSig + + return dict_report + + def add_victims_exploit_targets(self, section_lists, dict_report): + """ + Parse Victims & Exploit Targets from links and format into the report. + + Args: + section_lists (list): entity lists under links Victims & Exploit Targets sections + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with Victims & Exploit Targets + """ + linksVictimsOrg = dict_report.get('Links_Victims_Org', []) + linksVictimsIP = dict_report.get('Links_Victims_IP', []) + linksExploitVuln = dict_report.get('Links_Exploit_Vuln', []) + + for section_list in section_lists: + type_name = section_list.get('type', {}).get('name') + + if type_name == "Organization": + self.add_link_to_list(section_list['entities'], linksVictimsOrg) + elif type_name == "IpAddress": + self.add_link_to_list(section_list['entities'], linksVictimsIP) + elif type_name == "CyberVulnerability": + self.add_link_to_list(section_list['entities'], linksExploitVuln) + + dict_report['Links_Victims_Org'] = linksVictimsOrg + dict_report['Links_Victims_IP'] = linksVictimsIP + dict_report['Links_Exploit_Vuln'] = linksExploitVuln + + return dict_report + + def add_default_links_values(self, dict_report): + """ + Set default text to indicate when no links exist. + This prevents formatting issues within the analyzer report. + + Args: + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with links + """ + for key in DEFAULT_LINKS_MAP: + if not dict_report.get(key): + dict_report[key] = DEFAULT_LINKS_MAP[key] + + return dict_report + + def format_links(self, json_response, dict_report): + """ + Get links from the JSON response and format into the report. + + Args: + json_response (dict): API response containing entity context + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with links + """ + try: + for hit in json_response['data']['links']['hits']: + for section in hit['sections']: + if section['lists']: + section_name = section.get('section_id', {}).get('name') + + if section_name == "Actors, Tools & TTPs": + dict_report = self.add_actors_tools_ttps(section['lists'], dict_report) + elif section_name == "Indicators & Detection Rules": + dict_report = self.add_indicators_detection_rules( + section['lists'], dict_report + ) + elif section_name == "Victims & Exploit Targets": + dict_report = self.add_victims_exploit_targets( + section['lists'], dict_report + ) + except KeyError: + pass + + self.add_default_links_values(dict_report) + + return dict_report + + def format_risk(self, json_response, dict_report): + """ + Format Risk data from the JSON response and add to the report. + + Args: + json_response (dict): API response containing entity context + dict_report (dict): analyzer report content + + Returns: + dict: the analyzer report content with Risk data + """ + evidenceDetails = {} + risk_obj = json_response['data']['risk'] + + try: + riskScore = risk_obj['score'] + except KeyError: + riskScore = 0 + + try: + evidenceDetails = risk_obj['evidenceDetails'] + evidenceDetails.reverse() + except KeyError: + pass + + if not evidenceDetails: + evidenceDetails = [ + { + "criticality": 0, + "criticalityLabel": "None", + "rule": "No Risk Rules Found", + "evidenceString": "No Evidence Details Found", + } + ] + + risk_summary = risk_obj['riskSummary'] + criticality = risk_obj['criticality'] + criticality_label = risk_obj['criticalityLabel'] + + dict_report['Risk_Score'] = riskScore + dict_report['Risk_Summary'] = risk_summary + dict_report['Risk_Details'] = evidenceDetails + dict_report['Criticality'] = criticality + dict_report['Criticality_Label'] = criticality_label + + return dict_report + + def build_report(self, json_response, observable): + """Parse the JSON response from entity enrichment to build the long.html report. + + Args: + json_response (dict): API response containing entity context + observable (string): observable enriched with Recorded Future + """ + ai_insights_obj = json_response['data']['aiInsights'] + if ai_insights_obj['text']: + ai_insights = ai_insights_obj['text'] + elif ai_insights_obj['comment']: + ai_insights = ai_insights_obj['comment'] + else: + ai_insights = "Insufficient Information for Analysis" + + try: + if self.data_type == URL_DATA_TYPE: + intel_card = "https://app.recordedfuture.com/live/sc/entity/url%3A" + observable + else: + intel_card = json_response['data']['intelCard'] + except KeyError: + intel_card = "https://app.recordedfuture.com/live/" + + dict_report = { + 'Intel_Card': intel_card, + 'AI_Insights': ai_insights, + } + + dict_report = self.format_risk(json_response, dict_report) + dict_report = self.format_related_entities(json_response, dict_report) + dict_report = self.format_links(json_response, dict_report) + + # ensure_ascii should be set to False, but there appears to be a bug in Cortexutils. + # Setting True for now. + self.report(dict_report, True) def summary(self, raw): + """Creates the Observable short summary tag to include the Risk Score and color-coded + by Criticality. + + Args: + raw (dict): The long report contents + + Returns: + dict: The short Summary tag taxonomy + """ taxonomies = [] - namespace = 'RF' - - level = 'info' - predicate = 'score' - value = '{}/100'.format(raw['data']['risk']['score']) - criticality = raw['data']['risk']['criticality'] - if criticality == 0: - level = 'safe' - elif criticality == 1: - level = 'info' + namespace = "RecordedFuture" + predicate = "RiskScore" + level = "safe" + value = raw['Risk_Score'] + + criticality = raw['Criticality'] + + if criticality == 1: + level = "info" elif criticality == 2: - level = 'suspicious' + level = "suspicious" elif criticality >= 3: - level = 'malicious' - taxonomies.append(self.build_taxonomy(level, namespace, predicate, value)) + level = "malicious" - level = 'info' - predicate = '#evidenceDetails' - value = str(len(raw['data']['risk']['evidenceDetails'])) taxonomies.append(self.build_taxonomy(level, namespace, predicate, value)) - - return {"taxonomies": taxonomies} + return {'taxonomies': taxonomies} def run(self): - if self.data_type in ['domain', 'ip', 'hash']: - data = self.get_param('data', None, 'Data is missing') - url = 'https://api.recordedfuture.com/v2/{}/{}?fields=risk%2CintelCard'.format(self.data_type, data) - req = urllib.request.Request(url, None, {'X-RFToken': self.recordedfuture_key}) - try: - with urllib.request.urlopen(req) as res: - j = json.loads(res.read().decode("utf-8")) - self.summary(j) - return self.report(j) - except IOError as e: - self.error(str(e)) + """The entry point when the Recorded Future Analyzer is run on an observable.""" + Analyzer.run(self) + types = [IP_DATA_TYPE, DOMAIN_DATA_TYPE, FQDN_DATA_TYPE, HASH_DATA_TYPE, URL_DATA_TYPE] + + if self.data_type in types: + observable = self.get_param("data", None, "Data is missing") + json_response = self.lookup_observable(observable, self.data_type) + self.build_report(json_response, observable) else: - self.error('Invalid data type') + self.error("Invalid data type") + -if __name__ == '__main__': - RecordedFutureAnalyzer().run() +if __name__ == "__main__": + RecordedFuture().run() diff --git a/thehive-templates/RecordedFuture_2_0/long.html b/thehive-templates/RecordedFuture_2_0/long.html new file mode 100644 index 000000000..8ece4354f --- /dev/null +++ b/thehive-templates/RecordedFuture_2_0/long.html @@ -0,0 +1,160 @@ +
+
+ {{artifact.data | fang}} +
+
+ {{content.errorMessage}} +
+
+ +
+
+ Summary +
+
+
+
ERROR:
+
{{content.errortext}} 
+
+
+
Risk Score
+
{{content.Risk_Score}}
+
+
+
Criticality
+
{{content.Criticality_Label}} ({{content.Criticality}})
+
+
+
Risk Summary
+
{{content.Risk_Summary}}
+
+ Intelligence Card +
+
+ Recorded Future AI Insights +
+
+
+
AI Insights
+
{{content.AI_Insights}}
+
+
+
+ Triggered Risk Rules +
+
+ + + + + + + + + + + +
CriticalityRisk RuleEvidence Details
+ + {{evidence.criticalityLabel}} + + {{evidence.rule}}{{evidence.evidenceString}}
+
+
+ Links: Actors, Tools & TTPs +
+
+
+
Threat Actor
+
{{lta}}
+
+
+
Malware
+
{{ltm}}
+
+
+
MITRE ATT&CK Identifier
+
{{lttpm}}
+
+
+
Attack Vector
+
{{lttpav}}
+
+
+
+ Links: Indicators & Detection Rules +
+
+
+
IP Address
+
{{liip}}
+
+
+
Domain
+
{{lid}}
+
+
+
URL
+
{{liu}}
+
+
+
Hash
+
{{lih}}
+
+
+
Malware Signature
+
{{ldms}}
+
+
+
+ Links: Victims & Exploit Targets +
+
+
+
Victim Organization
+
{{lvo}}
+
+
+
Victim IP Address
+
{{lvi}}
+
+
+
Vulnerability
+
{{lev}}
+
+
+
+ Related Context +
+
+
+
Related Threat Actor
+
{{ta}}
+
+
+
Related Attack Vector
+
{{av}}
+
+
+
Malware Category
+
{{mc}}
+
+
+
Malware Family
+
{{mf}}
+
+
+
Related IPs
+
{{ip}}
+
+
+
Related Domains
+
{{domain}}
+
+
+
Related Hashes
+
{{hash}}
+
+
+
diff --git a/thehive-templates/RecordedFuture_2_0/short.html b/thehive-templates/RecordedFuture_2_0/short.html new file mode 100644 index 000000000..5bd8fbd3a --- /dev/null +++ b/thehive-templates/RecordedFuture_2_0/short.html @@ -0,0 +1,5 @@ + + {{t.namespace}}:{{t.predicate}}="{{t.value}}" + diff --git a/thehive-templates/RecordedFuture_risk_1_0/long.html b/thehive-templates/RecordedFuture_risk_1_0/long.html deleted file mode 100644 index 42c5bf2ad..000000000 --- a/thehive-templates/RecordedFuture_risk_1_0/long.html +++ /dev/null @@ -1,55 +0,0 @@ - -
-
- Summary -
-
-
-
Score
-
{{content.data.risk.score}}/100
-
-
-
Criticality
-
{{content.data.risk.criticalityLabel}} ({{content.data.risk.criticality}})
-
-
-
Risk summary
-
{{content.data.risk.riskSummary}}
-
- Intel Card -
-
- Triggered Risk Rules -
-
- - - - - - - - - - - -
CriticalityRuleEvidence
- - {{evidence.criticalityLabel}} - - {{evidence.rule}}{{evidence.evidenceString}}
-
-
- - -
-
- {{(artifact.data || artifact.attachment.name) | fang}} -
-
-
-
Error:
-
{{content.errorMessage}}
-
-
-
diff --git a/thehive-templates/RecordedFuture_risk_1_0/short.html b/thehive-templates/RecordedFuture_risk_1_0/short.html deleted file mode 100644 index 5fc0dabfb..000000000 --- a/thehive-templates/RecordedFuture_risk_1_0/short.html +++ /dev/null @@ -1,3 +0,0 @@ - - {{t.namespace}}:{{t.predicate}}="{{t.value}}" -