def genObject_MarkingSpecification(data=None): from stix.extensions.marking.terms_of_use_marking import TermsOfUseMarkingStructure objTOU = TermsOfUseMarkingStructure() try: objTOU.terms_of_use = open('tou.txt').read() except: objTOU.terms_of_use = None from stix.extensions.marking.simple_marking import SimpleMarkingStructure objSimpleMarkingStructure = SimpleMarkingStructure() objSimpleMarkingStructure.statement = data['source'][ "stix.extensions.marking.simple_marking.SimpleMarkingStructure.statement"] from stix.extensions.marking.tlp import TLPMarkingStructure objTLP = TLPMarkingStructure() objTLP.color = data['source'][ 'stix.extensions.marking.tlp.TLPMarkingStructure.color'] from stix.data_marking import MarkingSpecification objMarkingSpecification = MarkingSpecification() objMarkingSpecification.idref = None objMarkingSpecification.version = None objMarkingSpecification.marking_structures = [] objMarkingSpecification.marking_structures.append( objSimpleMarkingStructure) objMarkingSpecification.marking_structures.append(objTLP) objMarkingSpecification.marking_structures.append(objTOU) ### Externally Modified # objMarkingSpecification.controlled_structure = None return (objMarkingSpecification)
def setTLP(target, distribution, tags, sort=False): marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() attrColors = fetchColors(tags.get('attributes')) if ('attributes' in tags) else [] if attrColors: color = setColor(attrColors) else: eventColors = fetchColors(tags.get('event')) if ('event' in tags) else [] if eventColors: color = setColor(eventColors) else: color = TLP_mapping.get(distribution, None) #for tag in tags: # if tag["name"].startswith("tlp:") and tag["name"].count(':') == 1: # new_colour = tag["name"][4:].upper() # if colour and sort: # if TLP_order[colour] < TLP_order[new_colour]: # colour = new_colour # else: # colour = new_colour if color is None: return target tlp.color = color marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) target.handling = handling
def _get_tlp_marking_structure(self, feed): tlp_marking_structure = TLPMarkingStructure() tlp_marking_structure.color = feed.tlp marking_specification = MarkingSpecification() marking_specification.marking_structures = tlp_marking_structure marking_specification.controlled_structure = '../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*' return marking_specification
def _make_marking_specification_statement(self, key, value, controlled_structure=None): simple_marking_structres = SimpleMarkingStructure() statement = '%s: %s' % (key, value) simple_marking_structres.statement = statement marking_specification = MarkingSpecification() marking_specification.marking_structures = simple_marking_structres marking_specification.controlled_structure = controlled_structure return marking_specification
def main(): mydata = loaddata() ''' Your Namespace ''' # NAMESPACE = {sanitizer(mydata["NSXURL"]) : (mydata["NS"])} # set_id_namespace(NAMESPACE) NAMESPACE = Namespace(sanitizer(mydata['NSXURL']), sanitizer(mydata['NS'])) set_id_namespace(NAMESPACE) # new ids will be prefixed by "myNS" wrapper = STIXPackage() info_src = InformationSource() info_src.identity = Identity(name=sanitizer(mydata["Identity"])) marking_specification = MarkingSpecification() marking_specification.controlled_structure = "//node() | //@*" tlp = TLPMarkingStructure() tlp.color = sanitizer(mydata["TLP_COLOR"]) marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) timestamp = datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S') MyTITLE = sanitizer(mydata["Title"]) SHORT = timestamp DESCRIPTION = sanitizer(mydata["Description"]) wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE, description=DESCRIPTION, short_description=SHORT) wrapper.stix_header.handling = handling indiDom = Indicator() indiDom.title = MyTITLE indiDom.add_indicator_type("IP Watchlist") for key in mydata["IOC"].keys(): myip = Address(address_value=sanitizer(key), category=Address.CAT_IPV4) myip.condition = "Equals" obsu = Observable(myip) #if mydata[key].size: for idx, mydata["IOC"][key] in enumerate(mydata["IOC"][key]): ioc = File() ioc.add_hash(sanitizer(mydata["IOC"][key])) myip.add_related(ioc, "Downloaded") indiDom.add_observable(obsu) wrapper.add_indicator(indiDom) print(wrapper.to_xml())
def main(): # Create a new stixmarx MarkingContainer with a # new STIXPackage object contained within it. container = stixmarx.new() # Get the associated STIX Package package = container.package # Create an Indicator object indicator = Indicator(title='Indicator Title', description='Gonna Mark This') # Add the Indicator object to our STIX Package package.add(indicator) # Build MarkingSpecification and add TLP MarkingStructure red_marking = MarkingSpecification(marking_structures=TLP(color="RED")) amber_marking = MarkingSpecification(marking_structures=TLP(color="AMBER")) green_marking = MarkingSpecification(marking_structures=TLP(color="GREEN")) # Mark the indicator with our TLP RED marking # This is the equivalent of a component marking. Applies to all descendants # nodes, text and attributes. container.add_marking(indicator, red_marking, descendants=True) # Mark the indicator with TLP GREEN. If descendants is false, the marking # will only apply to the indicator node. Does NOT include text, attributes # or descendants. container.add_marking(indicator, green_marking) # Mark the description text. # >>> type(indicator.description.value) <type 'str'> indicator.description.value = container.add_marking( indicator.description.value, amber_marking) # >>> type(indicator.description.value) <class 'stixmarx.api.types.MarkableBytes'> # Mark the indicator timestamp attribute. # >>> type(indicator.description.value) <type 'datetime.datetime'> indicator.timestamp = container.add_marking(indicator.timestamp, amber_marking) # >>> type(indicator.description.value) <type 'stixmarx.api.types.MarkableDateTime'> # Print the XML! print(container.to_xml().decode("utf-8"))
def convert_marking_definition(marking20): definition = marking20["definition"] marking_spec = MarkingSpecification() if marking20["definition_type"] == "statement": tou = TermsOfUseMarkingStructure(terms_of_use=definition["statement"]) tou.id_ = convert_id20(marking20["id"]) marking_spec.marking_structures.append(tou) elif marking20["definition_type"] == "tlp": tlp = TLPMarkingStructure(color=definition["tlp"]) tlp.id_ = convert_id20(marking20["id"]) marking_spec.marking_structures.append(tlp) elif marking20["definition_type"] == "ais": identity20_tuple = _EXPLICIT_OBJECT_USED[marking20["created_by_ref"]] color = definition["tlp"].upper() if definition["is_proprietary"] == "true": proprietary = IsProprietary() consent = "EVERYONE" else: proprietary = NotProprietary() consent = definition["consent"].upper() proprietary.ais_consent = AISConsentType(consent=consent) proprietary.tlp_marking = TLPMarkingType(color=color) ais_marking = AISMarkingStructure() ais_marking.id_ = convert_id20(marking20["id"]) if isinstance(proprietary, IsProprietary): ais_marking.is_proprietary = proprietary else: ais_marking.not_proprietary = proprietary marking_spec.controlled_structure = "//node() | //@*" marking_spec.marking_structures.append(ais_marking) marking_spec.information_source = create_information_source( identity20_tuple) # Remove marking to CIQ identity. Special case for AIS. for mark_spec in CONTAINER.get_markings(identity20_tuple[0]): mark_struct = mark_spec.marking_structures[0] if mark_struct.idref and mark_struct.idref == ais_marking.id_: CONTAINER.remove_marking(identity20_tuple[0], mark_spec, True) record_id_object_mapping(marking20["id"], marking_spec.marking_structures[0]) if "object_marking_refs" in marking20: for m_id in marking20["object_marking_refs"]: ms = create_marking_specification(m_id) if ms: CONTAINER.add_marking(marking_spec, ms, descendants=True) if "granular_markings" in marking20: error( "Granular Markings present in '%s' are not supported by stix2slider", 604, marking20["id"]) return marking_spec
def create_marking_specification(id20): if id20 in _ID_OBJECT_MAPPING: marking1x = _ID_OBJECT_MAPPING[id20] if isinstance(marking1x, AISMarkingStructure): return # This is a special case for AIS. marking_spec = MarkingSpecification() marking_struct = MarkingStructure() marking_struct.idref = convert_id20(id20) marking_spec.marking_structures.append(marking_struct) return marking_spec
def generate_stix_header(self): handling_markings = extract_handling_markings(self) stix_header = STIXHeader( handling=Marking([ MarkingSpecification( controlled_structure=PackageXPath.make_marking_xpath_by_node_relative(), marking_structures=generate_marking_structure(self, handling_markings), ) ]), ) return stix_header
def setTLP(target, distribution): marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() colour = TLP_mapping.get(distribution, None) if colour is None: return target tlp.color = colour marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) target.handling = handling
def test_global_marking_on_observables(self): """Test that global markings apply to Obseravbles""" container = stixmarx.new() package = container.package red_marking = generate_marking_spec(generate_red_marking_struct()) container.add_global(red_marking) observable = generate_observable() package.add_observable(observable) self.assertTrue(container.is_marked(observable, red_marking)) self.assertFalse( container.is_marked(observable, MarkingSpecification()))
def _marking(self): """Define the TLP marking and the inheritance.""" marking_specification = MarkingSpecification() tlp = TLPMarkingStructure() tlp.color = self.pulse["TLP"].upper() marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*" simple = SimpleMarkingStructure() simple.statement = "Automated ingest from AlienVault OTX." marking_specification.marking_structures.append(simple) handling = Marking() handling.add_marking(marking_specification) return handling
def _marking(): """Define the TLP marking and the inheritance.""" marking_specification = MarkingSpecification() tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "../../../../descendant"\ "-or-self::node() | ../../../../descendant-or-self::node()/@*" simple = SimpleMarkingStructure() simple.statement = HNDL_ST marking_specification.marking_structures.append(simple) handling = Marking() handling.add_marking(marking_specification) return handling
def _marking(): """Define the TLP marking and the inheritance.""" marking_specification = MarkingSpecification() tlp = TLPMarkingStructure() tlp.color = SETTINGS['stix']['tlp'] marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = SETTINGS['stix'][ 'controlled_structure'] simple = SimpleMarkingStructure() simple.statement = SETTINGS['stix']['statement'] marking_specification.marking_structures.append(simple) handling = Marking() handling.add_marking(marking_specification) return handling
def to_stix_tlp(obj): from stix.data_marking import Marking, MarkingSpecification from stix.extensions.marking.tlp import TLPMarkingStructure marking_specification = MarkingSpecification() marking_specification.controlled_structure = "//node() | //@*" tlp = TLPMarkingStructure() tlp.color = obj.tlp marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) return handling
def convert(self, stix_id_prefix='', published_only=True, **kw_arg): self.parse(**kw_arg) stix_packages = [] for event in self.events: if published_only: if not event.published: continue # id generator package_id = self.get_misp_pacakge_id(stix_id_prefix, event) stix_package = STIXPackage(timestamp=event.dt, id_=package_id) stix_header = STIXHeader() # set identity information identity = Identity(name=self.identity_name) information_source = InformationSource(identity=identity) stix_header.information_source = information_source tlp = None for tag in event.tags: if tag.tlp is not None: tlp = tag.tlp break if tlp is not None: # TLP for Generic format tlp_marking_structure = TLPMarkingStructure() tlp_marking_structure.color = tlp marking_specification = MarkingSpecification() marking_specification.marking_structures = tlp_marking_structure marking_specification.controlled_structure = '../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*' marking = Marking() marking.add_marking(marking_specification) stix_header.handling = marking stix_header.title = event.info stix_header.description = event.info stix_header.short_description = event.info for attribute in event.attributes: stix_package.add_indicator(attribute.convert()) stix_package.stix_header = stix_header stix_packages.append(stix_package) return stix_packages
def gen_stix_indicator_sample(config, target=None, datatype=None, title='random test data', description='random test data', package_intents='Indicators - Watchlist', tlp_color='WHITE', observables_list=None): '''generate sample stix data comprised of indicator_count indicators of type datatype''' # setup the xmlns... xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name'] set_stix_id_namespace({xmlns_url: xmlns_name}) set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) # construct a stix package... stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = title stix_header.description = description stix_header.package_intents = package_intents marking = MarkingSpecification() marking.controlled_structure = '../../../../descendant-or-self::node()' tlp_marking = TLPMarkingStructure() tlp_marking.color = tlp_color marking.marking_structures.append(tlp_marking) stix_package.stix_header = stix_header stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking) indicator_ = Indicator() indicator_.title = str(uuid.uuid4()) + '_sample_indicator' indicator_.confidence = 'Unknown' indicator_.add_indicator_type('Malware Artifacts') observable_composition_ = ObservableComposition() observable_composition_.operator = \ indicator_.observable_composition_operator for observable_id in observables_list: observable_ = Observable() observable_.idref = observable_id observable_composition_.add(observable_) indicator_.observable = Observable() indicator_.observable.observable_composition = observable_composition_ stix_package.add_indicator(indicator_) return (stix_package)
def main(): # Make the ISA Markings structure isa = ISAMarkings() isa.create_date_time = dates.now() isa.identifier = "this:is:a:test" # Wire up the STIX marking types marking_spec = MarkingSpecification() marking_spec.controlled_structure = "//node | //@*" marking_spec.marking_structures.append(isa) # Add the ISA marking structure handling = Marking() handling.marking.append(marking_spec) # Create the STIX Package and add our data markings to the handling section. package = STIXPackage() package.stix_header = STIXHeader(title="ISA Markings Test") package.stix_header.handling = handling print(package.to_xml(include_schemalocs=True))
def setTLP(target, distribution, tags, sort=False): marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() colour = TLP_mapping.get(distribution, None) for tag in tags: if tag["name"].startswith("tlp:") and tag["name"].count(':') == 1: new_colour = tag["name"][4:].upper() if colour and sort: if TLP_order[colour] < TLP_order[new_colour]: colour = new_colour else: colour = new_colour if colour is None: return target tlp.color = colour marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) target.handling = handling
def set_tlp(self, target, distribution, tags): marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() attr_colors = self.fetch_colors(tags.get('attributes')) if 'attributes' in tags else [] if attr_colors: color = self.set_color(attr_colors) else: event_colors = self.fetch_colors(tags.get('event')) if 'event' in tags else [] if event_colors: color = self.set_color(event_colors) else: color = TLP_mapping.get(str(distribution), None) if color is None: return target tlp.color = color marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) target.handling = handling return target
def stix_pkg(config, src, endpoint, payload, title='random test data', description='random test data', package_intents='Indicators - Watchlist', tlp_color='WHITE', dest=None): '''package observables''' # setup the xmlns... xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name'] set_stix_id_namespace({xmlns_url: xmlns_name}) set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) # construct a stix package... stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = title stix_header.description = description stix_header.package_intents = package_intents marking = MarkingSpecification() marking.controlled_structure = '../../../../descendant-or-self::node()' tlp_marking = TLPMarkingStructure() tlp_marking.color = tlp_color marking.marking_structures.append(tlp_marking) stix_package.stix_header = stix_header stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking) if isinstance(payload, Observable): stix_package.add_observable(payload) elif isinstance(payload, Indicator): stix_package.add_indicator(payload) elif isinstance(payload, Incident): stix_package.add_incident(payload) return (stix_package)
def __map_stix_header(self, event): self.init() stix_header = STIXHeader(title=event.title) stix_header.description = event.description stix_header.short_description = event.title identifiy = self.create_stix_identity(event) time = self.cybox_mapper.get_time(produced_time=event.created_at, received_time=event.modified_on) info_source = InformationSource(identity=identifiy, time=time) stix_header.information_source = info_source # Add TLP marking = Marking() marking_spec = MarkingSpecification() marking.add_marking(marking_spec) tlp_marking_struct = TLPMarkingStructure() tlp_marking_struct.color = event.tlp.upper() tlp_marking_struct.marking_model_ref = 'http://govcert.lu/en/docs/POL_202_V2.2_rfc2350.pdf' marking_spec.marking_structures = list() marking_spec.marking_structures.append(tlp_marking_struct) stix_header.handling = marking return stix_header
def main(argv): ###################################################################### # Se non impostati da command line vengono utilizzati i seguenti valori per TITLE, DESCRIPTION, IDENTITY # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28) TITLE = "Test" # La description strutturiamola come segue # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)> DESCRIPTION = "Cyber Saiyan - Test - https://infosharing.cybersaiyan.it" # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community IDENTITY = "Cyber Saiyan Community" # File degli IoC IOCFILE = "CS-ioc.txt" # Prefisso STIX output files STIX 1.2 e STIX 2 OUTFILEPREFIX = "package" # Short Description - UNUSED SHORT = "unused" ###################################################################### VERBOSE = 0 # Parse ARGV[] try: opts, args = getopt.getopt(argv, "ht:d:i:f:o:v") except getopt.GetoptError: print( "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]") sys.exit(2) for opt, arg in opts: if opt == "-h": print( "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]") sys.exit() elif opt == "-t": TITLE = arg elif opt == "-d": DESCRIPTION = arg elif opt == "-i": IDENTITY = arg elif opt == "-f": IOCFILE = arg elif opt == "-o": OUTFILEPREFIX = arg elif opt == "-v": VERBOSE = 1 print("---------------------") print("TITLE: " + TITLE) print("DESCRIPTION: " + DESCRIPTION) print("IDENTITY: " + IDENTITY) print("IOC FILE: " + IOCFILE) print("---------------------") ######################## # Commond data timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") ######################## # Build STIX 1.2 file info_src = InformationSource() info_src.identity = Identity(name=IDENTITY) NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN") set_id_namespace(NAMESPACE) wrapper = STIXPackage() marking_specification = MarkingSpecification() marking_specification.controlled_structure = "//node() | //@*" tlp = TLPMarkingStructure() tlp.color = "white" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) wrapper.stix_header = STIXHeader(information_source=info_src, title=TITLE, description=DESCRIPTION, short_description=SHORT) wrapper.stix_header.handling = handling # HASH indicators indicatorHASH = Indicator() indicatorHASH.title = TITLE + " - HASH" indicatorHASH.add_indicator_type("File Hash Watchlist") # DOMAIN indicators indiDOMAIN = Indicator() indiDOMAIN.title = TITLE + " - DOMAIN" indiDOMAIN.add_indicator_type("Domain Watchlist") # URL indicators indiURL = Indicator() indiURL.title = TITLE + " - URL" indiURL.add_indicator_type("URL Watchlist") # IP indicators indiIP = Indicator() indiIP.title = TITLE + " - IP" indiIP.add_indicator_type("IP Watchlist") # EMAIL indicators indiEMAIL = Indicator() indiEMAIL.title = TITLE + " - EMAIL" indiEMAIL.add_indicator_type("Malicious E-mail") ######################## # Build STIX 2 file pattern_sha256 = [] pattern_md5 = [] pattern_sha1 = [] pattern_domain = [] pattern_url = [] pattern_ip = [] pattern_email = [] # Marking marking_def_white = stix2.TLP_WHITE # campagna # [TODO] aggiungere tutti i campi dello STIX 1.2 (es. IDENTITY) campaign_MAIN = stix2.Campaign( created=timestamp, modified=timestamp, name=TITLE, description=DESCRIPTION, first_seen=timestamp, objective="TBD" ) ######################## # Read IoC file loaddata(IOCFILE) if (VERBOSE): print("Reading IoC file " + IOCFILE + "...") ioccount = 0 # sha256 for ioc in listSHA256: # STIX 1.2 filei = File() filei.add_hash(Hash(ioc)) obsi = Observable(filei) indicatorHASH.add_observable(obsi) if (VERBOSE): print("SHA256: " + ioc) ioccount += 1 # STIX 2 pattern_sha256.append("[file:hashes.'SHA-256' = '" + ioc + "'] OR ") # md5 for ioc in listMD5: # STIX 1.2 filej = File() filej.add_hash(Hash(ioc)) obsj = Observable(filej) indicatorHASH.add_observable(obsj) if (VERBOSE): print("MD5: " + ioc) ioccount += 1 # STIX 2 pattern_md5.append("[file:hashes.'MD5' = '" + ioc + "'] OR ") # sha1 for ioc in listSHA1: # STIX 1.2 filek = File() filek.add_hash(Hash(ioc)) obsk = Observable(filek) indicatorHASH.add_observable(obsk) if (VERBOSE): print("SHA1: " + ioc) ioccount += 1 # STIX 2 pattern_sha1.append("[file:hashes.'SHA1' = '" + ioc + "'] OR ") # domains for ioc in listDOMAIN: # STIX 1.2 url = URI() url.value = ioc url.type_ = URI.TYPE_DOMAIN url.condition = "Equals" obsu = Observable(url) indiDOMAIN.add_observable(obsu) if (VERBOSE): print("DOMAIN: " + ioc) ioccount += 1 # STIX 2 pattern_domain.append("[domain-name:value = '" + ioc + "'] OR ") # url for ioc in listURL: # STIX 1.2 url = URI() url.value = ioc url.type_ = URI.TYPE_URL url.condition = "Equals" obsu = Observable(url) indiURL.add_observable(obsu) if (VERBOSE): print("URL: " + ioc) ioccount += 1 # STIX 2 pattern_url.append("[url:value = '" + ioc + "'] OR ") # ip for ioc in listIP: # STIX 1.2 ip = Address() ip.address_value = ioc obsu = Observable(ip) indiIP.add_observable(obsu) if (VERBOSE): print("IP: " + ioc) ioccount += 1 # STIX 2 pattern_ip.append("[ipv4-addr:value = '" + ioc + "'] OR ") # email for ioc in listEMAIL: # STIX 1.2 email = EmailAddress() email.address_value = ioc obsu = Observable(email) indiEMAIL.add_observable(obsu) if (VERBOSE): print("Email: " + ioc) ioccount += 1 # STIX 2 pattern_email.append("[email-message:from_ref.value = '" + ioc + "'] OR ") # subject for ioc in listSUBJECT: # STIX 1.2 emailsubject = EmailMessage() emailsubject.subject = ioc obsu = Observable(emailsubject) indiEMAIL.add_observable(obsu) if (VERBOSE): print("Subject: " + ioc) ioccount += 1 # STIX 2 (http://docs.oasis-open.org/cti/stix/v2.0/stix-v2.0-part5-stix-patterning.html) # Replace all quotes in a subject string with escaped quotes pattern_email.append("[email-message:subject = '" + ioc.replace("'", "\\'") + "'] OR ") ######################## # add all indicators to STIX 1.2 wrapper.add_indicator(indicatorHASH) wrapper.add_indicator(indiDOMAIN) wrapper.add_indicator(indiURL) wrapper.add_indicator(indiIP) wrapper.add_indicator(indiEMAIL) ######################## # prepare for STIX 2 bundle_objects = [campaign_MAIN, marking_def_white] if len(pattern_sha256) != 0: stix2_sha256 = "".join(pattern_sha256) stix2_sha256 = stix2_sha256[:-4] indicator_SHA256 = stix2.Indicator( name=TITLE + " - SHA256", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_sha256, object_marking_refs=[marking_def_white] ) relationship_indicator_SHA256 = stix2.Relationship(indicator_SHA256, "indicates", campaign_MAIN) bundle_objects.append(indicator_SHA256) bundle_objects.append(relationship_indicator_SHA256) if len(pattern_md5) != 0: stix2_md5 = "".join(pattern_md5) stix2_md5 = stix2_md5[:-4] indicator_MD5 = stix2.Indicator( name=TITLE + " - MD5", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_md5, object_marking_refs=[marking_def_white] ) relationship_indicator_MD5 = stix2.Relationship(indicator_MD5, "indicates", campaign_MAIN) bundle_objects.append(indicator_MD5) bundle_objects.append(relationship_indicator_MD5) if len(pattern_sha1) != 0: stix2_sha1 = "".join(pattern_sha1) stix2_sha1 = stix2_sha1[:-4] indicator_SHA1 = stix2.Indicator( name=TITLE + " - SHA1", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_sha1, object_marking_refs=[marking_def_white] ) relationship_indicator_SHA1 = stix2.Relationship(indicator_SHA1, "indicates", campaign_MAIN) bundle_objects.append(indicator_SHA1) bundle_objects.append(relationship_indicator_SHA1) if len(pattern_domain) != 0: stix2_domain = "".join(pattern_domain) stix2_domain = stix2_domain[:-4] indicator_DOMAINS = stix2.Indicator( name=TITLE + " - DOMAINS", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_domain, object_marking_refs=[marking_def_white] ) relationship_indicator_DOMAINS = stix2.Relationship(indicator_DOMAINS, "indicates", campaign_MAIN) bundle_objects.append(indicator_DOMAINS) bundle_objects.append(relationship_indicator_DOMAINS) if len(pattern_url) != 0: stix2_url = "".join(pattern_url) stix2_url = stix2_url[:-4] indicator_URLS = stix2.Indicator( name=TITLE + " - URL", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_url, object_marking_refs=[marking_def_white] ) relationship_indicator_URLS = stix2.Relationship(indicator_URLS, "indicates", campaign_MAIN) bundle_objects.append(indicator_URLS) bundle_objects.append(relationship_indicator_URLS) if len(pattern_ip) != 0: stix2_ip = "".join(pattern_ip) stix2_ip = stix2_ip[:-4] indicator_IPS = stix2.Indicator( name=TITLE + " - IPS", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_ip, object_marking_refs=[marking_def_white] ) relationship_indicator_IPS = stix2.Relationship(indicator_IPS, "indicates", campaign_MAIN) bundle_objects.append(indicator_IPS) bundle_objects.append(relationship_indicator_IPS) if len(pattern_email) != 0: stix2_email = "".join(pattern_email) stix2_email = stix2_email[:-4] indicator_EMAILS = stix2.Indicator( name=TITLE + " - EMAILS", created=timestamp, modified=timestamp, description=DESCRIPTION, labels=["malicious-activity"], pattern=stix2_email, object_marking_refs=[marking_def_white] ) relationship_indicator_EMAILS = stix2.Relationship(indicator_EMAILS, "indicates", campaign_MAIN) bundle_objects.append(indicator_EMAILS) bundle_objects.append(relationship_indicator_EMAILS) # creo il bunble STIX 2 bundlestix2 = stix2.Bundle(objects=bundle_objects) if (ioccount > 0): ######################## # save to STIX 1.2 file print("Writing STIX 1.2 package: " + OUTFILEPREFIX + ".stix") f = open(OUTFILEPREFIX + ".stix", "wb") f.write(wrapper.to_xml()) f.close() ######################## # save to STIX 2 file print("Writing STIX 2 package: " + OUTFILEPREFIX + ".stix2") g = open(OUTFILEPREFIX + ".stix2", "w") g.write(str(bundlestix2)) g.close() else: print("No IoC found")
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 sAddr = data[sKey]['attrib']['ipAddr'] if len(sAddr) > 0: objAddr = Address() objAddr.is_source = True objAddr.address_value = sAddr 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 += "isSource: True | " obsAddr.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsAddr) obsAddr = None objIndicator.add_indicator_type("IP Watchlist") ### Parsing Domain sDomain = data[sKey]['attrib']['domain'] if len(sDomain) > 0: objDomain = DomainName() objDomain.value = sDomain objDomain.value.condition = 'Equals' if isFQDN(sDomain): objDomain.type = 'FQDN' elif isTLD(sDomain): objDomain.type = 'TLD' else: continue obsDomain = Observable(objDomain) objDomain = None obsDomain.sighting_count = 1 obsDomain.title = 'Domain: ' + sDomain sDscrpt = 'Domain: ' + sDomain + " | " sDscrpt += "isFQDN: True | " obsDomain.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsDomain) obsDomain = None objIndicator.add_indicator_type("Domain Watchlist") #Parser URI sURI = data[sKey]['attrib']['URI'] if len(sURI) > 0: objURI = URI() objURI.value = sURI objURI.value.condition = 'Equals' objURI.type_ = URI.TYPE_URL obsURI = Observable(objURI) objURI = None obsURI.sighting_count = 1 obsURI.title = 'URI: ' + sURI sDscrpt = 'URI: ' + sURI + " | " sDscrpt += "Type: URL | " obsURI.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsURI) obsURI = None objIndicator.add_indicator_type("URL Watchlist") #Parser File Hash sHash = data[sKey]['attrib']['hash'] if len(sHash) > 0: objFile = File() sFileName = data[sKey]['attrib']['fileName'] if len(sFileName) > 0: objFile.file_name = sFileName objFile.file_format = sFileName.split('.')[1] objFile.add_hash(Hash(sHash, exact=True)) obsFile = Observable(objFile) objFile = None obsFile.sighting_count = 1 obsFile.title = 'File: ' + sFileName sDscrpt = 'FileName: ' + sFileName + " | " sDscrpt += "FileHash: " + sHash + " | " obsFile.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsFile) obsFile = None objIndicator.add_indicator_type("File Hash Watchlist") ### Add Generated observable to Indicator objIndicator.observables = listOBS objIndicator.observable_composition_operator = 'OR' #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']) ### Old Title / Description Generator #objIndicator.title = data[sKey]['attrib']['title']; #objIndicator.description = "<![CDATA[" + data[sKey]['attrib']['dscrpt'] + "]]>"; ### Generate Indicator Title based on availbe data sTitle = 'ZeuS Tracker (' + data[sKey]['attrib'][ 'status'] + ')| ' + data[sKey]['attrib']['title'] if len(sAddr) > 0: sAddLine = "This IP address has been identified as malicious" if len(sDomain) > 0: sAddLine = "This domain has been identified as malicious" if len(sAddLine) > 0: sTitle = sTitle + " | " + sAddLine if len(srcObj.Domain) > 0: sTitle = sTitle + " by " + srcObj.Domain else: sTitle = sTitle + "." if len(sTitle) > 0: objIndicator.title = sTitle #Generate Indicator Description based on availbe data sDscrpt = "" if len(sAddr) > 0: sAddLine = "This IP address " + sAddr if len(sDomain) > 0: sAddLine = "This domain " + sDomain if len(sAddr) > 0 and len(sDomain) > 0: sAddLine = "This domain " + sDomain + " (" + sAddr + ")" if len(sAddLine) > 0: sDscrpt = sDscrpt + sAddLine sDscrpt = sDscrpt + " has been identified as malicious" if len(srcObj.Domain) > 0: sDscrpt = sDscrpt + " by " + srcObj.Domain else: sDscrpt = sDscrpt + "." sDscrpt = sDscrpt + ". For more detailed infomation about this indicator go to [CAUTION!!Read-URL-Before-Click] [" + data[ sKey]['attrib']['link'] + "]." if len(sDscrpt) > 0: objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" #Parse TTP objMalware = MalwareInstance() objMalware.add_name("ZeuS") objMalware.add_name("Zbot") objMalware.add_name("Zeus") objMalware.add_type("Remote Access Trojan") objMalware.short_description = "Zeus, ZeuS, or Zbot is Trojan horse computer malware effects Microsoft Windows operating system" objMalware.description = "Zeus, ZeuS, or Zbot is Trojan horse computer malware that runs on computers running under versions of the Microsoft Windows operating system. While it is capable of being used to carry out many malicious and criminal tasks, it is often used to steal banking information by man-in-the-browser keystroke logging and form grabbing. It is also used to install the CryptoLocker ransomware.[1] Zeus is spread mainly through drive-by downloads and phishing schemes. (2014(http://en.wikipedia.org/wiki/Zeus_%28Trojan_horse%29))" objTTP = TTP(title="ZeuS") 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) objTOU = TermsOfUseMarkingStructure() sTOU = open('tou.txt').read() objTOU.terms_of_use = sProducer + " | " + sTOU marking_specification.marking_structures.append(objTOU) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" 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)
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 = [] oObsSrcData = genObsSrcData(srcObj, data[sKey]) ### Parsing IP Address sAddr = data[sKey]['attrib']['ip'] if len(sAddr) > 0: objAddr = Address() objAddr.is_destination = True objAddr.address_value = sAddr objAddr.address_value.condition = 'Equals' if isIPv4(sAddr): objAddr.type = 'ipv4-addr' elif isIPv6(sAddr): objAddr.type = 'ipv6-addr' else: continue obsAddr = Observable(objAddr) objAddr = None obsAddr.sighting_count = 1 oObsSrcData.sighting_count = 1 obsAddr.observable_source.append(oObsSrcData) sTitle = 'IP: ' + sAddr obsAddr.title = sTitle sDscpt = 'ipv4-addr' + ': ' + sAddr + " | " sDscpt += "is_destination: True | " if data[sKey]['attrib']['first']: sDscpt += "firstSeen: " + data[sKey]['attrib']['first'] + " | " if data[sKey]['attrib']['last']: sDscpt += "lastSeen: " + data[sKey]['attrib']['last'] + " | " obsAddr.description = "<![CDATA[" + sDscpt + "]]>" listOBS.append(obsAddr) obsAddr = None ### Parsing Network Address sAddr = data[sKey]['attrib']['inetnum'] if sAddr: objAddr = Address() objAddr.is_destination = True sAddrNet = sAddr.split("-") objAddr.address_value = sAddrNet[0].strip( ) + "##comma##" + sAddrNet[1].strip() objAddr.address_value.condition = 'InclusiveBetween' objAddr.category = 'ipv4-net' obsAddr = Observable(objAddr) objAddr = None obsAddr.sighting_count = 1 oObsSrcData.sighting_count = 1 obsAddr.observable_source.append(oObsSrcData) sTitle = 'NETWORK_range: ' + sAddr obsAddr.title = sTitle sDscpt = 'ipv4-net' + ': ' + sAddr + " | " if data[sKey]['attrib']['netname']: sDscpt += 'netName' + ': ' + data[sKey]['attrib'][ 'netname'] + " | " obsAddr.description = "<![CDATA[" + sDscpt + "]]>" listOBS.append(obsAddr) obsAddr = None ### Parsing Email Address sEMAIL = data[sKey]['attrib']['email'] if sEMAIL: objEmail = EmailAddress() #objEmail.is_source = True objEmail.address_value = sEMAIL objEmail.address_value.condition = 'Equals' objEmail.category = 'e-mail' obsEmail = Observable(objEmail) objEmail = None obsEmail.sighting_count = 1 oObsSrcData.sighting_count = 1 if len(data[sKey]['attrib']['source']) > 0: oObsSrcData.name = data[sKey]['attrib']['source'] obsEmail.observable_source.append(oObsSrcData) sTitle = 'REGISTRAR_email: ' + sEMAIL obsEmail.title = sTitle sDscrpt = 'REGISTRAR_email: ' + sEMAIL if data[sKey]['attrib']['descr']: sDscrpt += " | REGISTRAR_name: " + data[sKey]['attrib'][ 'descr'] + " | " obsEmail.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsEmail) obsEmail = None ### Parsing Domain sDomain = data[sKey]['attrib']['domain'] if len(sDomain) > 0: objDomain = DomainName() objDomain.value = sDomain objDomain.value.condition = 'Equals' objDomain.is_destination = True if isFQDN(sDomain): objDomain.type = 'FQDN' elif isTLD(sDomain): objDomain.type = 'TLD' else: continue obsDomain = Observable(objDomain) objDomain = None obsDomain.sighting_count = 1 oObsSrcData.sighting_count = 1 obsDomain.observable_source.append(oObsSrcData) obsDomain.title = 'Domain: ' + sDomain sDscpt = 'Domain: ' + sDomain + " | " sDscpt += "isDestination: True | " if data[sKey]['attrib']['first']: sDscpt += "firstSeen: " + data[sKey]['attrib']['first'] + " | " if data[sKey]['attrib']['last']: sDscpt += "lastSeen: " + data[sKey]['attrib']['last'] + " | " #if obsDomain.description = "<![CDATA[" + sDscpt + "]]>" listOBS.append(obsDomain) obsDomain = None objIndicator.add_indicator_type("Domain Watchlist") #Parser URI sURI = data[sKey]['attrib']['url'] if len(sURI) > 0: objURI = URI() objURI.value = sURI objURI.value.condition = 'Equals' objURI.type_ = URI.TYPE_URL obsURI = Observable(objURI) objURI = None obsURI.sighting_count = 1 oObsSrcData.sighting_count = 1 obsURI.observable_source.append(oObsSrcData) obsURI.title = 'URI: ' + sURI sDscpt = 'URI: ' + sURI + " | " sDscpt += "Type: URL | " obsURI.description = "<![CDATA[" + sDscpt + "]]>" listOBS.append(obsURI) obsURI = None objIndicator.add_indicator_type("URL Watchlist") sDscrpt = None sCntry_code = None sCntry_name = None sRgstra_email = None sRgstra_name = None # add Phishing Email Target # add Phishing email Details phishtank_ID if data[sKey]['attrib']['country']: sCntry_code = data[sKey]['attrib']['country'] if sCntry_code in dictCC2CN: sCntry_name = dictCC2CN[sCntry_code] if data[sKey]['attrib']['email'] > 0: sRgstra_email = data[sKey]['attrib']['email'] if data[sKey]['attrib']['descr']: sRgstra_name = data[sKey]['attrib']['descr'] sDscrpt = " clean-mx.de has identified this " if isIPv4(data[sKey]['attrib']['domain']): sDscrpt += "ip address " + data[sKey]['attrib']['domain'] + " " else: sDscrpt += "domain " + data[sKey]['attrib']['domain'] + " " sDscrpt += "as malicious " if data[sKey]['attrib']['target']: sDscrpt += "and uses phishing email(s) targeting " + data[sKey][ 'attrib']['target'] + " users with " else: sDscrpt += "and sent out " sDscrpt += "email containg this url <-Do Not Connect-> {" + data[sKey][ 'attrib']['url'] + "} <-Do Not Connect-> link. " if data[sKey]['attrib']['phishtank']: sDscrpt += "For more detail on the specific phisihing email use this phishtank ID [" + data[ sKey]['attrib']['phishtank'] + "]. " if sCntry_code: sDscrpt += " This url appears to originated in " + sCntry_code if sCntry_name: sDscrpt += " (" + sCntry_name + ")" if sCntry_code and (sRgstra_email or sRgstra_name): sDscrpt += " and is " if sRgstra_email: sDscrpt += "register to " + sRgstra_email if sRgstra_email and sRgstra_name: sDscrpt += " of " + sRgstra_name elif sRgstra_name: sDscrpt += "register to " + sRgstra_name sDscrpt += "." if sCntry_code or sRgstra_email or sRgstra_name: objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" sTitle = 'Phishing ID:' + sKey + " " if data[sKey]['attrib']["target"]: sTitle += "Target: " + data[sKey]['attrib']["target"] + " " if data[sKey]['attrib']["url"]: sTitle += "URL: " + data[sKey]['attrib']["url"] + " " objIndicator.title = sTitle ### Add Generated observable to Indicator objIndicator.add_indicator_type("IP Watchlist") objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS #Parsing Producer sProducer = srcObj.Domain if len(sProducer) > 0: objIndicator.set_producer_identity(sProducer) objIndicator.set_produced_time(data[sKey]['attrib']['first']) objIndicator.set_received_time(data[sKey]['dateDL']) 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) objTOU = TermsOfUseMarkingStructure() #sTOU = open('tou.txt').read() objTOU.terms_of_use = sProducer + " | " + srcObj.srcTOU marking_specification.marking_structures.append(objTOU) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" 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)
def main(): ###################################################################### # MODIFICARE LE VARIABILI SEGUENTI # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28) MyTITLE = "GandCrab" # La description strutturiamola come segue # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)> DESCRIPTION = "CERT-PA - Nuova campagna di Cyber-Estorsione basata su ransomware GandCrab - https://www.cert-pa.it/notizie/nuova-campagna-di-cyber-estorsione-basata-su-ransomware-gandcrab/" # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community IDENTITY = "CERT-PA via Cyber Saiyan Community" # ###################################################################### # Build STIX file info_src = InformationSource() info_src.identity = Identity(name=IDENTITY) NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN") set_id_namespace(NAMESPACE) timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') SHORT = timestamp wrapper = STIXPackage() marking_specification = MarkingSpecification() marking_specification.controlled_structure = "//node() | //@*" tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE.encode(encoding='UTF-8', errors='replace'), description=DESCRIPTION.encode(encoding='UTF-8', errors='replace'), short_description=SHORT.encode(encoding='UTF-8', errors='replace')) wrapper.stix_header.handling = handling # HASH indicators indicatorHASH = Indicator() indicatorHASH.title = MyTITLE + " - HASH" indicatorHASH.add_indicator_type("File Hash Watchlist") # DOMAIN indicators indiDOMAIN = Indicator() indiDOMAIN.title = MyTITLE + " - DOMAIN" indiDOMAIN.add_indicator_type("Domain Watchlist") # URL indicators indiURL = Indicator() indiURL.title = MyTITLE + " - URL" indiURL.add_indicator_type("URL Watchlist") # IP indicators indiIP = Indicator() indiIP.title = MyTITLE + " - IP" indiIP.add_indicator_type("IP Watchlist") # EMAIL indicators indiEMAIL = Indicator() indiEMAIL.title = MyTITLE + " - EMAIL" indiEMAIL.add_indicator_type("Malicious E-mail") # Read IoC file file_ioc = "CS-ioc.txt" ioc = loaddata(file_ioc) print "Reading IoC file..." for idx, ioc in enumerate(ioc): notfound = 1 # sha256 p = re.compile(r"^[0-9a-f]{64}$", re.IGNORECASE) m = p.match(ioc) if m and notfound: filei = File() filei.add_hash(Hash(ioc)) obsi = Observable(filei) indicatorHASH.add_observable(obsi) print "SHA256: " + ioc notfound = 0 #md5 p = re.compile(r"^[0-9a-f]{32}$", re.IGNORECASE) m = p.match(ioc) if m and notfound: filej = File() filej.add_hash(Hash(ioc)) obsj = Observable(filej) indicatorHASH.add_observable(obsj) print "MD5: " + ioc notfound = 0 #sha1 p = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE) m = p.match(ioc) if m and notfound: filek = File() filek.add_hash(Hash(ioc)) obsk = Observable(filek) indicatorHASH.add_observable(obsk) print "SHA1: " + ioc notfound = 0 #domains if validators.domain(ioc) and notfound: url = URI() url.value = ioc url.type_ = URI.TYPE_DOMAIN url.condition = "Equals" obsu = Observable(url) indiDOMAIN.add_observable(obsu) print "DOMAIN: " + ioc notfound = 0 #url if validators.url(ioc) and notfound: url = URI() url.value = ioc url.type_ = URI.TYPE_URL url.condition = "Equals" obsu = Observable(url) indiURL.add_observable(obsu) print "URL: " + ioc notfound = 0 #ip if validators.ipv4(ioc) and notfound: ip = Address() ip.address_value = ioc obsu = Observable(ip) indiIP.add_observable(obsu) print "IP: " + ioc notfound = 0 # add all indicators to STIX wrapper.add_indicator(indicatorHASH) wrapper.add_indicator(indiDOMAIN) wrapper.add_indicator(indiURL) wrapper.add_indicator(indiIP) wrapper.add_indicator(indiEMAIL) # print STIX file to stdout print "Writing STIX package: package.stix" f = open ("package.stix", "w") f.write (wrapper.to_xml()) f.close () print
def add_ais_marking(stix_package, proprietary, consent, color, **kwargs): """ This utility functions aids in the creation of an AIS marking and appends it to the provided STIX package. Args: stix_package: A stix.core.STIXPackage object. proprietary: True if marking uses IsProprietary, False for NotProprietary. consent: A string with one of the following values: "EVERYONE", "NONE" or "USG". color: A string that corresponds to TLP values: "WHITE", "GREEN" or "AMBER". **kwargs: Six required keyword arguments that are used to create a CIQ identity object. These are: country_name_code, country_name_code_type, admin_area_name_code, admin_area_name_code_type, organisation_name, industry_type. Raises: ValueError: When keyword arguments are missing. User did not supply correct values for: proprietary, color and consent. Note: The following line is required to register the AIS extension:: >>> import stix.extensions.marking.ais Any Markings under STIX Header will be removed. Please follow the guidelines for `AIS`_. The industry_type keyword argument accepts: a list of string based on defined sectors, a pipe-delimited string of sectors, or a single sector. .. _AIS: https://www.us-cert.gov/ais """ from stix.common import InformationSource from stix.extensions.identity.ciq_identity_3_0 import ( CIQIdentity3_0Instance, STIXCIQIdentity3_0, PartyName, Address, Country, NameElement, OrganisationInfo, AdministrativeArea) from stix.core.stix_header import STIXHeader from stix.data_marking import MarkingSpecification, Marking args = ('country_name_code', 'country_name_code_type', 'industry_type', 'admin_area_name_code', 'admin_area_name_code_type', 'organisation_name') diff = set(args) - set(kwargs.keys()) if diff: msg = 'All keyword arguments must be provided. Missing: {0}' raise ValueError(msg.format(tuple(diff))) party_name = PartyName() party_name.add_organisation_name(kwargs['organisation_name']) country = Country() country_name = NameElement() country_name.name_code = kwargs['country_name_code'] country_name.name_code_type = kwargs['country_name_code_type'] country.add_name_element(country_name) admin_area = AdministrativeArea() admin_area_name = NameElement() admin_area_name.name_code = kwargs['admin_area_name_code'] admin_area_name.name_code_type = kwargs['admin_area_name_code_type'] admin_area.add_name_element(admin_area_name) address = Address() address.country = country address.administrative_area = admin_area org_info = OrganisationInfo() org_info.industry_type = _validate_and_create_industry_type( kwargs['industry_type']) id_spec = STIXCIQIdentity3_0() id_spec.party_name = party_name id_spec.add_address(address) id_spec.organisation_info = org_info identity = CIQIdentity3_0Instance() identity.specification = id_spec if proprietary is True: proprietary_obj = IsProprietary() consent = 'EVERYONE' elif proprietary is False: proprietary_obj = NotProprietary() else: raise ValueError('proprietary expected True or False.') proprietary_obj.ais_consent = AISConsentType(consent=consent) proprietary_obj.tlp_marking = TLPMarkingType(color=color) ais_marking = AISMarkingStructure() if isinstance(proprietary_obj, IsProprietary): ais_marking.is_proprietary = proprietary_obj else: ais_marking.not_proprietary = proprietary_obj marking_spec = MarkingSpecification() marking_spec.controlled_structure = '//node() | //@*' marking_spec.marking_structures.append(ais_marking) marking_spec.information_source = InformationSource() marking_spec.information_source.identity = identity if not stix_package.stix_header: stix_package.stix_header = STIXHeader() # Removes any other Markings if present. stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking_spec)
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 Domain sDomain = data[sKey]['attrib']['domain'] if len(sDomain) > 0: objDomain = DomainName() objDomain.value = sDomain objDomain.value.condition = 'Equals' if isFQDN(sDomain): objDomain.type = 'FQDN' elif isTLD(sDomain): objDomain.type = 'TLD' else: continue obsDomain = Observable(objDomain) objDomain = None obsDomain.sighting_count = 1 obsDomain.title = 'Domain: ' + sDomain sDscrpt = 'Domain: ' + sDomain + " | " sDscrpt += "isFQDN: True | " obsDomain.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsDomain) obsDomain = None objIndicator.add_indicator_type("Domain Watchlist") ### Add Generated observable to Indicator objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS #Parsing Producer infoSrc = InformationSource(identity=Identity(name=srcObj.Domain)) infoSrc.add_contributing_source(data[sKey]['attrib']['ref']) if len(srcObj.Domain) > 0: objIndicator.producer = infoSrc if data[sKey]['attrib']['lstDateVF']: objIndicator.set_produced_time( data[sKey]['attrib']['lstDateVF'][0]) objIndicator.set_received_time(data[sKey]['dateDL']) ### Generate Indicator Title based on availbe data lstContainng = [] lstIs = [] sTitle = 'This domain ' + data[sKey]['attrib'][ 'domain'] + ' has been identified as malicious' if len(data[sKey]['attrib']['ref']): sTitle += ' by ' + data[sKey]['attrib']['ref'] if len(data[sKey]['attrib']['type']) > 0: sTitle += ', via this vector [' + data[sKey]['attrib'][ 'type'] + '].' else: sTitle += '.' objIndicator.title = sTitle ### Generate Indicator Description based on availbe data sDscrpt = 'Lehigh.edu site has added this domain ' + data[sKey][ 'attrib']['domain'] sDscrpt += ' to recommend block list.' sDscrpt += ' This site has been identified as malicious' sDscrpt += ' by ' + data[sKey]['attrib']['ref'] sDscrpt += ' and was still attive on the following dates ' + str( data[sKey]['attrib']['lstDateVF']) + "." objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" #Parse TTP objMalware = MalwareInstance() objMalware.add_type("Remote Access Trojan") ttpTitle = data[sKey]['attrib']['type'] 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 = srcObj.Domain + " | " + 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)
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 sAddr = data[sKey]['attrib']['ipAddr'] if len(sAddr) > 0: objAddr = Address() objAddr.is_destination = True objAddr.address_value = sAddr objAddr.address_value.condition = 'Equals' if isIPv4(sAddr): objAddr.category = objAddr.CAT_IPV4 elif isIPv6(sAddr): objAddr.category = objAddr.CAT_IPV6 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 objIndicator.add_indicator_type("IP Watchlist") ### Parsing Domain sDomain = data[sKey]['attrib']['domain'] if len(sDomain) > 0: objDomain = DomainName() objDomain.value = sDomain objDomain.value.condition = 'Equals' if isFQDN(sDomain): objDomain.type = 'FQDN' elif isTLD(sDomain): objDomain.type = 'TLD' else: continue obsDomain = Observable(objDomain) objDomain = None obsDomain.sighting_count = 1 obsDomain.title = 'Domain: ' + sDomain sDscrpt = 'Domain: ' + sDomain + " | " sDscrpt += "isFQDN: True | " obsDomain.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsDomain) obsDomain = None objIndicator.add_indicator_type("Domain Watchlist") #Parser URI sURI = data[sKey]['attrib']['title'] if len(sURI) > 0: objURI = URI() objURI.value = sURI objURI.value.condition = 'Equals' objURI.type_ = URI.TYPE_URL obsURI = Observable(objURI) objURI = None obsURI.sighting_count = 1 obsURI.title = 'URI: ' + sURI sDscrpt = 'URI: ' + sURI + " | " sDscrpt += "Type: URL | " obsURI.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsURI) obsURI = None objIndicator.add_indicator_type("URL Watchlist") ### Add Generated observable to Indicator objIndicator.observables = listOBS objIndicator.observable_composition_operator = 'OR' #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']) ### Generate Indicator Title based on availbe data sTitle = 'C2C Site: ' + sURI objIndicator.title = sTitle #Generate Indicator Description based on availbe data sDscrpt = "" if len(sAddr) > 0: sAddLine = "This IP address " + sAddr if len(sDomain) > 0: sAddLine = "This domain " + sDomain if len(sAddr) > 0 and len(sDomain) > 0: sAddLine = "This domain " + sDomain + " (" + sAddr + ")" if len(sAddLine) > 0: sDscrpt += sAddLine sDscrpt = sDscrpt + " has been identified as a command and control site for " + data[ sKey]['attrib']['dscrpt'] + ' malware' if len(srcObj.Domain) > 0: sDscrpt = sDscrpt + " by " + srcObj.Domain else: sDscrpt = sDscrpt + "." sDscrpt = sDscrpt + ". For more detailed infomation about this indicator go to [CAUTION!!Read-URL-Before-Click] [" + data[ sKey]['attrib']['link'] + "]." if len(sDscrpt) > 0: objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" pass #Parse TTP sType = data[sKey]['attrib']['dscrpt'] if len(sType) > 0: objMalware = MalwareInstance() objMalware.add_name(sType) objMalware.add_type("Remote Access Trojan") objMalware.short_description = "" objMalware.description = "" objTTP = TTP(title=sType) objTTP.behavior = Behavior() objTTP.behavior.add_malware_instance(objMalware) objIndicator.add_indicated_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)
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 = [] oObsSrcData = genObsSrcData(srcObj, data[sKey]) ### Parsing IP Address sAddr = sKey if len(sAddr) > 0: objAddr = Address() objAddr.is_source = True objAddr.address_value = sAddr objAddr.address_value.condition = 'InclusiveBetween' objAddr.category = 'ipv4-net' obsAddr = Observable(objAddr) objAddr = None obsAddr.sighting_count = int(data[sKey]['attrib']['Attacks']) oObsSrcData.sighting_count = int(data[sKey]['attrib']['Attacks']) obsAddr.observable_source.append(oObsSrcData) sTitle = 'NETWORK_range: ' + sAddr obsAddr.title = sTitle sDscpt = 'ipv4-net' + ': ' + sAddr + " | " sDscpt += "is_source: True | " sDscpt += "Attack_Count: " + data[sKey]['attrib']['Attacks'] + " | " sDscpt += "Attack_DateRange: " + data[sKey]['attrib'][ 'dateRange'] + " | " obsAddr.description = sDscpt listOBS.append(obsAddr) obsAddr = None ### Parsing Registrar Information if data[sKey]['attrib']['email']: objEmail = EmailAddress() objEmail.address_value = data[sKey]['attrib']['email'] objEmail.address_value.condition = 'Equals' objEmail.category = 'e-mail' objWhoisReg = WhoisRegistrar() if len(data[sKey]['attrib']['Name']) > 1: objWhoisReg.name = data[sKey]['attrib']['Name'] objWhoisReg.email_address = objEmail objEmail = None objWhois = WhoisEntry() objWhois.registrar_info = objWhoisReg obsWhois = Observable(objWhois) #print obsWhois.id_ objWhois = None obsWhois.sighting_count = 1 sTitle = 'REGISTRAR_email: ' + data[sKey]['attrib']['email'] if len(data[sKey]['attrib']['Name']) > 0: sTitle += " | REGISTRAR_name: " + data[sKey]['attrib'][ 'Name'] + " | " obsWhois.title = sTitle obsWhois.description = sTitle listOBS.append(obsWhois) obsWhois = None sDscrpt = None sCntry_code = None sCntry_name = None sRgstra_email = None sRgstra_name = None if len(data[sKey]['attrib']['Country']) > 0: sCntry_code = data[sKey]['attrib']['Country'] if sCntry_code in dictCC2CN: sCntry_name = dictCC2CN[sCntry_code] if 'email' in data[sKey]['attrib']: sRgstra_email = data[sKey]['attrib']['email'] if len(data[sKey]['attrib']['Name']) > 0: sRgstra_name = data[sKey]['attrib']['Name'] sDscrpt = "This IP block appears to have " if sCntry_code: sDscrpt += "originated in " + sCntry_code if sCntry_name: sDscrpt += "(" + sCntry_name + ")" if sCntry_code and (sRgstra_email or sRgstra_name): sDscrpt += " and is " if sRgstra_email: sDscrpt += "register to " + sRgstra_email if sRgstra_email and sRgstra_name: sDscrpt += " of " + sRgstra_name elif sRgstra_name: sDscrpt += "register to " + sRgstra_name sDscrpt += "." if sCntry_code or sRgstra_email or sRgstra_name: objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" objIndicator.title = sAddr.replace('##comma##', ' - ') + " | " + srcObj.pkgTitle ### Add Generated observable to Indicator objIndicator.add_indicator_type("IP Watchlist") objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS #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']) 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) objTOU = TermsOfUseMarkingStructure() #sTOU = open('tou.txt').read() objTOU.terms_of_use = sProducer + " | " + srcObj.srcTOU marking_specification.marking_structures.append(objTOU) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" 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)