Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _get_technique_listing(self, tactic, domain='enterprise'):
"""
INTERNAL - retrieves techniques for a given tactic and domain
:param tactic: The tactic to grab techniques from
:param domain: The domain to draw from
"""
techniques = []
subtechs = {}
techs = self.collections[domain].query([Filter('type', '=', 'attack-pattern'), Filter('kill_chain_phases.phase_name', '=', tactic)])
for entry in techs:
if entry['kill_chain_phases'][0]['kill_chain_name'] == 'mitre-attack':
tid = [t['external_id'] for t in entry['external_references'] if 'attack' in t['source_name']]
if '.' not in tid[0]:
techniques.append(MatrixEntry(id=tid[0], name=entry['name']))
else:
parent = tid[0].split('.')[0]
if parent not in subtechs:
subtechs[parent] = []
subtechs[parent].append(MatrixEntry(id=tid[0], name=entry['name']))
return techniques, subtechs
def get_all_techniques(src, source_name):
"""Filters data source by attack-pattern which extracts all ATT&CK Techniques"""
filters = [
stix2.Filter("type", "=", "attack-pattern"),
stix2.Filter("external_references.source_name", "=", source_name),
]
results = src.query(filters)
return remove_deprecated(results)
def _get_tactic_listing(self, domain='enterprise'):
"""
INTERNAL - retrieves tactics for the associated domain
:param domain: The domain to draw from
"""
tactics = {}
t_filt = []
matrix = self.collections[domain].query([Filter('type', '=', 'x-mitre-matrix')])
for i in range(len(matrix)):
tactics[matrix[i]['name']] = []
for tactic_id in matrix[i]['tactic_refs']:
tactics[matrix[i]['name']].append(self.collections[domain].query([Filter('id', '=', tactic_id)])[0])
for entry in tactics[matrix[0]['name']]:
self.convert_data[entry['x_mitre_shortname']] = entry['name']
self.convert_data[entry['name']] = entry['x_mitre_shortname']
t_filt.append(MatrixEntry(id=entry['external_references'][0]['external_id'], name=entry['name']))
return t_filt
def generate():
"""parse the STIX on MITRE/CTI and return a layer dict with techniques with randomized scores"""
# import the STIX data from MITRE/CTI
stix = requests.get("https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json").json()
ms = stix2.MemoryStore(stix_data=stix["objects"])
# get all techniques in STIX
techniques = ms.query([
stix2.Filter("type", "=", "attack-pattern")
])
# parse techniques into layer format
techniques_list = []
for technique in techniques:
# skip deprecated and revoked
if ("x_mitre_deprecated" in technique and technique["x_mitre_deprecated"]) or ("revoked" in technique and technique["revoked"]): continue
techniqueID = technique["external_references"][0]["external_id"] # get the attackID
techniques_list.append({
"techniqueID": techniqueID,
"score": random.randint(1,100) # random score
})
# return the techniques in a layer dict
return {
"name": "heatmap example",
"version": "3.0",
"sorting": 3, # descending order of score
def get_technique_by_group(src, stix_id):
relations = src.relationships(stix_id, 'uses', source_only=True)
return src.query([
Filter('type', '=', 'attack-pattern'),
Filter('id', 'in', [r.target_ref for r in relations])
])
def get_all_groups(src):
filt = [Filter('type', '=', 'intrusion-set')]
return src.query(filt)
def generate(softwaretype="software"):
""" generate and return a layer dict showing techniques used by software
If softwaretype is specified as "malware" or "tool", only shows software of that type. If softwaretype is specified as "software" output layer shows both malware and tools
"""
# import the STIX data from MITRE/CTI
stix = requests.get("https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json").json()
ms = stix2.MemoryStore(stix_data=stix["objects"])
# software includes malware and tool types so perform two queries and merge the results
software_filters = []
if softwaretype == "malware" or softwaretype == "software":
software_filters.append( [ stix2.Filter('type', '=', 'malware') ] )
if softwaretype == "tool" or softwaretype == "software":
software_filters.append( [ stix2.Filter('type', '=', 'tool') ] )
software = list(chain.from_iterable(
ms.query(f) for f in software_filters
))
# build a list of techniques used by software
techniques_used = {} #attackID => using software names
for thesoftware in software:
# filter out revoked and deprecated software
if ("x_mitre_deprecated" in thesoftware and thesoftware["x_mitre_deprecated"]) or ("revoked" in thesoftware and thesoftware["revoked"]): continue
for relationship in ms.relationships(thesoftware["id"]):
# skip all non-technique relationships
if "attack-pattern" not in relationship["target_ref"]: continue
technique = ms.get(relationship["target_ref"])
def get_all_techniques(src, source_name):
"""Filters data source by attack-pattern which extracts all ATT&CK Techniques"""
filters = [
stix2.Filter("type", "=", "attack-pattern"),
stix2.Filter("external_references.source_name", "=", source_name),
]
results = src.query(filters)
return remove_deprecated(results)
def generate():
"""parse the STIX on MITRE/CTI and return a layer dict showing all techniques used by an APT group with phrase 'bear' in the group aliases."""
# import the STIX data from MITRE/CTI
stix = requests.get("https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json").json()
ms = stix2.MemoryStore(stix_data=stix["objects"])
groups = ms.query([ stix2.Filter("type", "=", "intrusion-set") ])
# find bear groups
bear_groups = [] #list of groups with bear in name
for group in groups:
# filter out deprecated and revoked groups
if ("x_mitre_deprecated" in group and group["x_mitre_deprecated"]) or ("revoked" in group and group["revoked"]): continue
# check all aliases for bear
for alias in group["aliases"]:
if re.match(".*bear.*", alias, re.IGNORECASE) is not None:
bear_groups.append(group)
break # don't match the same group multiple times
# find techniques used by bear groups
techniques_used = {} #attackID => using bear groups
for bear in bear_groups:
# construct the "bear" name for the comment
'pre-attack': 'PRE-ATT&CK',
'mobile-attack': 'Mobile'
}
domainToLayerFileDomain = {
'enterprise-attack': 'mitre-enterprise',
'mobile-attack': 'mitre-mobile',
'pre-attack': 'pre-attack'
}
domainToTaxiiCollectionId = {
"enterprise-attack": "95ecc380-afe9-11e4-9b6c-751b66dd541e",
"mobile-attack": "2f669986-b40b-4423-b720-4396ca6a462b",
"pre-attack": "062767bd-02d2-4b72-84ba-56caef0f8658"
}
attackTypeToStixFilter = { # stix filters for querying for each type of data
'technique': [Filter('type', '=', 'attack-pattern')],
'software': [Filter('type', '=', 'malware'), Filter('type', '=', 'tool')],
'group': [Filter('type', '=', 'intrusion-set')],
'mitigation': [Filter('type', '=', 'course-of-action')]
}
attackTypeToPlural = { # because some of these pluralize differently
'technique': 'techniques',
'malware': 'malware',
'software': 'software',
'group': 'groups',
'mitigation': 'mitigations'
}
sectionNameToSectionHeaders = { # how we want to format headers for each section
"additions": "New {obj_type}",
"changes": "{obj_type} changes",
"minor_changes": "Minor {obj_type} changes",
"deprecations": "{obj_type} deprecations",
"revocations": "{obj_type} revocations",