Source code for CveXplore.database.maintenance.content_handlers

"""
XML Content Handlers
====================
"""
from collections import defaultdict
from xml.sax.handler import ContentHandler


[docs]class CapecHandler(ContentHandler): """ Class handling the CAPEC XML parsing """
[docs] def __init__(self): self.capec = [] self.Attack_Pattern_Catalog_tag = False self.Attack_Patterns_tag = False self.Attack_Pattern_tag = False self.Attack_step_tag = False self.Description_tag = False self.Text_tag = False self.Prerequisites_tag = False self.Prerequisite_tag = False self.Mitigations_tag = False self.Mitigation_tag = False self.Related_Weaknesses_tag = False self.Related_Weakness_tag = False self.CWE_ID_tag = False self.Related_Attack_Patterns = False self.Taxonomy_Mappings = False self.Taxonomy_Mapping = False self.Likelihood_Of_Attack = False self.Typical_Severity = False self.Execution_Flow = False self.Step = True self.Phase = True self.Attack_Description = True self.Technique = True self.entry_id = False self.entry_name = False self.tag = False self.id = "" self.name = "" self.Summary_ch = "" self.Prerequisite_ch = "" self.Mitigation_ch = "" self.CWE_ID_ch = "" self.entry_id_ch = "" self.entry_name_ch = "" self.taxonomy_name = "" self.step_name = "" self.Step_ch = "" self.Phase_ch = "" self.Attack_Description_ch = "" self.Technique_ch = "" self.Likelihood_Of_Attack_ch = "" self.Typical_Severity_ch = "" self.loa = "" self.ts = "" self.Summary = [] self.Prerequisite = [] self.Solution_or_Mitigation = [] self.Related_Weakness = [] self.Related_AttackPatterns = [] self.techniques = [] self.taxonomy_mapping = defaultdict(dict) self.execution_flow = defaultdict(dict)
[docs] def startElement(self, name, attrs): if name == "Attack_Pattern_Catalog": self.Attack_Pattern_Catalog_tag = True if name == "Attack_Patterns" and self.Attack_Pattern_Catalog_tag: self.Attack_Patterns_tag = True if name == "Attack_Pattern" and self.Attack_Patterns_tag: self.Attack_Pattern_tag = True if self.Attack_Pattern_tag: self.tag = name if self.tag == "Attack_Pattern": self.id = attrs.getValue("ID") self.name = attrs.getValue("Name") if self.tag == "Related_Attack_Patterns": self.Related_Attack_Patterns = True if self.tag == "Related_Attack_Pattern" and self.Related_Attack_Patterns: self.Related_AttackPatterns.append(attrs.get("CAPEC_ID")) if self.tag == "Taxonomy_Mappings": self.Taxonomy_Mappings = True if self.tag == "Taxonomy_Mapping" and self.Taxonomy_Mappings: self.Taxonomy_Mapping = True self.taxonomy_name = attrs.get("Taxonomy_Name") if self.tag == "Entry_ID" and self.Taxonomy_Mappings: self.entry_id = True self.entry_id_ch = "" if self.tag == "Entry_Name" and self.Taxonomy_Mappings: self.entry_name = True self.entry_name_ch = "" if self.tag == "Execution_Flow": self.Execution_Flow = True if self.tag == "Attack_Step" and self.Execution_Flow: self.Attack_step_tag = True if self.tag == "Step" and self.Attack_step_tag: self.Step = True self.Step_ch = "" if self.tag == "Phase" and self.Attack_step_tag: self.Phase = True self.Phase_ch = "" if self.tag == "Description" and self.Attack_step_tag: self.Attack_Description = True self.Attack_Description_ch = "" if self.tag == "Technique" and self.Attack_step_tag: self.Technique = True self.Technique_ch = "" if self.tag == "Description" and not self.Attack_step_tag: self.Description_tag = True self.Summary_ch = "" if self.tag == "Prerequisites": self.Prerequisites_tag = True if name == "Prerequisite" and self.Prerequisites_tag: self.Prerequisite_tag = True self.Prerequisite_ch = "" if self.tag == "Mitigations": self.Mitigations_tag = True if name == "Mitigation" and self.Mitigations_tag: self.Mitigation_tag = True if name == "xhtml:p" and self.Mitigation_tag: self.Text_tag = True self.Mitigation_ch = "" if self.tag == "Related_Weaknesses": self.Related_Weaknesses_tag = True if name == "Related_Weakness" and self.Related_Weaknesses_tag: self.Related_Weakness.append(attrs.getValue("CWE_ID")) if self.tag == "Likelihood_Of_Attack": self.Likelihood_Of_Attack = True self.Likelihood_Of_Attack_ch = "" if self.tag == "Typical_Severity": self.Typical_Severity = True self.Typical_Severity_ch = ""
[docs] def characters(self, ch): if self.Description_tag: self.Summary_ch += ch if self.Prerequisite_tag: self.Prerequisite_ch += ch if self.Text_tag: if self.Mitigation_tag: self.Mitigation_ch += ch if self.entry_id: self.entry_id_ch += ch if self.entry_name: self.entry_name_ch += ch if self.Step: self.Step_ch += ch if self.Phase: self.Phase_ch += ch if self.Attack_Description: self.Attack_Description_ch += ch if self.Technique: self.Technique_ch += ch if self.Likelihood_Of_Attack: self.Likelihood_Of_Attack_ch += ch if self.Typical_Severity: self.Typical_Severity_ch += ch
[docs] def endElement(self, name): if name == "Description" and not self.Attack_step_tag: self.Summary.append(self.Summary_ch.rstrip()) if self.Summary_ch != "": self.Summary_ch = "" self.Description_tag = False if name == "Entry_ID": self.entry_id = False if name == "Entry_Name": self.entry_name = False entry_id = self.entry_id_ch.rstrip() cut_entry = entry_id.split(".") url = "" if self.taxonomy_name == "ATTACK": if len(cut_entry) == 1: # no subtechnique use plain entry_id url = "https://attack.mitre.org/techniques/T{}".format(entry_id) else: # attack with subtechniques use cut_entry url = "https://attack.mitre.org/techniques/T{}/{}".format( cut_entry[0], cut_entry[1] ) elif self.taxonomy_name == "WASC": if "/" in self.entry_name_ch: url = "http://projects.webappsec.org/{}".format( self.entry_name_ch.replace("/", " and ").replace(" ", "-") ) else: url = "http://projects.webappsec.org/{}".format( self.entry_name_ch.replace(" ", "-") ) elif self.taxonomy_name == "OWASP Attacks": entry_id = "Link" url = "https://owasp.org/www-community/attacks/{}".format( self.entry_name_ch.replace(" ", "_") ) self.taxonomy_mapping[self.taxonomy_name][ self.entry_id_ch.rstrip().replace(".", "_") ] = { "Entry_ID": entry_id, "Entry_Name": self.entry_name_ch.rstrip(), "URL": url, } if self.entry_id_ch != "": self.entry_id_ch = "" if self.entry_name_ch != "": self.entry_name_ch = "" if name == "Taxonomy_Mappings": self.Taxonomy_Mappings = False if name == "Taxonomy_Mapping": self.Taxonomy_Mapping = False if name == "Step": self.step_name = self.Step_ch.rstrip() self.Step = False if name == "Phase": self.Phase = False if name == "Description" and self.Attack_step_tag: self.Attack_Description = False self.execution_flow[self.step_name] = { "Phase": self.Phase_ch.rstrip(), "Description": self.Attack_Description_ch.rstrip(), "Techniques": [], } if self.Step_ch != "": self.Step_ch = "" if self.Phase_ch != "": self.Phase_ch = "" if self.Attack_Description_ch != "": self.Attack_Description_ch = "" if name == "Technique" and self.Attack_step_tag: if self.Technique_ch != "": self.execution_flow[self.step_name]["Techniques"].append( self.Technique_ch.rstrip() ) self.Technique_ch = "" self.Technique = False if name == "Attack_Step": self.Attack_step_tag = False if name == "Execution_Flow": self.Execution_Flow = False if name == "Prerequisite": if self.Prerequisite_ch != "": self.Prerequisite.append(self.Prerequisite_ch.rstrip()) self.Prerequisite_tag = False if name == "Mitigation": if self.Mitigation_ch != "": self.Solution_or_Mitigation.append(self.Mitigation_ch.rstrip()) self.Mitigation_ch = "" self.Mitigation_tag = False if name == "Prerequisites": self.Prerequisites_tag = False if name == "Mitigations": self.Mitigations_tag = False if name == "Related_Weaknesses": self.Related_Weaknesses_tag = False if name == "Related_Attack_Patterns": self.Related_Attack_Patterns = False if name == "Likelihood_Of_Attack": self.Likelihood_Of_Attack = False self.loa = self.Likelihood_Of_Attack_ch.rstrip() self.Likelihood_Of_Attack_ch = "" if name == "Typical_Severity": self.Typical_Severity = False self.ts = self.Typical_Severity_ch.rstrip() self.Typical_Severity_ch = "" if name == "Attack_Pattern": if not self.name.startswith("DEPRECATED"): self.capec.append( { "name": self.name, "id": self.id, "summary": "\n".join(self.Summary), "prerequisites": " ".join(self.Prerequisite), "solutions": " ".join(self.Solution_or_Mitigation), "related_capecs": sorted(self.Related_AttackPatterns), "related_weakness": sorted(self.Related_Weakness), "taxonomy": dict(self.taxonomy_mapping), "execution_flow": dict(self.execution_flow), "loa": self.loa, "typical_severity": self.ts, } ) self.Summary = [] self.Prerequisite = [] self.Solution_or_Mitigation = [] self.Related_Weakness = [] self.Related_AttackPatterns = [] self.techniques = [] self.taxonomy_mapping = defaultdict(dict) self.execution_flow = defaultdict(dict) self.Attack_Pattern_tag = False if name == "Attack_Patterns": self.Attack_Patterns_tag = False if name == "Attack_Pattern_Catalog": self.Attack_Pattern_Catalog_tag = False
[docs]class CWEHandler(ContentHandler): """ Class handling the CWE XML parsing """
[docs] def __init__(self): self.cwe = [] self.description_tag = False self.category_tag = False self.weakness_tag = False self.weakness_relationships_tag = False self.category_relationships_tag = False
[docs] def startElement(self, name, attrs): if name == "Weakness": self.weakness_tag = True self.statement = "" self.weaknessabs = attrs.get("Abstraction") self.name = attrs.get("Name") self.idname = attrs.get("ID") self.status = attrs.get("Status") if not self.name.startswith("DEPRECATED"): self.cwe.append( { "name": self.name, "id": self.idname, "status": self.status, "weaknessabs": self.weaknessabs, } ) elif name == "Category": self.category_tag = True self.category_name = attrs.get("Name") self.category_id = attrs.get("ID") self.category_status = attrs.get("Status") if not self.category_name.startswith("DEPRECATED"): self.cwe.append( { "name": self.category_name, "id": self.category_id, "status": self.category_status, "weaknessabs": "Category", } ) elif name == "Description" and self.weakness_tag: self.description_tag = True self.description = "" elif name == "Summary" and self.category_tag: self.description_tag = True self.description = "" elif name == "Relationships" and self.category_tag: self.category_relationships_tag = True self.relationships = [] elif name == "Related_Weaknesses" and self.weakness_tag: self.weakness_relationships_tag = True self.relationships = [] elif name == "Related_Weakness" and self.weakness_relationships_tag: self.relationships.append(attrs.get("CWE_ID")) elif name == "Has_Member" and self.category_relationships_tag: self.relationships.append(attrs.get("CWE_ID"))
[docs] def characters(self, ch): if self.description_tag: self.description += ch.replace(" ", "")
[docs] def endElement(self, name): if name == "Description" and self.weakness_tag: self.description_tag = False self.description = self.description + self.description self.cwe[-1]["Description"] = self.description.replace("\n", "") if name == "Summary" and self.category_tag: self.description_tag = False self.description = self.description + self.description self.cwe[-1]["Description"] = self.description.replace("\n", "") elif name == "Weakness" and self.weakness_tag: self.weakness_tag = False elif name == "Category" and self.category_tag: self.category_tag = False elif name == "Related_Weaknesses" and self.weakness_tag: self.weakness_relationships_tag = False self.cwe[-1]["related_weaknesses"] = self.relationships elif name == "Relationships" and self.category_tag: self.category_relationships_tag = False self.cwe[-1]["relationships"] = self.relationships