def main(): stix_package = STIXPackage() # Build the Exploit Target vuln = Vulnerability() vuln.cve_id = "CVE-2014-0160" vuln.add_reference("http://heartbleed.com/") et = ExploitTarget(title="Heartbleed") et.add_vulnerability(vuln) stix_package.add_exploit_target(et) # Build the TTP ttp = TTP(title="Generic Heartbleed Exploits") ttp.exploit_targets.append(ExploitTarget(idref=et.id_)) stix_package.add_ttp(ttp) # Build the indicator indicator = Indicator(title="Snort Signature for Heartbleed") indicator.confidence = Confidence("High") tm = SnortTestMechanism() tm.rules = [ """alert tcp any any -> any any (msg:"FOX-SRT - Flowbit - TLS-SSL Client Hello"; flow:established; dsize:< 500; content:"|16 03|"; depth:2; byte_test:1, <=, 2, 3; byte_test:1, !=, 2, 1; content:"|01|"; offset:5; depth:1; content:"|03|"; offset:9; byte_test:1, <=, 3, 10; byte_test:1, !=, 2, 9; content:"|00 0f 00|"; flowbits:set,foxsslsession; flowbits:noalert; threshold:type limit, track by_src, count 1, seconds 60; reference:cve,2014-0160; classtype:bad-unknown; sid: 21001130; rev:9;)""", """alert tcp any any -> any any (msg:"FOX-SRT - Suspicious - TLS-SSL Large Heartbeat Response"; flow:established; flowbits:isset,foxsslsession; content:"|18 03|"; depth: 2; byte_test:1, <=, 3, 2; byte_test:1, !=, 2, 1; byte_test:2, >, 200, 3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid: 21001131; rev:5;)""" ] tm.efficacy = "Low" tm.producer = InformationSource(identity=Identity(name="FOX IT")) tm.producer.references = [ "http://blog.fox-it.com/2014/04/08/openssl-heartbleed-bug-live-blog/" ] indicator.test_mechanisms = TestMechanisms([tm]) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) print(stix_package.to_xml(encoding=None))
def main(): stix_package = STIXPackage() # Build the Exploit Target vuln = Vulnerability() vuln.cve_id = "CVE-2014-0160" vuln.add_reference("http://heartbleed.com/") et = ExploitTarget(title="Heartbleed") et.add_vulnerability(vuln) stix_package.add_exploit_target(et) # Build the TTP ttp = TTP(title="Generic Heartbleed Exploits") ttp.exploit_targets.append(ExploitTarget(idref=et.id_)) stix_package.add_ttp(ttp) # Build the indicator indicator = Indicator(title="Snort Signature for Heartbleed") indicator.confidence = Confidence("High") tm = SnortTestMechanism() tm.rules = [ """alert tcp any any -> any any (msg:"FOX-SRT - Flowbit - TLS-SSL Client Hello"; flow:established; dsize:< 500; content:"|16 03|"; depth:2; byte_test:1, <=, 2, 3; byte_test:1, !=, 2, 1; content:"|01|"; offset:5; depth:1; content:"|03|"; offset:9; byte_test:1, <=, 3, 10; byte_test:1, !=, 2, 9; content:"|00 0f 00|"; flowbits:set,foxsslsession; flowbits:noalert; threshold:type limit, track by_src, count 1, seconds 60; reference:cve,2014-0160; classtype:bad-unknown; sid: 21001130; rev:9;)""", """alert tcp any any -> any any (msg:"FOX-SRT - Suspicious - TLS-SSL Large Heartbeat Response"; flow:established; flowbits:isset,foxsslsession; content:"|18 03|"; depth: 2; byte_test:1, <=, 3, 2; byte_test:1, !=, 2, 1; byte_test:2, >, 200, 3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid: 21001131; rev:5;)""" ] tm.efficacy = "Low" tm.producer = InformationSource(identity=Identity(name="FOX IT")) tm.producer.references = ["http://blog.fox-it.com/2014/04/08/openssl-heartbleed-bug-live-blog/"] indicator.test_mechanisms = TestMechanisms([tm]) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) print(stix_package.to_xml(encoding=None))
def toStixXml(self, confidence, efficacy): """ This method converts a list of FASGuard generated Snort rules into a STIX compliant XML string ready for output. It first converts the object into a hash of the right format and then converts it into XML using STIXPackage.from_dict and to_xml on the resulting object. Arguments: confidence - High, Medium or Low. High means low false alarm rate. efficacy - High, Medium or Low. High means a low missed detection rate. Returns: Reference to string containing STIX/CybOX XML file. """ logger = logging.getLogger('simple_example') self.logger = logger self.logger.debug('In asg.fasguardStixRule') stix_package = STIXPackage() # Build the Exploit Target vuln = Vulnerability() vuln.cve_id = "Unknown" et = ExploitTarget(title="From FASGuard") et.add_vulnerability(vuln) stix_package.add_exploit_target(et) # Build the TTP ttp = TTP(title="FASGuard Produced Signatures") ttp.exploit_targets.append(ExploitTarget(idref=et.id_)) stix_package.add_ttp(ttp) # Build the indicator indicator = Indicator(title="Snort Signature from FASGuard") indicator.confidence = Confidence(confidence) tm = SnortTestMechanism() tm.rules = self.ruleList tm.efficacy = efficacy tm.producer = InformationSource(identity=Identity(name="FASGuard")) tm.producer.references = ["http://fasguard.github.io/"] indicator.test_mechanisms = [tm] indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) return stix_package.to_xml() # stixDict = {'campaigns': [{}], # 'courses_of_action': [{}], # 'exploit_targets': [{}], # 'id': 'INSERT_PACKAGE_ID_HERE'} # stixDict['indicators'] = [{'indicator': # {'title': # 'Automatically Generated FASGuard Signatures', # 'test_mechanisms': # {'test_mechanism': # {'efficacy':'Low', # 'producer': # {'Identity':'FASGuard'}, # 'rule':'xyz'}}}} # ] stix_package = STIXPackage.from_dict(stixDict) stix_xml = stix_package.to_xml() return stix_xml
def csv2stix(outFormat,inFile): #============= # Build package metadata #============= stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = "TG3390" stix_package.stix_header.description = "Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/" marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) stix_package.stix_header.handling = handling #============= # Build package structure #============= ta_tg3390 = ThreatActor(title="TG3390") ta_tg3390.identity = Identity(name="TG3390") attack_pattern = AttackPattern() attack_pattern.description = ("Infrastructure Building") ttp_infrastructure = TTP(title="Infrastructure Building") ttp_infrastructure.behavior = Behavior() ttp_infrastructure.behavior.add_attack_pattern(attack_pattern) ttp_infrastructure.add_intended_effect("Unauthorized Access") infra_domainInd = Indicator(title="Domains associated with TG3390 Infrastructure") infra_domainInd.add_indicator_type("Domain Watchlist") infra_domainInd.confidence = "High" infra_domainInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) infra_IPInd = Indicator(title="[H] IP Addresses associated with TG3390 Infrastructure") infra_IPInd.add_indicator_type("IP Watchlist") infra_IPInd.confidence = "High" infra_IPInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) infra_IPInd_M = Indicator(title="[M] IP Addresses associated with TG3390 Infrastructure") infra_IPInd_M.add_indicator_type("IP Watchlist") infra_IPInd_M.confidence = "Medium" infra_IPInd_M.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) httpBrowserObj = MalwareInstance() httpBrowserObj.add_name("HTTP Browser") ttp_httpB = TTP(title="HTTP Browser") ttp_httpB.behavior = Behavior() ttp_httpB.behavior.add_malware_instance(httpBrowserObj) ttp_httpB.add_intended_effect("Theft - Intellectual Property") httpB_hashInd = Indicator(title="File hashes for HTTP Browser") httpB_hashInd.add_indicator_type("File Hash Watchlist") httpB_hashInd.confidence = "High" httpB_hashInd.add_indicated_ttp(TTP(idref=ttp_httpB.id_)) httpBrowserDropperObj = MalwareInstance() httpBrowserDropperObj.add_name("HTTP Browser Dropper") ttp_httpBDpr = TTP(title="HTTP Browser Dropper") ttp_httpBDpr.behavior = Behavior() ttp_httpBDpr.behavior.add_malware_instance(httpBrowserDropperObj) ttp_httpBDpr.add_intended_effect("Theft - Intellectual Property") httpBDpr_hashInd = Indicator(title="File hashes for HTTP Browser Dropper") httpBDpr_hashInd.add_indicator_type("File Hash Watchlist") httpBDpr_hashInd.confidence = "High" httpBDpr_hashInd.add_indicated_ttp(TTP(idref=ttp_httpBDpr.id_)) plugXObj = MalwareInstance() plugXObj.add_name("PlugX Dropper") ttp_plugX = TTP(title="PlugX Dropper") ttp_plugX.behavior = Behavior() ttp_plugX.behavior.add_malware_instance(plugXObj) ttp_plugX.add_intended_effect("Theft - Intellectual Property") plugX_hashInd = Indicator(title="File hashes for PlugX Dropper") plugX_hashInd.add_indicator_type("File Hash Watchlist") plugX_hashInd.confidence = "High" plugX_hashInd.add_indicated_ttp(TTP(idref=ttp_plugX.id_)) #============= # Process content in to structure #============= ip_rules = [] ip_rules_M = [] domain_rules = [] with open(inFile, 'rb') as f: reader = csv.reader(f) for row in reader: obs = row[0] obsType = row[1] description = row[2] confidence = row[3] #print obs,obsType,description,confidence if description == 'TG-3390 infrastructure': if obsType == 'Domain name': domain_obj = DomainName() domain_obj.value = obs #domain_obj.title = description infra_domainInd.add_object(domain_obj) domain_rule = generate_snort([obs], 'DomainName', str(infra_domainInd.id_).split(':',1)[1].split('-',1)[1]) domain_rules.append(domain_rule) elif obsType == 'IP address': ipv4_obj = Address() ipv4_obj.category = "ipv4-addr" ipv4_obj.address_value = obs ipv4_obj.title = description ind_ref = str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1] if confidence == "High": infra_IPInd.add_object(ipv4_obj) ip_rules.append(obs) else: infra_IPInd_M.add_object(ipv4_obj) ip_rules_M.append(obs) else: print "TTP Infra: obsType is wrong" elif description == 'HttpBrowser RAT dropper': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description httpBDpr_hashInd.add_observable(file_obj) elif description == 'HttpBrowser RAT': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description httpB_hashInd.add_observable(file_obj) elif description == 'PlugX RAT dropper': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description plugX_hashInd.add_observable(file_obj) else: print "TTP not found" #print ip_rules ip_rule = generate_snort(ip_rules, 'Address', str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1]) ip_rule_M = generate_snort(ip_rules_M, 'Address', str(infra_IPInd_M.id_).split(':',1)[1].split('-',1)[1]) ip_tm = SnortTestMechanism() ip_tm.rules = [ip_rule] ip_tm.efficacy = "High" ip_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_IPInd.test_mechanisms = [ip_tm] ip_M_tm = SnortTestMechanism() ip_M_tm.rules = [ip_rule_M] ip_M_tm.efficacy = "Medium" ip_M_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_IPInd_M.test_mechanisms = [ip_M_tm] domain_tm = SnortTestMechanism() domain_tm.rules = domain_rules domain_tm.efficacy = "High" domain_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_domainInd.test_mechanisms = [domain_tm] #============= # Add the composed content to the structure #============= stix_package.add_indicator(infra_domainInd) stix_package.add_indicator(infra_IPInd) stix_package.add_indicator(infra_IPInd_M) stix_package.add_indicator(httpBDpr_hashInd) stix_package.add_indicator(httpB_hashInd) stix_package.add_indicator(plugX_hashInd) stix_package.add_ttp(ttp_infrastructure) stix_package.add_ttp(ttp_httpB) stix_package.add_ttp(ttp_httpBDpr) stix_package.add_ttp(ttp_plugX) """ if outFormat =='dict': print stix_package.to_dict() if outFormat =='json': parsed = stix_package.to_json() jsonpkg = json.loads(parsed) pprint.pprint(jsonpkg) if outFormat =='stix': print stix_package.to_xml() """ #if verbose: #print stix_package.to_xml() #pprint(stix_package.to_json()) return stix_package
def toStixXml(self, confidence, efficacy): """ This method converts a list of FASGuard generated Snort rules into a STIX compliant XML string ready for output. It first converts the object into a hash of the right format and then converts it into XML using STIXPackage.from_dict and to_xml on the resulting object. Arguments: confidence - High, Medium or Low. High means low false alarm rate. efficacy - High, Medium or Low. High means a low missed detection rate. Returns: Reference to string containing STIX/CybOX XML file. """ logger = logging.getLogger('simple_example') self.logger = logger self.logger.debug('In asg.fasguardStixRule') stix_package = STIXPackage() # Build the Exploit Target vuln = Vulnerability() vuln.cve_id = "Unknown" et = ExploitTarget(title="From FASGuard") et.add_vulnerability(vuln) stix_package.add_exploit_target(et) # Build the TTP ttp = TTP(title="FASGuard Produced Signatures") ttp.exploit_targets.append(ExploitTarget(idref=et.id_)) stix_package.add_ttp(ttp) # Build the indicator indicator = Indicator(title = "Snort Signature from FASGuard") indicator.confidence = Confidence(confidence) tm = SnortTestMechanism() tm.rules = self.ruleList tm.efficacy = efficacy tm.producer = InformationSource(identity=Identity(name="FASGuard")) tm.producer.references = ["http://fasguard.github.io/"] indicator.test_mechanisms = [tm] indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) return stix_package.to_xml() # stixDict = {'campaigns': [{}], # 'courses_of_action': [{}], # 'exploit_targets': [{}], # 'id': 'INSERT_PACKAGE_ID_HERE'} # stixDict['indicators'] = [{'indicator': # {'title': # 'Automatically Generated FASGuard Signatures', # 'test_mechanisms': # {'test_mechanism': # {'efficacy':'Low', # 'producer': # {'Identity':'FASGuard'}, # 'rule':'xyz'}}}} # ] stix_package = STIXPackage.from_dict(stixDict) stix_xml = stix_package.to_xml() return stix_xml
def adptr_dict2STIX(srcObj, data): sTxt = "Called... " sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()') stixObj = None ### Input Check if srcObj == None or data == None: #TODO: Needs error msg: Missing srcData Object return (False) ### Generate NameSpace id tags STIX_NAMESPACE = {"http://hailataxii.com": "opensource"} OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource") stix_set_id_namespace(STIX_NAMESPACE) obs_set_id_namespace(OBS_NAMESPACE) ### Building STIX Wrapper stix_package = STIXPackage() objIndicator = Indicator() ### Bulid Object Data for sKey in data: objIndicator = Indicator() listOBS = [] ### Parsing IP Address for sAddr in data[sKey]['attrib']['ipAddrList']: if len(sAddr) > 0: objAddr = Address() objAddr.is_destination = True objAddr.address_value = sAddr #objAddr.address_value.operator = 'Equals' objAddr.address_value.condition = 'Equals' if isIPv4(sAddr): objAddr.category = 'ipv4-addr' elif isIPv6(sAddr): objAddr.category = 'ipv6-addr' else: continue obsAddr = Observable(objAddr) objAddr = None obsAddr.sighting_count = 1 obsAddr.title = 'IP: ' + sAddr sDscrpt = 'IPv4' + ': ' + sAddr + " | " sDscrpt += "isDestination: True | " obsAddr.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsAddr) obsAddr = None ### Parsing Port Number sPort = data[sKey]['attrib']['ipPort'] if len(sPort) > 0: objPort = Port() objPort.port_value = int(sPort) objPort.port_value.condition = 'Equals' sProtocol = data[sKey]['attrib']['ipProt'] if len(sProtocol) > 0: objPort.layer4_protocol = sProtocol.upper() obsPort = Observable(objPort) objPort = None obsPort.sighting_count = 1 obsPort.title = 'Port: ' + sPort sDscrpt = 'PortNumber' + ': ' + sPort + " | " sDscrpt += "Protocol: " + sProtocol.upper() + " | " obsPort.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsPort) ### Add Generated observable to Indicator objIndicator.add_indicator_type("IP Watchlist") objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS from stix.extensions.test_mechanism.snort_test_mechanism import SnortTestMechanism from stix.common import InformationSource, Identity testMech = SnortTestMechanism() testMech.rules = [data[sKey]['attrib']['rule']] testMech.efficacy = "Unknown" infoSrc = InformationSource(identity=Identity(name=srcObj.Domain)) infoSrc.add_contributing_source("http://www.shadowserver.org") infoSrc.add_contributing_source("https://spyeyetracker.abuse.ch") infoSrc.add_contributing_source("https://palevotracker.abuse.ch") infoSrc.add_contributing_source("https://zeustracker.abuse.ch") testMech.producer = infoSrc lstRef = data[sKey]['attrib']['reference'].split('|') testMech.producer.references = lstRef objIndicator.test_mechanisms = [testMech] #Parsing Producer sProducer = srcObj.Domain if len(sProducer) > 0: objIndicator.set_producer_identity(sProducer) #objIndicator.set_produced_time(data[sKey]['attrib']['dateVF']); objIndicator.set_received_time(data[sKey]['dateDL']) ### Title / Description Generator objIndicator.set_received_time(data[sKey]['dateDL']) sTitle = "sid:" + data[sKey]['attrib']['sid'] + " | " sTitle += data[sKey]['attrib']['msg'] + " | " sTitle += "rev:" + data[sKey]['attrib']['rev'] objIndicator.title = sTitle sDscrpt = "SNORT Rule by Emergingthreats | " + data[sKey]['attrib'][ 'rule'] objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" #Parse TTP objMalware = MalwareInstance() nameList = data[sKey]['attrib']['flowbits'] if len(nameList) > 0: nameList = nameList.split("|") for sName in nameList: sName = sName.split(",")[1] objMalware.add_name(sName) #objMalware.add_type("Remote Access Trojan") objMalware.short_description = data[sKey]['attrib']['msg'] ttpTitle = data[sKey]['attrib']['classtype'] + " | " + data[sKey][ 'attrib']['msg'] objTTP = TTP(title=ttpTitle) objTTP.behavior = Behavior() objTTP.behavior.add_malware_instance(objMalware) objIndicator.add_indicated_ttp(objTTP) #objIndicator.add_indicated_ttp(TTP(idref=objTTP.id_)) #stix_package.add_ttp(objTTP) stix_package.add_indicator(objIndicator) objIndicator = None ### STIX Package Meta Data stix_header = STIXHeader() stix_header.title = srcObj.pkgTitle stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>" ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/ marking_specification = MarkingSpecification() classLevel = SimpleMarkingStructure() classLevel.statement = "Unclassified (Public)" marking_specification.marking_structures.append(classLevel) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" objTOU = TermsOfUseMarkingStructure() sTOU = open('tou.txt').read() objTOU.terms_of_use = sProducer + " | " + sTOU marking_specification.marking_structures.append(objTOU) handling = Marking() handling.add_marking(marking_specification) stix_header.handling = handling stix_package.stix_header = stix_header stix_header = None ### Generate STIX XML File locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml' sndFile(stix_package.to_xml(), locSTIXFile) return (stix_package)