def stix_xml(bldata): # Create the STIX Package and Header objects stix_package = STIXPackage() stix_header = STIXHeader() # Set the description stix_header.description = "RiskIQ Blacklist Data - STIX Format" # Set the namespace NAMESPACE = {"http://www.riskiq.com" : "RiskIQ"} set_id_namespace(NAMESPACE) # Set the produced time to now stix_header.information_source = InformationSource() stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() # Create the STIX Package stix_package = STIXPackage() # Build document stix_package.stix_header = stix_header # Build the Package Intent stix_header.package_intents.append(PackageIntent.TERM_INDICATORS) # Build the indicator indicator = Indicator() indicator.title = "List of Malicious URLs detected by RiskIQ - Malware, Phishing, and Spam" indicator.add_indicator_type("URL Watchlist") for datum in bldata: url = URI() url.value = "" url.value = datum['url'] url.type_ = URI.TYPE_URL url.condition = "Equals" indicator.add_observable(url) stix_package.add_indicator(indicator) return stix_package.to_xml()
def stix_xml(bldata): # Create the STIX Package and Header objects stix_package = STIXPackage() stix_header = STIXHeader() # Set the description stix_header.description = "RiskIQ Blacklist Data - STIX Format" # Set the namespace NAMESPACE = {"http://www.riskiq.com": "RiskIQ"} set_id_namespace(NAMESPACE) # Set the produced time to now stix_header.information_source = InformationSource() stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() # Create the STIX Package stix_package = STIXPackage() # Build document stix_package.stix_header = stix_header # Build the Package Intent stix_header.package_intents.append(PackageIntent.TERM_INDICATORS) # Build the indicator indicator = Indicator() indicator.title = "List of Malicious URLs detected by RiskIQ - Malware, Phishing, and Spam" indicator.add_indicator_type("URL Watchlist") for datum in bldata: url = URI() url.value = "" url.value = datum['url'] url.type_ = URI.TYPE_URL url.condition = "Equals" indicator.add_observable(url) stix_package.add_indicator(indicator) return stix_package.to_xml()
def main(): # Create a new STIXPackage stix_package = STIXPackage() # Create a new STIXHeader stix_header = STIXHeader() # Add Information Source. This is where we will add the tool information. stix_header.information_source = InformationSource() # Create a ToolInformation object. Use the initialization parameters # to set the tool and vendor names. # # Note: This is an instance of cybox.common.ToolInformation and NOT # stix.common.ToolInformation. tool = ToolInformation(tool_name="python-stix", tool_vendor="The MITRE Corporation") # Set the Information Source "tools" section to a # cybox.common.ToolInformationList which contains our tool that we # created above. stix_header.information_source.tools = ToolInformationList(tool) # Set the header description stix_header.description = "Example" # Set the STIXPackage header stix_package.stix_header = stix_header # Print the XML! print(stix_package.to_xml()) # Print the dictionary! pprint(stix_package.to_dict())
def init_stix(self): stix_package = STIXPackage() stix_header = STIXHeader() info_source = InformationSource() info_source.description = 'HAR file analysis of visit to malicious URL' stix_header.information_source = info_source stix_package.stix_header = stix_header return stix_package
def _add_header(self, stix_package, title, desc): stix_header = STIXHeader() stix_header.title = title stix_header.description = desc stix_header.information_source = InformationSource() stix_header.information_source.time = CyboxTime() stix_header.information_source.time.produced_time = datetime.now().isoformat() stix_package.stix_header = stix_header
def init_stix(self): stix_package = STIXPackage() stix_header = STIXHeader() info_source = InformationSource() info_source.description = 'HAR file analysis of visit to malicious URL' stix_header.information_source = info_source stix_package.stix_header = stix_header return stix_package
def _add_header(self, stix_package, title, desc): stix_header = STIXHeader() stix_header.title = title stix_header.description = desc stix_header.information_source = InformationSource() stix_header.information_source.time = CyboxTime() stix_header.information_source.time.produced_time = datetime.now() stix_package.stix_header = stix_header
def main(): stix_package = STIXPackage() stix_header = STIXHeader() # Add tool information stix_header.information_source = InformationSource() stix_header.information_source.tools = ToolInformationList() stix_header.information_source.tools.append(ToolInformation("python-stix ex_04.py", "The MITRE Corporation")) stix_header.description = "Example " stix_package.stix_header = stix_header print(stix_package.to_xml()) print(stix_package.to_dict())
def main(): stix_package = STIXPackage() stix_header = STIXHeader() # Add tool information stix_header.information_source = InformationSource() stix_header.information_source.tools = ToolInformationList() stix_header.information_source.tools.append( ToolInformation("python-stix ex_04.py", "The MITRE Corporation")) stix_header.description = "Example 04" stix_package.stix_header = stix_header print(stix_package.to_xml()) print(stix_package.to_dict())
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 set_stix_header(self, threat_name, threat_descr, threat_source=None, reference=None): # Create a STIX Package hdr = STIXHeader() hdr.title = threat_name hdr.add_description(threat_descr) hdr.information_source = InformationSource() if threat_source is not None: hdr.information_source.description = threat_source if reference is not None: hdr.information_source.references = fields.TypedField(reference, References) # Set the produced time to now hdr.information_source.time = Time() hdr.information_source.time.produced_time = datetime.utcnow() self._pkg.stix_header = hdr
def wrap_maec(maec_package, file_name=None): """Wrap a MAEC Package in a STIX TTP/Package. Return the newly created STIX Package. Args: maec_package: the ``maec.package.package.Package`` instance to wrap in STIX. file_name: the name of the input file from which the MAEC Package originated, to be used in the Title of the STIX TTP that wraps the MAEC Package. Optional. Returns: A ``stix.STIXPackage`` instance with a single TTP that wraps the input MAEC Package. """ # Set the namespace to be used in the STIX Package stix.utils.set_id_namespace( {"https://github.com/MAECProject/maec-to-stix": "MAECtoSTIX"}) # Create the STIX MAEC Instance maec_malware_instance = MAECInstance() maec_malware_instance.maec = maec_package # Create the STIX TTP that includes the MAEC Instance ttp = TTP() ttp.behavior = Behavior() ttp.behavior.add_malware_instance(maec_malware_instance) # Create the STIX Package and add the TTP to it stix_package = STIXPackage() stix_package.add_ttp(ttp) # Create the STIX Header and add it to the Package stix_header = STIXHeader() if file_name: stix_header.title = "STIX TTP wrapper around MAEC file: " + str( file_name) stix_header.add_package_intent("Malware Characterization") # Add the Information Source to the STIX Header tool_info = ToolInformation() stix_header.information_source = InformationSource() tool_info.name = "MAEC to STIX" tool_info.version = str(maec_to_stix.__version__) stix_header.information_source.tools = ToolInformationList(tool_info) stix_package.stix_header = stix_header return stix_package
def wrap_maec(maec_package, file_name=None): """Wrap a MAEC Package in a STIX TTP/Package. Return the newly created STIX Package. Args: maec_package: the ``maec.package.package.Package`` instance to wrap in STIX. file_name: the name of the input file from which the MAEC Package originated, to be used in the Title of the STIX TTP that wraps the MAEC Package. Optional. Returns: A ``stix.STIXPackage`` instance with a single TTP that wraps the input MAEC Package. """ # Set the namespace to be used in the STIX Package stix.utils.set_id_namespace({"https://github.com/MAECProject/maec-to-stix":"MAECtoSTIX"}) # Create the STIX MAEC Instance maec_malware_instance = MAECInstance() maec_malware_instance.maec = maec_package # Create the STIX TTP that includes the MAEC Instance ttp = TTP() ttp.behavior = Behavior() ttp.behavior.add_malware_instance(maec_malware_instance) # Create the STIX Package and add the TTP to it stix_package = STIXPackage() stix_package.add_ttp(ttp) # Create the STIX Header and add it to the Package stix_header = STIXHeader() if file_name: stix_header.title = "STIX TTP wrapper around MAEC file: " + str(file_name) stix_header.add_package_intent("Malware Characterization") # Add the Information Source to the STIX Header tool_info = ToolInformation() stix_header.information_source = InformationSource() tool_info.name = "MAEC to STIX" tool_info.version = str(maec_to_stix.__version__) stix_header.information_source.tools = ToolInformationList(tool_info) stix_package.stix_header = stix_header return stix_package
def build_stix( ): # setup stix document stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Sample breach report" stix_header.add_package_intent ("Incident") # stamp with creator stix_header.information_source = InformationSource() stix_header.information_source.description = "The person who reported it" stix_header.information_source.identity = Identity() stix_header.information_source.identity.name = "Infosec Operations Team" stix_package.stix_header = stix_header # add incident and confidence breach = Incident() breach.description = "Intrusion into enterprise network" breach.confidence = "High" # set incident-specific timestamps breach.time = incidentTime() breach.title = "Breach of Cyber Tech Dynamics" breach.time.initial_compromise = datetime.strptime("2012-01-30", "%Y-%m-%d") breach.time.incident_discovery = datetime.strptime("2012-05-10", "%Y-%m-%d") breach.time.restoration_achieved = datetime.strptime("2012-08-10", "%Y-%m-%d") breach.time.incident_reported = datetime.strptime("2012-12-10", "%Y-%m-%d") # add the impact impact = ImpactAssessment() impact.add_effect("Unintended Access") breach.impact_assessment = impact # add the victim breach.add_victim ("Cyber Tech Dynamics") stix_package.add_incident(breach) return stix_package
def _create_stix_package(self): """Create and return a STIX Package with the basic information populated. Returns: A ``stix.STIXPackage`` object with a STIX Header that describes the intent of the package in terms of capturing malware artifacts, along with some associated metadata. """ stix_package = STIXPackage() stix_header = STIXHeader() stix_header.add_package_intent("Indicators - Malware Artifacts") if self.file_name: stix_header.title = "STIX Indicators extracted from MAEC file: " + str(self.file_name) # Add the Information Source to the STIX Header tool_info = ToolInformation() stix_header.information_source = InformationSource() tool_info.name = "MAEC to STIX" tool_info.version = str(__version__) stix_header.information_source.tools = ToolInformationList(tool_info) stix_package.stix_header = stix_header return stix_package
def _create_stix_package(self): """Create and return a STIX Package with the basic information populated. Returns: A ``stix.STIXPackage`` object with a STIX Header that describes the intent of the package in terms of capturing malware artifacts, along with some associated metadata. """ stix_package = STIXPackage() stix_header = STIXHeader() stix_header.add_package_intent("Indicators - Malware Artifacts") if self.file_name: stix_header.title = "STIX Indicators extracted from MAEC file: " + str( self.file_name) # Add the Information Source to the STIX Header tool_info = ToolInformation() stix_header.information_source = InformationSource() tool_info.name = "MAEC to STIX" tool_info.version = str(__version__) stix_header.information_source.tools = ToolInformationList(tool_info) stix_package.stix_header = stix_header 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(): # Create a new STIXPackage stix_package = STIXPackage() # Create a new STIXHeader stix_header = STIXHeader() # Add Information Source. This is where we will add the tool information. stix_header.information_source = InformationSource() # Create a ToolInformation object. Use the initialization parameters # to set the tool and vendor names. # # Note: This is an instance of cybox.common.ToolInformation and NOT # stix.common.ToolInformation. tool = ToolInformation( tool_name="python-stix", tool_vendor="The MITRE Corporation" ) # Set the Information Source "tools" section to a # cybox.common.ToolInformationList which contains our tool that we # created above. stix_header.information_source.tools = ToolInformationList(tool) # Set the header description stix_header.description = "Example" # Set the STIXPackage header stix_package.stix_header = stix_header # Print the XML! print(stix_package.to_xml()) # Print the dictionary! pprint(stix_package.to_dict())
def doCuckoo(results): malfilename = "" # memstrings = [] print "json dumps %s" % (json.dumps(results['target'])) try: fileitems = results['target']['file'] malfilename = fileitems['name'] malfilesize = fileitems['size'] malmd5 = fileitems['md5'] malsha1 = fileitems['sha1'] malsha256 = fileitems['sha256'] malsha512 = fileitems['sha512'] malssdeep = fileitems['ssdeep'] malfiletype = fileitems["type"] # MD54K - From Chris Hudel malmd54k = doMD54K(fileitems['path']) # memfile = fileitems['path'][0:len(fileitems['path']) - 64] + "../analyses/" + str(results['info']['id']) + "/memory.dmp" # memstrings = doStrings(stringscmd(memfile)) except: fileitems = [] pass staticitems = results['static'] # info = results['info'] # Suspicious PE imports iocimports = [] try: for imports in staticitems['pe_imports']: for item in imports['imports']: if item['name'] in suspiciousimports: iocimports.append(item['name']) except: pass #rsrcentries = [] # PE sectionis badpesections = [] try: for sections in staticitems['pe_sections']: if sections['name'] not in goodpesections: badpesection = [ sections['name'], sections['size_of_data'], str(sections['entropy']) ] badpesections.append(badpesection) except: pass # PE Exports iocexports = [] try: for exportfunc in staticitems['pe_exports']: iocexports.append(exportfunc['name']) except: pass # PE Version Info versioninfo = dict.fromkeys(['LegalCopyright', 'InternalName', 'FileVersion', 'CompanyName', 'PrivateBuild', \ 'LegalTrademarks', 'Comments', 'ProductName', 'SpecialBuild', 'ProductVersion', \ 'FileDescription', 'OriginalFilename']) if 'pe_versioninfo' in staticitems: for item in staticitems['pe_versioninfo']: if item['name'] in versioninfo: versioninfo[item['name']] = item['value'] # Dropped files droppedfiles = [] try: for droppedfile in results['dropped']: droppedfiles.append([droppedfile['name'], droppedfile['size'], droppedfile['md5'], droppedfile['sha1'], \ droppedfile['sha256'], droppedfile['sha512']]) except: pass # Hosts contacted. This will exclude # localhost, broadcast and any other 'noise' # as indicated by excludedips hosts = [] try: for host in results['network']['hosts']: if host not in excludedips: hosts.append(host) except: pass # Mutexes mutexes = [] try: for mutex in results['behavior']['summary']['mutexes']: mutexes.append(mutex) except: pass # Processes processes = [] try: for process in results['behavior']['processes']: processes.append([ process['process_name'], process['process_id'], process['parent_id'] ]) except: pass # grab the string results # currently these are simple # regexes for IPv4 addresses and # emails strings = doStrings(results['strings']) # Registry Keys # This uses modified cuckoo source code to only # pull the Registry keys created, instead # of those created OR just opened regkeys = results['behavior']['summary']['keys'] # Create our metadata dictionary for getting the # metadata values int the IOC metadata = {'malfilename':malfilename, 'malmd5':malmd5, 'malsha1':malsha1, 'malsha256':malsha256, 'malsha512':malsha512, \ 'malmd54k':malmd54k, 'malfilesize':malfilesize, 'malssdeep':malssdeep, 'malfiletype':malfiletype, \ 'iocexports':iocexports, 'iocimports':iocimports, 'badpesections':badpesections, 'versioninfo':versioninfo} dynamicindicators = { "droppedfiles": droppedfiles, "processes": processes, "regkeys": regkeys, 'mutexes': mutexes, 'hosts': hosts } stix_package = STIXPackage() stix_header = STIXHeader() desc = "IOCAware Auto-Generated IOC Document" if len(malfilename) > 0: desc += " " + malfilename stix_header.description = desc stix_header.information_source = InformationSource() stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() stix_package.stix_header = stix_header #wfe = createMetaData(stix_package, metadata) #addStrings(stix_package, wfe, strings) createMetaData(stix_package, metadata, strings) createDynamicIndicators(stix_package, dynamicindicators) filename = IOCLOCATION + "/iocaware_stix_" + str(uuid.uuid4()) + ".xml" stixfile = open(filename, "w") stixfile.write(stix_package.to_xml())
def create_cybox_object(self, jdict, whitelist, config): listObservables = [] NS = cybox.utils.Namespace("cert.siemens.com", "siemens_cert") cybox.utils.set_id_namespace(NS) """ store information about malware binary that was analyzed """ if 'target' in jdict and 'category' in jdict['target'] and jdict['target']['category'] == 'file': log.debug("handling File information ...") main_file_object = self.__create_cybox_main_file(jdict['target']['file']) file_md5 = jdict['target']['file']['md5'] elif 'target' in jdict and 'category' in jdict['target'] and jdict['target']['category'] == 'url': log.warning("Not a file analysis report! URL reports not handled") return else: log.error("No target information in report ... skipping") return """ try to find email that dropped this attachment """ if config["attachemail"] or config["referenceemail"]: log.info("handling email attack vector information ...") email_object_properties, email_observables_list, email_stix_path_tuple_list = self.__check_malware_mailing_list(file_md5, log, config) if email_object_properties and len(email_object_properties)>0: for email_object in email_object_properties: main_file_object.add_related(email_object, "Contained_Within", inline=False) else: log.warning("failed linking mail object (no objects to link)") email_stix_path_tuple_list = [] else: email_object = None email_observables = [] email_stix_path_tuple_list = [] """ store extended information about malware file """ if 'static' in jdict: log.debug("handling extended File information ...") win_executable_extension = self.__create_cybox_win_executable(jdict['target']['file'], jdict['static']) if win_executable_extension: main_file_object.add_related(win_executable_extension, "Characterized_By", inline=False) win_executable_extension = [win_executable_extension] else: log.warning("No extended File information found") win_executable_extension = [] """ store domains connected to """ if 'network' in jdict and 'domains' in jdict['network']: log.debug("handling Domain information ...") domains, addresses = self.__create_cybox_domains(jdict['network']['domains'], whitelist) for dom in domains: main_file_object.add_related(dom, 'Connected_To', inline=False) else: domains = [] addresses = [] """ store http session information """ if 'network' in jdict and 'http' in jdict['network']: log.debug("handling HTTP information ...") http_requests = self.__create_cybox_https(jdict['network']['http'], whitelist) for session in http_requests: main_file_object.add_related(session, 'Connected_To', inline=False) else: http_requests = [] """ store dns queries information about the malware """ if 'network' in jdict and 'dns' in jdict['network']: log.debug("handling DNS information ...") queries = self.__create_cybox_dns_queries(jdict['network']['dns'], whitelist) for query in queries: main_file_object.add_related(query, 'Connected_To', inline=False) else: queries = [] """ store information about dropped files """ if 'dropped' in jdict: log.debug('handling dropped files ...') dropped = self.__create_cybox_dropped_files(jdict['dropped'], jdict['target']['file']['sha256']) for drop in dropped: main_file_object.add_related(drop, 'Dropped', inline=False) else: dropped = [] """ store virustotal information """ if 'virustotal' in jdict and 'positives' in jdict['virustotal']: log.debug('handling virustotal information ...') vtInformationTools = self.__create_stix_virustotal(jdict['virustotal'], log, config) vtFound = True else: vtInformationTools = [] vtFound = False """ create observables """ if config["attachemail"] and len(email_observables)>0: obs = Observables([main_file_object]+email_observables+win_executable_extension+domains+addresses+http_requests+dropped+queries) else: obs = Observables([main_file_object]+win_executable_extension+domains+addresses+http_requests+dropped+queries) """ generate stix id with siemens namespace """ if config: stix_id_generator = stix.utils.IDGenerator(namespace={config["xmlns"]: config["namespace"]}) else: stix_id_generator = stix.utils.IDGenerator(namespace={"cert.siemens.com": "siemens_cert"}) """ create stix package """ stix_id = stix_id_generator.create_id() stix_package = STIXPackage(observables=obs, id_=stix_id) stix_header = STIXHeader() stix_header.title = "Analysis report: %s" % (str(main_file_object.file_name).decode('utf8', errors='xmlcharrefreplace')) if 'info' in jdict and 'started' in jdict['info']: sandbox_report_date = dateparser.parse(jdict['info']['started']+' CET').isoformat() else: sandbox_report_date = datetime.datetime.now(pytz.timezone('Europe/Berlin')).isoformat() stix_header.description = 'Summarized analysis results for file "%s" with MD5 hash "%s" created on %s.' % (str(main_file_object.file_name).decode('utf8', errors='xmlcharrefreplace'), main_file_object.hashes.md5, sandbox_report_date) stix_header.add_package_intent("Malware Characterization") """ create markings """ spec = MarkingSpecification() spec.idref = stix_id spec.controlled_structure = "//node()" tlpmark = TLPMarkingStructure() if config: if not vtFound: tlpmark.color = config["color"] else: tlpmark.color = "GREEN" elif vtFound: tlpmark.color = "GREEN" else: tlpmark.color = "AMBER" spec.marking_structure = [tlpmark] """ attach to header """ stix_header.handling = Marking([spec]) stix_information_source = InformationSource() stix_information_source.time = Time(produced_time=sandbox_report_date) stix_information_source.tools = ToolInformationList([ToolInformation(tool_name="SIEMENS-ANALYSIS-TOOL-ID-12", tool_vendor="ANALYSIS-ID: %s" % (jdict['info']['id']))]+vtInformationTools) stix_header.information_source = stix_information_source stix_package.stix_header = stix_header """ write result xml file """ xml_file_name = "stix-%s-malware-report.xml" % (file_md5) xml_report_file_path = os.path.join(self.reports_path, xml_file_name) fp = open(xml_report_file_path, 'w') if config: fp.write(stix_package.to_xml(ns_dict={config["xmlns"]: config["namespace"]})) else: fp.write(stix_package.to_xml(ns_dict={'cert.siemens.com': 'siemens_cert'})) fp.close() if config["copytoshare"]: self.__copy_xml_to_ti_share(xml_report_file_path, xml_file_name, config) for item in email_stix_path_tuple_list: self.__copy_xml_to_ti_share(item[0], item[1], config, "email") else: log.warning("copy to TI share is disabled: %s" % (config["copytoshare"])) return
def stix(json): """ Created a stix file based on a json file that is being handed over """ # Create a new STIXPackage stix_package = STIXPackage() # Create a new STIXHeader stix_header = STIXHeader() # Add Information Source. This is where we will add the tool information. stix_header.information_source = InformationSource() # Create a ToolInformation object. Use the initialization parameters # to set the tool and vendor names. # # Note: This is an instance of cybox.common.ToolInformation and NOT # stix.common.ToolInformation. tool = ToolInformation( tool_name="viper2stix", tool_vendor="The Viper group http://viper.li - developed by Alexander Jaeger https://github.com/deralexxx/viper2stix" ) #Adding your identity to the header identity = Identity() identity.name = Config.get('stix', 'producer_name') stix_header.information_source.identity=identity # Set the Information Source "tools" section to a # cybox.common.ToolInformationList which contains our tool that we # created above. stix_header.information_source.tools = ToolInformationList(tool) stix_header.title = Config.get('stix', 'title') # Set the produced time to now stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = Config.get('stix', 'TLP') marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) # Set the header description stix_header.description = Config.get('stix', 'description') # Set the STIXPackage header stix_package.stix_header = stix_header stix_package.stix_header.handling = handling try: pp = pprint.PrettyPrinter(indent=5) pp.pprint(json['default']) #for key, value in json['default'].iteritems(): # print key, value for item in json['default']: #logger.debug("item %s", item) indicator = Indicator() indicator.title = "File Hash" indicator.description = ( "An indicator containing a File observable with an associated hash" ) # Create a CyboX File Object f = File() sha_value = item['sha256'] if sha_value is not None: sha256 = Hash() sha256.simple_hash_value = sha_value h = Hash(sha256, Hash.TYPE_SHA256) f.add_hash(h) sha1_value = item['sha1'] if sha_value is not None: sha1 = Hash() sha1.simple_hash_value = sha1_value h = Hash(sha1, Hash.TYPE_SHA1) f.add_hash(h) sha512_value = item['sha512'] if sha_value is not None: sha512 = Hash() sha512.simple_hash_value = sha512_value h = Hash(sha512, Hash.TYPE_SHA512) f.add_hash(h) f.add_hash(item['md5']) #adding the md5 hash to the title as well stix_header.title+=' '+item['md5'] #print(item['type']) f.size_in_bytes=item['size'] f.file_format=item['type'] f.file_name = item['name'] indicator.description = "File hash served by a Viper instance" indicator.add_object(f) stix_package.add_indicator(indicator) except Exception, e: logger.error('Error: %s',format(e)) return False
def main(): # get args parser = argparse.ArgumentParser ( description = "Parse a given CSV from Shadowserver and output STIX XML to stdout" , formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("--infile","-f", help="input CSV with bot data", default = "bots.csv") args = parser.parse_args() # setup stix document stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = "Bot Server IP addresses" stix_header.description = "IP addresses connecting to bot control servers at a given port" stix_header.add_package_intent ("Indicators - Watchlist") # add marking mark = Marking() markspec = MarkingSpecification() markstruct = SimpleMarkingStructure() markstruct.statement = "Usage of this information, including integration into security mechanisms implies agreement with the Shadowserver Terms of Service available at https://www.shadowserver.org/wiki/pmwiki.php/Shadowserver/TermsOfService" markspec.marking_structures.append(markstruct) mark.add_marking(markspec) stix_header.handling = mark # include author info stix_header.information_source = InformationSource() stix_header.information_source.time = Time() stix_header.information_source.time.produced_time =datetime.now(tzutc()) stix_header.information_source.tools = ToolInformationList() stix_header.information_source.tools.append("ShadowBotnetIP-STIXParser") stix_header.information_source.identity = Identity() stix_header.information_source.identity.name = "MITRE STIX Team" stix_header.information_source.add_role(VocabString("Format Transformer")) src = InformationSource() src.description = "https://www.shadowserver.org/wiki/pmwiki.php/Services/Botnet-CCIP" srcident = Identity() srcident.name = "shadowserver.org" src.identity = srcident src.add_role(VocabString("Originating Publisher")) stix_header.information_source.add_contributing_source(src) stix_package.stix_header = stix_header # add TTP for overall indicators bot_ttp = TTP() bot_ttp.title = 'Botnet C2' bot_ttp.resources = Resource() bot_ttp.resources.infrastructure = Infrastructure() bot_ttp.resources.infrastructure.title = 'Botnet C2' stix_package.add_ttp(bot_ttp) # read input data fd = open (args.infile, "rb") infile = csv.DictReader(fd) for row in infile: # split indicators out, may be 1..n with positional storage, same port and channel, inconsistent delims domain = row['Domain'].split() country = row['Country'].split() region = row['Region'].split('|') state = row['State'].split('|') asn = row['ASN'].split() asname = row['AS Name'].split() asdesc = row['AS Description'].split('|') index = 0 for ip in row['IP Address'].split(): indicator = Indicator() indicator.title = "IP indicator for " + row['Channel'] indicator.description = "Bot connecting to control server" # point to overall TTP indicator.add_indicated_ttp(TTP(idref=bot_ttp.id_)) # add our IP and port sock = SocketAddress() sock.ip_address = ip # add sighting sight = Sighting() sight.timestamp = "" obs = Observable(item=sock.ip_address) obsref = Observable(idref=obs.id_) sight.related_observables.append(obsref) indicator.sightings.append(sight) stix_package.add_observable(obs) # add pattern for indicator sock_pattern = SocketAddress() sock_pattern.ip_address = ip port = Port() port.port_value = row['Port'] sock_pattern.port = port sock_pattern.ip_address.condition= "Equals" sock_pattern.port.port_value.condition= "Equals" indicator.add_object(sock_pattern) stix_package.add_indicator(indicator) # add domain domain_obj = DomainName() domain_obj.value = domain[index] domain_obj.add_related(sock.ip_address,"Resolved_To", inline=False) stix_package.add_observable(domain_obj) # add whois obs whois_obj = WhoisEntry() registrar = WhoisRegistrar() registrar.name = asname[index] registrar.address = state[index] + region[index] + country[index] whois_obj.registrar_info = registrar whois_obj.add_related(sock.ip_address,"Characterizes", inline=False) stix_package.add_observable(whois_obj) # add ASN obj asn_obj = AutonomousSystem() asn_obj.name = asname[index] asn_obj.number = asn[index] asn_obj.handle = "AS" + str(asn[index]) asn_obj.add_related(sock.ip_address,"Contains", inline=False) stix_package.add_observable(asn_obj) # iterate index = index + 1 print stix_package.to_xml()