in aristotle/aristotle.py [0:0]
def normalize_better(self, k, v, sid=None):
""" Try to convert date, MITRE ATT&CK, and cve related metadata values to conform to the
BETTER schema for filtering and statistics. Currently applies to keys
'cve', 'mitre_tactic_id', 'mitre_technique_id' and those ending with '_at' or "-at".
:param k: key name of a metadata key-value pair
:type k: string, required
:param v: value of a metadata key-value pair
:type v: string, required
:param sid: SID related to the passed in key-value pair. Used only for enriching logging.
:type sid: int, optional
:returns: list of all key/value pairs to add to metadata structure
:rtype: list
"""
retlist = []
if k.endswith("_at") or k.endswith("-at"):
# treat as possible date
try:
v = dateparse(v.replace('_', '-'))
v = v.strftime("%Y-%m-%d")
except Exception as e:
print_warning("Unable to parse metadata '{}' key with value '{}' as date{}: {}".format(k, v, " for sid {}".format(sid) if sid is not None else "", e))
retlist.append([k, v])
elif k == "cve":
# ET ruleset will in some cases string together multiple CVEs in one
# string, e.g. "cve_2021_27561_cve_2021_27562" so deal with that and
# the other underscore nonsense.
cves = cve_re.findall(v.replace('_', '-'))
if len(cves) == 0:
print_warning("Unable to parse metadata '{}' key with value '{}'{}".format(k, v, " for sid {}".format(sid) if sid is not None else ""))
for cve in cves:
retlist.append([k, cve])
elif k in ['mitre_technique_id', 'mitre_tactic_id']:
# pull values out of 'mitre_tactic_id' and 'mitre_technique_id' metadata and
# put into BETTER 'mitre_attack' key
retlist.append(["mitre_attack", v])
else:
retlist.append([k, v])
return retlist