def resolveObjects(incident, ttps, objects, eventTags, org): for obj in objects: tmp_incident = Incident() resolveAttributes(tmp_incident, ttps, obj["Attribute"], eventTags, org) indicator = Indicator( timestamp=getDateFromTimestamp(int(obj["timestamp"]))) indicator.id_ = namespace[1] + ":MispObject-" + obj["uuid"] setProd(indicator, org) if obj["comment"] != "": indicator.description = obj["comment"] tlpTags = eventTags for attr in obj["Attribute"]: tlpTags = mergeTags(tlpTags, attr) setTLP(indicator, obj["distribution"], tlpTags, True) indicator.title = obj["name"] + " (MISP Object #" + obj["id"] + ")" indicator.description = indicator.title indicator.add_indicator_type("Malware Artifacts") indicator.add_valid_time_position(ValidTime()) indicator.observable_composition_operator = "AND" for rindicator in tmp_incident.related_indicators: if rindicator.item.observable: indicator.add_observable(rindicator.item.observable) relatedIndicator = RelatedIndicator(indicator, relationship=obj["meta-category"]) incident.related_indicators.append(relatedIndicator)
def main(): file_hash = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' stix_header = STIXHeader( title="File Hash Reputation Service Results", package_intents=["Indicators - Malware Artifacts"]) stix_package = STIXPackage(stix_header=stix_header) indicator = Indicator( title= "File Reputation for SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ) indicator.add_indicator_type("File Hash Watchlist") file_object = File() file_object.add_hash(Hash(file_hash)) file_object.hashes[0].simple_hash_value.condition = "Equals" file_object.hashes[0].type_.condition = "Equals" indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(title="Malicious file")) indicator.confidence = Confidence(value=VocabString('75')) indicator.confidence.value.vocab_name = "Percentage" indicator.confidence.value.vocab_reference = "https://en.wikipedia.org/wiki/Percentage" stix_package.add_indicator(indicator) print(stix_package.to_xml(encoding=None))
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 _dostix(hashes): '''This function creates a STIX packages containing hashes.''' print("[+] Creating STIX Package") title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now()) _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix']) stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = title stix_package.stix_header.handling = _marking() try: indicator = Indicator() indicator.set_producer_identity(SETTINGS['stix']['producer']) indicator.set_produced_time(indicator.timestamp) indicator.set_received_time(indicator.timestamp) indicator.add_kill_chain_phase(PHASE_DELIVERY) indicator.confidence = "Low" indicator.title = title indicator.add_indicator_type("File Hash Watchlist") indicator.description = SETTINGS['stix']['ind_desc'] try: indicator.add_indicated_ttp( TTP(idref=SETTINGS['indicated_ttp'], timestamp=indicator.timestamp)) indicator.suggested_coas.append( CourseOfAction(idref=SETTINGS['suggested_coa'], timestamp=indicator.timestamp)) except KeyError: pass for info in hashes: try: file_name = info['filename'] file_object = File() file_object.file_name = file_name file_object.file_name.condition = "Equals" file_object.file_extension = "." + file_name.split('.')[-1] file_object.file_extension.condition = "Equals" file_object.size_in_bytes = info['filesize'] file_object.size_in_bytes.condition = "Equals" file_object.file_format = info['fileformat'] file_object.file_format.condition = "Equals" file_object.add_hash(Hash(info['md5'])) file_object.add_hash(Hash(info['sha1'])) file_object.add_hash(Hash(info['sha256'])) file_object.add_hash(Hash(info['sha512'])) file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP)) for hashobj in file_object.hashes: hashobj.simple_hash_value.condition = "Equals" hashobj.type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + file_name indicator.add_observable(file_obs) except TypeError: pass stix_package.add_indicator(indicator) return stix_package except KeyError: pass
def create_indicator(self, ce1sus_indicator, event_permissions, user): indicator = Indicator() indicator.id_ = 'ce1sus:Indicator-{0}'.format(ce1sus_indicator.uuid) indicator.title = ce1sus_indicator.title indicator.description = ce1sus_indicator.description indicator.short_description = ce1sus_indicator.short_description if ce1sus_indicator.confidence: indicator.confidence = ce1sus_indicator.confidence.title() else: indicator.confidence = 'Low' # TODO: handling # TODO: markings for type_ in ce1sus_indicator.types: indicator.add_indicator_type(type_.name) if ce1sus_indicator.operator: indicator.observable_composition_operator = ce1sus_indicator.operator # Todo Add confidence # indicator_attachment.confidence = "Low" creator = self.create_stix_identity(ce1sus_indicator) time = self.cybox_mapper.get_time( produced_time=ce1sus_indicator.created_at) info_source = InformationSource(identity=creator, time=time) indicator.producer = info_source observables = ce1sus_indicator.get_observables_for_permissions( event_permissions, user) for obs in observables: cybox_obs = self.create_observable(obs, event_permissions, user) indicator.add_observable(cybox_obs) valid_time = ValidTime(start_time=ce1sus_indicator.created_at, end_time=ce1sus_indicator.created_at) indicator.add_valid_time_position(valid_time) return indicator
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 generate_indicators(self, count): '''Generate a list of STIX Indicators''' indicators = [] for i in range(0, count): indicator = Indicator(title='Multiple indicator types') indicator.set_producer_identity(Identity(name='Secret Source')) indicator.set_produced_time(datetime.today()) indicator.add_indicator_type(choice(['Malware Artifacts', 'C2', 'Exfiltration'])) indicator.add_short_description('Short description...') indicator.add_description('Long description...') indicator.confidence = Confidence(choice(['High', 'Medium', 'Low', 'None', 'Unknown'])) kill_chain_phase = choice(LMCO_KILL_CHAIN_PHASES) indicator.kill_chain_phases = KillChainPhasesReference( [KillChainPhaseReference(name=kill_chain_phase.name)]) ips = self.gen_ips(randint(0, 5)) for ip in ips: indicator.add_observable(ip) # user_agents = self.gen_user_agents(randint(0, 5)) # for ua in user_agents: # indicator.add_observable(ua) # fqnds = self.gen_fqdns(randint(0, 5)) # for f in fqnds: # indicator.add_observable(f) # urls = self.gen_urls(randint(0, 5)) # for u in urls: # indicator.add_observable(u) indicators.append(indicator) return indicators
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 _add_stix_indicators(self, final_indicator_objects, ttp_id): """Create and add STIX Indicators for a list of Object History entries. Link each Indicator to their Indicated TTP. Note: Each STIX Indicator is added to the STIX Package stored in the ``stix_package`` class member. Args: final_indicator_objects: a list of ``maec.bundle.object_history.ObjectHistoryEntry`` objects representing the final, pruned list of Objects to be used in the STIX Indicators. ttp_id: the id of the STIX TTP that each STIX Indicator should reference as its Indicated TTP. """ object_values_list = [] actions_list = [] final_object_list = [] # Deduplicate the Objects and combine their Actions for entry in final_indicator_objects: object = entry.object # Test if we've already created an Indicator for this Object obj_values = BundleDeduplicator.get_object_values(object) if obj_values not in object_values_list: object_values_list.append(obj_values) final_object_list.append(object) actions_list.append(entry.get_action_names()) else: object_index = object_values_list.index(obj_values) existing_actions = actions_list[object_index] existing_actions += entry.get_action_names() # Create the STIX Indicators for object in final_object_list: object_index = final_object_list.index(object) indicator = Indicator() indicator.title = "Malware Artifact Extracted from MAEC Document" indicator.add_indicator_type("Malware Artifacts") indicator.add_observable(object.properties) # Add the Action-derived description to the Indicator description = "Corresponding Action(s): " for action_name in actions_list[object_index]: description += (action_name + ", ") indicator.description = description[:-2] # Set the proper Confidence on the Indicator confidence = Confidence() confidence.value = "Low" confidence.description = "Tool-generated Indicator. It is HIGHLY recommended that it be vetted by a human analyst before usage." indicator.confidence = confidence # Link the Indicator to its Indicated TTP ttp = TTP(idref=ttp_id) indicator.add_indicated_ttp(ttp) # Add the Indicator to the STIX Package self.stix_package.add_indicator(indicator)
def stix(self): """Output data as STIX. STIX is highly subjective and difficult to format without getting more data from the user. Passive DNS results are formtted into a STIX watchlist with descriptions and other details about the record. :return: STIX formatted watchlist """ if python3: raise RuntimeError("STIX is not supported when using Python 3 due to dependency libraries.") stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Passive DNS resolutions associated" \ " with %s during the time periods of " \ " %s - %s" % (self.queryValue, self.firstSeen, self.lastSeen) stix_package.stix_header = stix_header for record in self._records: indicator = Indicator( title="Observed from %s - %s" % ( record.firstSeen, record.lastSeen ), short_description="Resolution observed by %s." % ( ','.join(record.source) ), description="Passive DNS data collected and aggregated from" \ " PassiveTotal services." ) if is_ip(record.resolve): indicator.add_indicator_type('IP Watchlist') ioc = Address( address_value=record.resolve, category=Address.CAT_IPV4 ) else: indicator.add_indicator_type('Domain Watchlist') ioc = DomainName(value=record.resolve) ioc.condition = "Equals" indicator.add_observable(ioc) stix_package.add_indicator(indicator) output = stix_package.to_xml() return output
def main(): pkg = STIXPackage() indicator = Indicator() indicator.id_ = "example:package-382ded87-52c9-4644-bab0-ad3168cbad50" indicator.title = "Malicious site hosting downloader" indicator.add_indicator_type("URL Watchlist") url = URI() url.value = "http://x4z9arb.cn/4712" url.type_ = URI.TYPE_URL indicator.add_observable(url) pkg.add_indicator(indicator) print pkg.to_xml()
def main(): stix_package = STIXPackage() ttp = TTP(title="C2 Behavior") indicator = Indicator(title="IP Address for known C2 Channel") indicator.add_indicator_type("IP Watchlist") addr = Address(address_value="10.0.0.0", category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_ttp(ttp) print(stix_package.to_xml(encoding=None))
def main(): pkg = STIXPackage() indicator = Indicator() indicator.id_ = "example:package-382ded87-52c9-4644-bab0-ad3168cbad50" indicator.title = "Malicious site hosting downloader" indicator.add_indicator_type("URL Watchlist") url = URI() url.value = "http://x4z9arb.cn/4712" url.type_ = URI.TYPE_URL url.value.condition = "Equals" indicator.add_observable(url) pkg.add_indicator(indicator) print pkg.to_xml()
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 buildIndicator(input_dict): indicator = Indicator() indicator.description = input_dict["description"] if input_dict["confidence"]: indicator.confidence = input_dict["confidence"] if input_dict["impact"]: indicator.likely_impact = input_dict["impact"] if input_dict["producer"]: indicator.producer = InformationSource() indicator.producer.identity = Identity(input_dict["producer"]) indicator.title = input_dict["title"] indicator.add_valid_time_position(valid_time.ValidTime(input_dict["starttime"], input_dict["endtime"])) if input_dict["type"]: indicator.add_indicator_type(input_dict["type"]) return indicator
def to_stix_relationship(obj): from stix.indicator import Indicator ind_rel = [] for relationship in obj.relationships: #if not relationship.private: #testing ind = Indicator() ind.title = "MARTI Relation" ind.timestamp = relationship.relationship_date ind.confidence = relationship.rel_confidence.title() ind.id_ = relationship.url_key ind.add_indicator_type(get_indicator_type(relationship.rel_type)) ind.description = relationship.rel_reason ind.short_description = relationship.relationship ind_rel.append(ind) return ind_rel
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 add_malware(hashVal, TTPTitle, malware_uuid): malware_instance = MalwareInstance() malware_instance.add_name(TTPTitle) # malware_instance.add_type("Malware") ttp = TTP(title=TTPTitle) ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) file_object = File() file_object.add_hash(Hash(hashVal)) file_object.hashes[0].simple_hash_value.condition = "Equals" indicator = Indicator(id_="indicator-{0}".format(malware_uuid), title="File hash") indicator.add_indicator_type("File Hash Watchlist") indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) return (indicator)
def main(): package = STIXPackage() # Create the indicator indicator = Indicator(title="IP Address for known C2 Channel") indicator.add_indicator_type("IP Watchlist") address = Address(category="ipv4-addr") address.address_value = "10.0.0.0" address.address_value.condition = "Equals" indicator.observable = address package.add_indicator(indicator) # Create the campaign campaign = Campaign(title="Operation Omega") package.add_campaign(campaign) # Link the campaign to the indicator campaign.related_indicators.append(RelatedIndicator(item=Indicator(idref=indicator.id_))) print package.to_xml()
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(): package = STIXPackage() # Create the indicator indicator = Indicator(title="IP Address for known C2 Channel") indicator.add_indicator_type("IP Watchlist") address = Address(category="ipv4-addr") address.address_value = "10.0.0.0" address.address_value.condition = "Equals" indicator.observable = address package.add_indicator(indicator) # Create the campaign campaign = Campaign(title="Operation Omega") package.add_campaign(campaign) # Link the campaign to the indicator campaign.related_indicators.append( RelatedIndicator(item=Indicator(idref=indicator.id_))) print package.to_xml()
def main(): stix_package = STIXPackage() ttp = TTP(title="Phishing") stix_package.add_ttp(ttp) # Create the indicator for just the subject email_subject_object = EmailMessage() email_subject_object.header = EmailHeader() email_subject_object.header.subject = "[IMPORTANT] Please Review Before" email_subject_object.header.subject.condition = "StartsWith" email_subject_indicator = Indicator() email_subject_indicator.title = "Malicious E-mail Subject Line" email_subject_indicator.add_indicator_type("Malicious E-mail") email_subject_indicator.observable = email_subject_object email_subject_indicator.confidence = "Low" # Create the indicator for just the attachment file_attachment_object = EmailMessage() file_attachment_object.attachments = Attachments() attached_file_object = File() attached_file_object.file_name = "Final Report" attached_file_object.file_name.condition = "StartsWith" attached_file_object.file_extension = "doc.exe" attached_file_object.file_extension.condition = "Equals" file_attachment_object.add_related(attached_file_object, "Contains", inline=True) file_attachment_object.attachments.append(file_attachment_object.parent.id_) indicator_attachment = Indicator() indicator_attachment.title = "Malicious E-mail Attachment" indicator_attachment.add_indicator_type("Malicious E-mail") indicator_attachment.observable = file_attachment_object indicator_attachment.confidence = "Low" # Create the combined indicator w/ both subject an attachment full_email_object = EmailMessage() full_email_object.attachments = Attachments() # Add the previously referenced file as another reference rather than define it again: full_email_object.attachments.append(file_attachment_object.parent.id_) full_email_object.header = EmailHeader() full_email_object.header.subject = "[IMPORTANT] Please Review Before" full_email_object.header.subject.condition = "StartsWith" combined_indicator = Indicator(title="Malicious E-mail") combined_indicator.add_indicator_type("Malicious E-mail") combined_indicator.confidence = Confidence(value="High") combined_indicator.observable = full_email_object email_subject_indicator.add_indicated_ttp(TTP(idref=ttp.id_)) indicator_attachment.add_indicated_ttp(TTP(idref=ttp.id_)) combined_indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.indicators = [combined_indicator, email_subject_indicator, indicator_attachment] print stix_package.to_xml()
def main(): fileIn = open('tor_exit_node_list.txt', 'r') fileOut = open('tor_stix.xml', 'w') #print("List of Tor Exit nodes as of 5/4/2018") ip_addr_list = [] for line in fileIn: ip_addr = re.search( '(([2][5][0-5]\.)|([2][0-4][0-9]\.)|([0-1]?[0-9]?[0-9]\.)){3}(([2][5][0-5])|([2][0-4][0-9])|([0-1]?[0-9]?[0-9]))', line) if ip_addr: ip_addr_list.append(ip_addr) #print(" ", ip_addr.group(0)) stix_package = STIXPackage() ttp = TTP(title="Tor Exit Nodes") i = 0 for ip_addr in ip_addr_list: indicator = Indicator(title="IP Address for known Tor exit Node") indicator.add_indicator_type("IP Watchlist") addr = Address(address_value=ip_addr.group(0), category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) print(i) i = i + 1 stix_package.add_ttp(ttp) #print(stix_package.to_xml(encoding=None)) fileOut.write(stix_package.to_xml(encoding=None))
def resolve_objects(self, incident, tags): for misp_object in self.misp_event.objects: tlp_tags = None tmp_incident = Incident() tlp_tags = deepcopy(tags) self.resolve_attributes(tmp_incident, misp_object.attributes, tags) indicator = Indicator(timestamp=self.get_date_from_timestamp(int(misp_object.timestamp))) indicator.id_ = "{}:MispObject-{}".format(namespace[1], misp_object.uuid) self.set_prod(indicator, self.orgc_name) for attribute in misp_object.attributes: tlp_tags = self.merge_tags(tlp_tags, attribute) self.set_tlp(indicator, misp_object.distribution, tlp_tags) title = "{} (MISP Object #{})".format(misp_object.name, misp_object.id) indicator.title = title indicator.description = misp_object.comment if misp_object.comment else title indicator.add_indicator_type("Malware Artifacts") indicator.add_valid_time_position(ValidTime()) indicator.observable_composition_operator = "AND" for rindicator in tmp_incident.related_indicators: if rindicator.item.observable: indicator.add_observable(rindicator.item.observable) relatedIndicator = RelatedIndicator(indicator, relationship=misp_object['meta-category']) incident.related_indicators.append(relatedIndicator)
def main(): stix_package = STIXPackage() malware_instance = MalwareInstance() malware_instance.add_name("Poison Ivy") malware_instance.add_type("Remote Access Trojan") ttp = TTP(title="Poison Ivy") ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) file_object = File() file_object.add_hash(Hash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) indicator = Indicator(title="File hash for Poison Ivy variant") indicator.add_indicator_type("File Hash Watchlist") indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_ttp(ttp) print stix_package.to_xml()
def main(): data = json.load(open("data.json")) stix_package = STIXPackage() ttps = {} for info in data['ips']: if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) indicator = Indicator(title=info['ip']) indicator.add_indicator_type("IP Watchlist") addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_)) stix_package.add_indicator(indicator) print stix_package.to_xml()
def main(): stix_package = STIXPackage() malware_instance = MalwareInstance() malware_instance.add_name("Poison Ivy") malware_instance.add_type("Remote Access Trojan") ttp = TTP(title="Poison Ivy") ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) file_object = File() file_object.add_hash(Hash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) file_object.hashes[0].simple_hash_value.condition = "Equals" indicator = Indicator(title="File hash for Poison Ivy variant") indicator.add_indicator_type("File Hash Watchlist") indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_ttp(ttp) print stix_package.to_xml()
def main(): file_hash = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' stix_header = STIXHeader(title="File Hash Reputation Service Results", package_intents=["Indicators - Malware Artifacts"]) stix_package = STIXPackage(stix_header=stix_header) indicator = Indicator(title="File Reputation for SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") indicator.add_indicator_type("File Hash Watchlist") file_object = File() file_object.add_hash(Hash(file_hash)) file_object.hashes[0].simple_hash_value.condition = "Equals" file_object.hashes[0].type_.condition = "Equals" indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(title="Malicious file")) indicator.confidence = Confidence(value=VocabString('75')) indicator.confidence.value.vocab_name = "Percentage" indicator.confidence.value.vocab_reference = "https://en.wikipedia.org/wiki/Percentage" stix_package.add_indicator(indicator) print(stix_package.to_xml(encoding=None))
def main(): # get args parser = argparse.ArgumentParser ( description = "Parse a given CSV and output STIX XML" , formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("--infile","-f", help="input CSV", default = "in.csv") args = parser.parse_args() # setup header contain_pkg = STIXPackage() stix_header = STIXHeader() stix_header.title = "Indicators" stix_header.add_package_intent ("Indicators") # XXX add Information_Source and Handling contain_pkg.stix_header = stix_header # create kill chain with three options (pre, post, unknown), relate as needed pre = KillChainPhase(phase_id="stix:KillChainPhase-1a3c67f7-5623-4621-8d67-74963d1c5fee", name="Pre-infection indicator", ordinality=1) post = KillChainPhase(phase_id="stix:KillChainPhase-d5459305-1a27-4f50-9875-23793d75e4fe", name="Post-infection indicator", ordinality=2) chain = KillChain(id_="stix:KillChain-3fbfebf2-25a7-47b9-ad8b-3f65e56e402d", name="Degenerate Cyber Kill Chain" ) chain.definer = "U5" chain.kill_chain_phases = [pre, post] contain_pkg.ttps.kill_chains.append(chain) # read input data fd = open (args.infile, "rb") infile = csv.DictReader(fd) for row in infile: # create indicator for each row error = False ind = Indicator() ind.add_alternative_id(row['ControlGroupID']) ind.title = "Indicator with ID " + row['IndicatorID'] ind.description = row['Notes'] ind.producer = InformationSource() ind.producer.description = row['Reference'] # XXX unknown purpose for 'Malware' field - omitted # if the field denotes a specific malware family, we might relate as 'Malware TTP' to the indicator # set chain phase if 'Pre' in row['Infection Type']: ind.kill_chain_phases.append(KillChainPhaseReference(phase_id="stix:KillChainPhase-1a3c67f7-5623-4621-8d67-74963d1c5fee",kill_chain_id="stix:KillChain-3fbfebf2-25a7-47b9-ad8b-3f65e56e402d")) elif 'Post' in row['Infection Type']: ind.kill_chain_phases.append(KillChainPhaseReference(phase_id="stix:KillChainPhase-1a3c67f7-5623-4621-8d67-74963d1c5fee",kill_chain_id="stix:KillChain-3fbfebf2-25a7-47b9-ad8b-3f65e56e402d")) ind_type = row['Indicator Type'] if 'IP' in ind_type: ind.add_indicator_type( "IP Watchlist") ind_obj = SocketAddress() ind_obj.ip_address = row['Indicator'] ind_obj.ip_address.condition= "Equals" if row['indValue']: port = Port() # pull port out, since it's in form "TCP Port 42" port.port_value = row['indValue'].split()[-1] port.layer4_protocol = row['indValue'].split()[0] port.port_value.condition= "Equals" ind_obj.port = port elif 'Domain' in ind_type: ind.add_indicator_type ("Domain Watchlist") ind_obj = DomainName() ind_obj.value = row['Indicator'] ind_obj.value.condition= "Equals" elif 'Email' in ind_type: # parse out which part of the email is being # i.e. "Sender: attach | Subject: whatever" tag = row['Indicator'].split(':')[0] val = row['Indicator'].split(':')[1] ind.add_indicator_type ("Malicious E-mail") ind_obj = EmailMessage() if "Subject" in tag: ind_obj.subject = val ind_obj.subject.condition= "Equals" elif "Sender" in tag: ind_obj.sender = val ind_obj.sender.condition= "Equals" elif "Attachment" in tag: # make inline File to store filename file_obj = File() file_obj.id_ = cybox.utils.create_id(prefix="File") file_obj.file_name = val file_obj.file_name.condition = "Equals" ind_obj.add_related(file_obj, "Contains") attach = Attachments() attach.append(file_obj.id_) ind_obj.attachments = attach elif 'User Agent' in ind_type: ind.add_indicator_type( VocabString(row['Indicator Type'])) fields = HTTPRequestHeaderFields() fields.user_agent = row['Indicator'] fields.user_agent.condition = "Equals" header = HTTPRequestHeader() header.parsed_header = fields thing = HTTPRequestResponse() thing.http_client_request = HTTPClientRequest() thing.http_client_request.http_request_header = header ind_obj = HTTPSession() ind_obj.http_request_response = [thing] elif 'URI' in ind_type: ind.add_indicator_type( VocabString(row['Indicator Type'])) thing = HTTPRequestResponse() thing.http_client_request = HTTPClientRequest() thing.http_client_request.http_request_line = HTTPRequestLine() thing.http_client_request.http_request_line.http_method = row['Indicator'].split()[0] thing.http_client_request.http_request_line.http_method.condition = "Equals" thing.http_client_request.http_request_line.value = row['Indicator'].split()[1] thing.http_client_request.http_request_line.value.condition = "Equals" ind_obj = HTTPSession() ind_obj.http_request_response = [thing] elif 'File' in ind_type: ind.add_indicator_type( VocabString(row['Indicator Type'])) ind_obj = File() ind_obj.file_name = row['Indicator'] ind_obj.file_name.condition = "Equals" digest = Hash() # XXX assumes that hash digests are stored in this field in real data digest.simple_hash_value = row['indValue'].strip() digest.simple_hash_value.condition = "Equals" digest.type_.condition = "Equals" ind_obj.add_hash(digest) elif 'Registry' in ind_type: ind.add_indicator_type( VocabString(row['Indicator Type'])) ind_obj = WinRegistryKey() keys = RegistryValues() key = RegistryValue() key.name = row['Indicator'] key.name.condition = "Equals" key.data = row['indValue'] key.data.condition = "Equals" keys.append(key) ind_obj.values = keys elif 'Mutex' in ind_type: ind.add_indicator_type (VocabString(row['Indicator Type'])) ind_obj = Mutex() ind_obj.name = row['Indicator'] ind_obj.name.condition= "Equals" else: print "ERR type not supported: " + ind_type + " <- will be omitted from output" error = True # finalize indicator if not error: ind.add_object(ind_obj) contain_pkg.add_indicator(ind) # DONE looping print contain_pkg.to_xml()
def json2indicator(config, src, dest, endpoint, json_, crits_id): '''transform crits indicators into stix indicators with embedded cybox observable composition''' try: set_id_method(IDGenerator.METHOD_UUID) xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name'] set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) if endpoint == 'indicators': endpoint_trans = { 'Email': 'emails', 'IP': 'ips', 'Sample': 'samples', 'Domain': 'domains', 'Indicator': 'indicators', 'Event': 'events' } if json_.get('type', None) not in ['Reference', 'Related_To']: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type='indicator type ' + json_.get('type', 'None'), id_=crits_id)) return (None) indicator_ = Indicator() indicator_.id = xmlns_name + ':indicator-' + crits_id indicator_.id_ = indicator_.id indicator_.title = json_['value'] indicator_.confidence = json_['confidence']['rating'].capitalize() indicator_.add_indicator_type('Malware Artifacts') observable_composition_ = ObservableComposition() observable_composition_.operator = \ indicator_.observable_composition_operator for r in json_['relationships']: if r.get('relationship', None) not in ['Contains', 'Related_To']: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type='indicator relationship type ' + r.get('relationship', 'None'), id_=crits_id)) continue if r['type'] in ['Sample', 'Email', 'IP', 'Sample', 'Domain']: observable_ = Observable() observable_.idref = xmlns_name + ':observable-' + r['value'] observable_composition_.add(observable_) elif r['type'] == 'Indicator': related_indicator = RelatedIndicator( Indicator(idref=xmlns_name + ':indicator-' + r['value'])) indicator_.related_indicators.append(related_indicator) # stix indicators don't support related_incident :-( # elif r['type'] == 'Event': # related_incident = RelatedIncident(Incident(idref=xmlns_name + ':incident-' + r['value'])) # indicator_.related_incidents.append(related_incident) indicator_.observable = Observable() indicator_.observable.observable_composition = \ observable_composition_ return (indicator_) else: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type=endpoint, id_=crits_id)) return (None) except: e = sys.exc_info()[0] config['logger'].error(log.log_messages['obj_convert_error'].format( src_type='crits', src_obj='indicator', id_=crits_id, dest_type='stix', dest_obj='indicator')) config['logger'].exception(e) return (None)
def genStixDoc( outputDir_, targetFileSha1_, targetFileSha256_, targetFileSha512_, targetFileSsdeep_, targetFileMd5_, targetFileSize_, targetFileName_, ipv4Addresses_, hostNames_): """ Generate Stix document from the input values. The doc structure is the file object along with the related network items: addresses, domain names. Output is written to files, which are then wrapped with taxii and uploaded using a separate script. """ parsedTargetFileName = reFileName(targetFileName_)[1] parsedTargetFilePrefix = reFileName(targetFileName_)[0] stix.utils.set_id_namespace({"http://www.equifax.com/cuckoo2Stix" : "cuckoo2Stix"}) NS = cybox.utils.Namespace("http://www.equifax.com/cuckoo2Stix", "cuckoo2Stix") cybox.utils.set_id_namespace(NS) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = 'File: ' + parsedTargetFileName + ' with the associated hashes, network indicators' stix_header.description = 'File: ' + parsedTargetFileName + ' with the associated hashes, network indicators' stix_package.stix_header = stix_header # Create the ttp malware_instance = MalwareInstance() malware_instance.add_name(parsedTargetFileName) malware_instance.description = targetFileSha1_ ttp = TTP(title='TTP: ' + parsedTargetFileName) ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) stix_package.add_ttp(ttp) # Create the indicator for the ipv4 addresses ipv4Object = Address(ipv4Addresses_, Address.CAT_IPV4) ipv4Object.condition = 'Equals' ipv4Indicator = Indicator() ipv4Indicator.title = parsedTargetFileName + ': ipv4 addresses' ipv4Indicator.add_indicator_type('IP Watchlist') ipv4Indicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship='Indicates Malware')) ipv4Indicator.observable = ipv4Object ipv4Indicator.confidence = 'Low' # Create the indicator for the domain names domainNameObject = DomainName() domainNameObject.value = hostNames_ domainNameObject.condition = 'Equals' domainNameIndicator = Indicator() domainNameIndicator.title = parsedTargetFileName + ': domain names' domainNameIndicator.add_indicator_type('Domain Watchlist') domainNameIndicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship='Indicates Malware')) domainNameIndicator.observable = domainNameObject domainNameIndicator.confidence = 'Low' # Create the indicator for the file fileObject = File() fileObject.file_name = parsedTargetFileName fileObject.file_name.condition = 'Equals' fileObject.size_in_bytes = targetFileSize_ fileObject.size_in_bytes.condition = 'Equals' fileObject.add_hash(Hash(targetFileSha1_, type_='SHA1', exact=True)) fileObject.add_hash(Hash(targetFileSha256_, type_='SHA256', exact=True)) fileObject.add_hash(Hash(targetFileSha512_, type_='SHA512', exact=True)) fileObject.add_hash(Hash(targetFileSsdeep_, type_='SSDEEP', exact=True)) fileObject.add_hash(Hash(targetFileMd5_, type_='MD5', exact=True)) fileIndicator = Indicator() fileIndicator.title = parsedTargetFileName + ': hashes' fileIndicator.description = parsedTargetFilePrefix fileIndicator.add_indicator_type('File Hash Watchlist') fileIndicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship="Indicates Malware")) fileIndicator.observable = fileObject fileIndicator.confidence = 'Low' stix_package.indicators = [fileIndicator, ipv4Indicator, domainNameIndicator] stagedStixDoc = stix_package.to_xml() stagedStixDoc = fixAddressObject(stagedStixDoc) stagedStixDoc = fixDomainObject(stagedStixDoc) today = datetime.datetime.now() now = today.strftime('%Y-%m-%d_%H%M%S') if not os.path.exists(outputDir_): os.makedirs(outputDir_) with open (outputDir_ + '/' + now + '-' + targetFileSha1_ + '.stix.xml', 'a') as myfile: myfile.write(stagedStixDoc) _l.debug('Wrote file: ' + now + '-' + targetFileSha1_ + '.stix.xml') return
def index2stix(local_index, orig_stix): #============= # Build package metadata #============= new_stix = STIXPackage() new_stix.stix_header = STIXHeader() new_stix.stix_header.title = "TG3390 - Enrichment" new_stix.stix_header.description = "Enrichment stix file to the Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/" marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) new_stix.stix_header.handling = handling enrich_IPs = Indicator(title="Suspected TG3390 IP Addresses obtained through automated enrichment") enrich_IPs.add_indicator_type("IP Watchlist") enrich_IPs.confidence = "Low" related_IPs = Indicator(title="Related indicator wrapper for source of enrichment") related_IPs.add_indicator_type("IP Watchlist") related_IPs.confidence = "Medium" enrich_Domains = Indicator(title="Suspected TG3390 Domains obtained through automated enrichment") enrich_Domains.add_indicator_type("Domain Watchlist") enrich_Domains.confidence = "Low" related_Domains = Indicator(title="Related indicator wrapper for source of enrichment") related_Domains.add_indicator_type("Domain Watchlist") related_Domains.confidence = "Medium" # START with the ones that already have ids: #if verbose: #print_chain(local_index) new_ref_created = True while new_ref_created: new_ref_created = False for ind_type in local_index: for obs in local_index[ind_type]: id_tobe_referenced = local_index[ind_type][obs][0] #print id_tobe_referenced[:10] if id_tobe_referenced[:10] != '{{no_ref}}': ref_obs = Observable() ref_obs.id_ = id_tobe_referenced.replace("{{no_ref}}","") ref_obs.description = 'Source of enrichment for: ' create_ref_obs = False for entry in local_index[ind_type][obs]: if type(entry) is list: if len(entry)>0: for item in entry: ref, child_ind_type = get_ref_from_obs(item, local_index) #print item if ref == '{{no_ref}}' or ref == '': create_ref_obs = True new_ref_created = True #print 'Create new, complete, observable for ' + item #print child_ind_type #Create the new observable for item and add as object to appropriate Indicator if child_ind_type == 'DomainName': append_ind = enrich_Domains related_ind = related_Domains new_obj = DomainName() new_obj.value = item #enrich_Domains.add_object(domain_obj) elif child_ind_type == 'Address': append_ind = enrich_IPs related_ind = related_IPs new_obj = Address() new_obj.category = "ipv4-addr" new_obj.address_value = item #enrich_IPs.add_object(ipv4_obj) else: print 'Unsupported indicator type: ' + child_ind_type new_obs = Observable(new_obj) new_obs_ref = new_obs.id_ append_ind.add_observable(new_obs) ref = new_obs_ref #local_index[item][0] = ref set_obs_ref(item, new_obs_ref, local_index) #print 'Adding ref to: ' + ref_obs.id_ + ' of ' + ref ref_obs.description = str(ref_obs.description) + ref.replace("{{no_ref}}","") + ', ' if create_ref_obs: #Add the new ref obs to Related Indicators related_ind.add_observable(ref_obs) #print related_ind.to_xml() create_ref_obs = False related_ind1 = RelatedIndicator(related_IPs, relationship='Source of enrichment for IPs') related_ind2 = RelatedIndicator(related_Domains, relationship='Source of enrichment for Domains') enrich_IPs.related_indicators.append(related_ind1) enrich_Domains.related_indicators.append(related_ind2) new_stix.add_indicator(enrich_IPs) new_stix.add_indicator(enrich_Domains) #new_stix_json = json.loads(new_stix.to_json()) #new_stix_xml = new_stix.to_xml() #if verbose: #print new_stix.to_xml() return new_stix
def csv2stix(outFormat,inFile): #============= # Build package metadata #============= stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = "TG3390" stix_package.stix_header.description = "Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/" marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) stix_package.stix_header.handling = handling #============= # Build package structure #============= ta_tg3390 = ThreatActor(title="TG3390") ta_tg3390.identity = Identity(name="TG3390") attack_pattern = AttackPattern() attack_pattern.description = ("Infrastructure Building") ttp_infrastructure = TTP(title="Infrastructure Building") ttp_infrastructure.behavior = Behavior() ttp_infrastructure.behavior.add_attack_pattern(attack_pattern) ttp_infrastructure.add_intended_effect("Unauthorized Access") infra_domainInd = Indicator(title="Domains associated with TG3390 Infrastructure") infra_domainInd.add_indicator_type("Domain Watchlist") infra_domainInd.confidence = "High" infra_domainInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) infra_IPInd = Indicator(title="[H] IP Addresses associated with TG3390 Infrastructure") infra_IPInd.add_indicator_type("IP Watchlist") infra_IPInd.confidence = "High" infra_IPInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) infra_IPInd_M = Indicator(title="[M] IP Addresses associated with TG3390 Infrastructure") infra_IPInd_M.add_indicator_type("IP Watchlist") infra_IPInd_M.confidence = "Medium" infra_IPInd_M.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_)) httpBrowserObj = MalwareInstance() httpBrowserObj.add_name("HTTP Browser") ttp_httpB = TTP(title="HTTP Browser") ttp_httpB.behavior = Behavior() ttp_httpB.behavior.add_malware_instance(httpBrowserObj) ttp_httpB.add_intended_effect("Theft - Intellectual Property") httpB_hashInd = Indicator(title="File hashes for HTTP Browser") httpB_hashInd.add_indicator_type("File Hash Watchlist") httpB_hashInd.confidence = "High" httpB_hashInd.add_indicated_ttp(TTP(idref=ttp_httpB.id_)) httpBrowserDropperObj = MalwareInstance() httpBrowserDropperObj.add_name("HTTP Browser Dropper") ttp_httpBDpr = TTP(title="HTTP Browser Dropper") ttp_httpBDpr.behavior = Behavior() ttp_httpBDpr.behavior.add_malware_instance(httpBrowserDropperObj) ttp_httpBDpr.add_intended_effect("Theft - Intellectual Property") httpBDpr_hashInd = Indicator(title="File hashes for HTTP Browser Dropper") httpBDpr_hashInd.add_indicator_type("File Hash Watchlist") httpBDpr_hashInd.confidence = "High" httpBDpr_hashInd.add_indicated_ttp(TTP(idref=ttp_httpBDpr.id_)) plugXObj = MalwareInstance() plugXObj.add_name("PlugX Dropper") ttp_plugX = TTP(title="PlugX Dropper") ttp_plugX.behavior = Behavior() ttp_plugX.behavior.add_malware_instance(plugXObj) ttp_plugX.add_intended_effect("Theft - Intellectual Property") plugX_hashInd = Indicator(title="File hashes for PlugX Dropper") plugX_hashInd.add_indicator_type("File Hash Watchlist") plugX_hashInd.confidence = "High" plugX_hashInd.add_indicated_ttp(TTP(idref=ttp_plugX.id_)) #============= # Process content in to structure #============= ip_rules = [] ip_rules_M = [] domain_rules = [] with open(inFile, 'rb') as f: reader = csv.reader(f) for row in reader: obs = row[0] obsType = row[1] description = row[2] confidence = row[3] #print obs,obsType,description,confidence if description == 'TG-3390 infrastructure': if obsType == 'Domain name': domain_obj = DomainName() domain_obj.value = obs #domain_obj.title = description infra_domainInd.add_object(domain_obj) domain_rule = generate_snort([obs], 'DomainName', str(infra_domainInd.id_).split(':',1)[1].split('-',1)[1]) domain_rules.append(domain_rule) elif obsType == 'IP address': ipv4_obj = Address() ipv4_obj.category = "ipv4-addr" ipv4_obj.address_value = obs ipv4_obj.title = description ind_ref = str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1] if confidence == "High": infra_IPInd.add_object(ipv4_obj) ip_rules.append(obs) else: infra_IPInd_M.add_object(ipv4_obj) ip_rules_M.append(obs) else: print "TTP Infra: obsType is wrong" elif description == 'HttpBrowser RAT dropper': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description httpBDpr_hashInd.add_observable(file_obj) elif description == 'HttpBrowser RAT': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description httpB_hashInd.add_observable(file_obj) elif description == 'PlugX RAT dropper': file_obj = File() file_obj.add_hash(Hash(obs)) file_obj.title = description plugX_hashInd.add_observable(file_obj) else: print "TTP not found" #print ip_rules ip_rule = generate_snort(ip_rules, 'Address', str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1]) ip_rule_M = generate_snort(ip_rules_M, 'Address', str(infra_IPInd_M.id_).split(':',1)[1].split('-',1)[1]) ip_tm = SnortTestMechanism() ip_tm.rules = [ip_rule] ip_tm.efficacy = "High" ip_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_IPInd.test_mechanisms = [ip_tm] ip_M_tm = SnortTestMechanism() ip_M_tm.rules = [ip_rule_M] ip_M_tm.efficacy = "Medium" ip_M_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_IPInd_M.test_mechanisms = [ip_M_tm] domain_tm = SnortTestMechanism() domain_tm.rules = domain_rules domain_tm.efficacy = "High" domain_tm.producer = InformationSource(identity=Identity(name="Auto")) infra_domainInd.test_mechanisms = [domain_tm] #============= # Add the composed content to the structure #============= stix_package.add_indicator(infra_domainInd) stix_package.add_indicator(infra_IPInd) stix_package.add_indicator(infra_IPInd_M) stix_package.add_indicator(httpBDpr_hashInd) stix_package.add_indicator(httpB_hashInd) stix_package.add_indicator(plugX_hashInd) stix_package.add_ttp(ttp_infrastructure) stix_package.add_ttp(ttp_httpB) stix_package.add_ttp(ttp_httpBDpr) stix_package.add_ttp(ttp_plugX) """ if outFormat =='dict': print stix_package.to_dict() if outFormat =='json': parsed = stix_package.to_json() jsonpkg = json.loads(parsed) pprint.pprint(jsonpkg) if outFormat =='stix': print stix_package.to_xml() """ #if verbose: #print stix_package.to_xml() #pprint(stix_package.to_json()) return stix_package
from cybox.common import Hash from cybox.objects.uri_object import URI from cybox.objects.win_registry_key_object import WinRegistryKey #from cybox.objects.domain_name_object import DomainName OUTPUT_FORMATS = ('csv', 'json', 'yara', 'autofocus', 'stix') #NAMESPACE = {"http://www.cert.gov.uk" : "certuk"} NAMESPACE = Namespace("http://www.cert.gov.uk", "certuk") set_id_namespace(NAMESPACE) stix_package = STIXPackage() add_ind_list = [] ind_ip = Indicator() ind_ip.add_indicator_type("IP Watchlist") ind_file = Indicator() ind_file.add_indicator_type("File Hash Watchlist") ind_url = Indicator() ind_url.add_indicator_type("URL Watchlist") ind_domain = Indicator() ind_domain.add_indicator_type("Domain Watchlist") ind_email = Indicator() ind_email.add_indicator_type("Malicious E-mail") ind_registrykey = Indicator() ind_registrykey.add_indicator_type("Host Characteristics")
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 _dostix(hashes): '''This function creates a STIX packages containing hashes.''' print("[+] Creating STIX Package") title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now()) _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix']) stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = title stix_package.stix_header.handling = _marking() try: indicator = Indicator() indicator.set_producer_identity(SETTINGS['stix']['producer']) indicator.set_produced_time(indicator.timestamp) indicator.set_received_time(indicator.timestamp) indicator.add_kill_chain_phase(PHASE_DELIVERY) indicator.confidence = "Low" indicator.title = title indicator.add_indicator_type("File Hash Watchlist") indicator.description = SETTINGS['stix']['ind_desc'] try: indicator.add_indicated_ttp( TTP(idref=SETTINGS['indicated_ttp'], timestamp=indicator.timestamp)) indicator.suggested_coas.append( CourseOfAction( idref=SETTINGS['suggested_coa'], timestamp=indicator.timestamp)) except KeyError: pass for info in hashes: try: file_name = info['filename'] file_object = File() file_object.file_name = file_name file_object.file_name.condition = "Equals" file_object.file_extension = "." + file_name.split('.')[-1] file_object.file_extension.condition = "Equals" file_object.size_in_bytes = info['filesize'] file_object.size_in_bytes.condition = "Equals" file_object.file_format = info['fileformat'] file_object.file_format.condition = "Equals" file_object.add_hash(Hash(info['md5'])) file_object.add_hash(Hash(info['sha1'])) file_object.add_hash(Hash(info['sha256'])) file_object.add_hash(Hash(info['sha512'])) file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP)) for hashobj in file_object.hashes: hashobj.simple_hash_value.condition = "Equals" hashobj.type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + file_name indicator.add_observable(file_obs) except TypeError: pass stix_package.add_indicator(indicator) return stix_package except KeyError: pass
def main(): # NOTE: ID values will differ due to being regenerated on each script execution pkg1 = STIXPackage() pkg1.title = "Example of Indicator Composition for an aggregate indicator composition" # USE CASE: Indicator with aggregate pattern # Add TTP for malware usage malware_ttp = TTP() malware_ttp.behavior = Behavior() malware = MalwareInstance() malware.title = "foobar malware" malware.add_type("Remote Access Trojan") malware_ttp.behavior.add_malware_instance(malware) c2_ttp = TTP() c2_ttp.resources = Resource() c2_ttp.resources.infrastructure = Infrastructure() c2_ttp.resources.infrastructure.add_type(VocabString("Malware C2")) pkg1.add_ttp(c2_ttp) pkg1.add_ttp(malware_ttp) nw_ind = Indicator() nw_ind.description = "Indicator for a particular C2 infstructure IP address." # add network network connection to this indicator obs = NetworkConnection() sock = SocketAddress() sock.ip_address = "46.123.99.25" sock.ip_address.category = "ipv4-addr" sock.ip_address.condition = "Equals" obs.destination_socket_address = sock nw_ind.add_observable(obs) nw_ind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) # create File Hash indicator w/ embedded Observable file_ind = Indicator() file_ind.description = "Indicator for the hash of the foobar malware." file_ind.add_indicator_type("File Hash Watchlist") file_obs = File() file_obs.add_hash("01234567890abcdef01234567890abcdef") file_obs.hashes[0].type_ = "MD5" file_obs.hashes[0].type_.condition = "Equals" file_ind.add_observable(file_obs) # create references file_ind.add_indicated_ttp(TTP(idref=malware_ttp.id_)) # create container indicator ind = Indicator() ind.add_indicator_type(VocabString("Campaign Characteristics")) ind.description = "Indicator for a composite of characteristics for the use of specific malware and C2 infrastructure within a Campaign." # Add campaign with related camp = Campaign() camp.title = "holy grail" pkg1.add_campaign(camp) camp.related_ttps.append(TTP(idref=c2_ttp.id_)) camp.related_ttps.append(TTP(idref=malware_ttp.id_)) # Add threat actor ta = ThreatActor() ta.identity = Identity() ta.identity.name = "boobear" ta.observed_ttps.append(TTP(idref=malware_ttp.id_)) pkg1.add_threat_actor(ta) # Create composite expression ind.composite_indicator_expression = CompositeIndicatorExpression() ind.composite_indicator_expression.operator = "AND" ind.composite_indicator_expression.append(file_ind) ind.composite_indicator_expression.append(nw_ind) pkg1.add_indicator(ind) print pkg1.to_xml() # USE CASE: Indicator with partial matching pkg2 = STIXPackage() pkg2.title = "Example of Indicator Composition for a one of many indicator composition" # create container indicator watchlistind = Indicator() watchlistind.add_indicator_type("IP Watchlist") watchlistind.description = "This Indicator specifies a pattern where any one or more of a set of three IP addresses are observed." watchlistind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) # Create composite expression watchlistind.composite_indicator_expression = CompositeIndicatorExpression() watchlistind.composite_indicator_expression.operator = "OR" ips = ['23.5.111.68', '23.5.111.99', '46.123.99.25'] for ip in ips: new_ind = Indicator() new_ind.description = "This Indicator specifies a pattern where one specific IP address is observed" # add network network connection to this indicator obs = Address() obs.address_value = ip obs.address_value.condition = "Equals" new_ind.add_observable(obs) new_ind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) watchlistind.composite_indicator_expression.append(new_ind) pkg2.add_indicator(watchlistind) print pkg2.to_xml() # USE CASE: Indicator with compound detection pkg3 = STIXPackage() pkg3.title = "Example of Indicator Composition for compound detection" # create container indicator watchlistind2 = Indicator() watchlistind2.add_indicator_type("IP Watchlist") watchlistind2.description = "This Indicator specifies a composite condition of two preexisting Indicators (each identifying a particular TTP with low confidence) that in aggregate identify the particular TTP with high confidence." # Create composite expression watchlistind2.composite_indicator_expression = CompositeIndicatorExpression() watchlistind2.composite_indicator_expression.operator = "OR" watchlistind2.add_indicated_ttp(TTP(idref=c2_ttp.id_)) watchlistind2.confidence = "High" nw_ind.description = "Indicator for a particular C2 IP address used by a malware variant." nw_ind.confidence = "Low" nw_ind.indicator_types = ["C2"] file_ind.description = "Indicator that contains malicious file hashes for a particular malware variant." file_ind.confidence = "Low" watchlistind2.composite_indicator_expression.append(nw_ind) watchlistind2.composite_indicator_expression.append(file_ind) pkg3.add_indicator(watchlistind2) print pkg3.to_xml()
def adptr_dict2STIX(srcObj, data): sTxt = "Called... " sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()') stixObj = None ### Input Check if srcObj == None or data == None: #TODO: Needs error msg: Missing srcData Object return (False) ### Generate NameSpace id tags STIX_NAMESPACE = {"http://hailataxii.com": "opensource"} OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource") stix_set_id_namespace(STIX_NAMESPACE) obs_set_id_namespace(OBS_NAMESPACE) ### Building STIX Wrapper stix_package = STIXPackage() objIndicator = Indicator() ### Bulid Object Data for sKey in data: objIndicator = Indicator() listOBS = [] 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 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() # if 'indicator' in data[sKey]['meta']['IDs']: # objIndicator.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({objIndicator.id_:'indicator'}) listOBS = [] ### Parsing IP Address sAddr = data[sKey]['attrib']['IP Address'] if sAddr: 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) # if 'address"' in data[sKey]['meta']['IDs']: # obsAddr.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({objIndicator.id_:'address'}) 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']['Hostname'] if sDomain: 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) # if 'domain' in data[sKey]['meta']['IDs']: # obsDomain.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({obsDomain.id_:'domain'}) 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") ### Parsing Port Number sPortList = data[sKey]['attrib']['Ports'] for item in sPortList: if sPortList[item]: objPort = Port() sPort = sPortList[item] objPort.port_value = int(sPort) objPort.port_value.condition = 'Equals' objPort.layer4_protocol = 'TCP' obsPort = Observable(objPort) objPort = None obsPort.sighting_count = 1 obsPort.title = 'Port: ' + str(sPort) sDscrpt = 'PortNumber: ' + str(sPort) + " | " sDscrpt += "Protocol: TCP | " obsPort.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsPort) ### 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']) objIndicator.producer = infoSrc # if data[sKey]['attrib']['lstDateVF']: # objIndicator.set_produced_time(data[sKey]['attrib']['lstDateVF'][0]); objIndicator.set_received_time(data[sKey]['meta']['dateDL']) ### Generate Indicator Title based on availbe data lstContainng = [] lstIs = [] sTitle = ' This' if data[sKey]['attrib']['Hostname']: sTitle += ' domain ' + data[sKey]['attrib']['Hostname'] else: sTitle += ' ipAddress ' + sKey sTitle += ' has been identified as a TOR network "Exit Point" router' objIndicator.title = sTitle ### Generate Indicator Description based on availbe data sDscrpt = ' torstatus.blutmagie.de has identified this' if data[sKey]['attrib']['Hostname']: sDscrpt += ' domain ' + data[sKey]['attrib']['Hostname'] else: sDscrpt += ' ipAddress ' + sKey # sDscrpt += ' with a router name of "' + data[sKey]['attrib']['Router Name'] + '"' # if data[sKey]['attrib']['Ports']['ORPort']: # sDscrpt += ' using ORPort: ' + str(data[sKey]['attrib']['Ports']['ORPort']) # if data[sKey]['attrib']['Ports']['DirPort']: # sDscrpt += ' and DirPort: ' + str(data[sKey]['attrib']['Ports']['DirPort']) sDscrpt += ' as a TOR network "Exit Point" router' if data[sKey]['attrib']['Country Code']: sCntry_code = data[sKey]['attrib']['Country Code'] if sCntry_code in dictCC2CN: sCntry_name = dictCC2CN[sCntry_code] sDscrpt += ', which appears to be located in ' + sCntry_name sDscrpt += '. \n\n RawData: ' + str(data[sKey]['attrib']) 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) # locDataFile = 'db_' + srcObj.fileName.split('.')[0] + '.json' # sndFile_Dict2JSON(data,locDataFile); # data = None return (stix_package)
def json2indicator(config, src, dest, endpoint, json_, crits_id): '''transform crits indicators into stix indicators with embedded cybox observable composition''' try: set_id_method(IDGenerator.METHOD_UUID) xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name'] set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) if endpoint == 'indicators': endpoint_trans = {'Email': 'emails', 'IP': 'ips', 'Sample': 'samples', 'Domain': 'domains', 'Indicator': 'indicators', 'Event': 'events'} if json_.get('type', None) not in ['Reference', 'Related_To']: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type='indicator type ' + json_.get('type', 'None'), id_=crits_id)) return(None) indicator_ = Indicator() indicator_.id = xmlns_name + ':indicator-' + crits_id indicator_.id_ = indicator_.id indicator_.title = json_['value'] indicator_.confidence = json_['confidence']['rating'].capitalize() indicator_.add_indicator_type('Malware Artifacts') observable_composition_ = ObservableComposition() observable_composition_.operator = \ indicator_.observable_composition_operator for r in json_['relationships']: if r.get('relationship', None) not in ['Contains', 'Related_To']: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type='indicator relationship type ' + r.get('relationship', 'None'), id_=crits_id)) continue if r['type'] in ['Sample', 'Email', 'IP', 'Sample', 'Domain']: observable_ = Observable() observable_.idref = xmlns_name + ':observable-' + r['value'] observable_composition_.add(observable_) elif r['type'] == 'Indicator': related_indicator = RelatedIndicator(Indicator(idref=xmlns_name + ':indicator-' + r['value'])) indicator_.related_indicators.append(related_indicator) # stix indicators don't support related_incident :-( # elif r['type'] == 'Event': # related_incident = RelatedIncident(Incident(idref=xmlns_name + ':incident-' + r['value'])) # indicator_.related_incidents.append(related_incident) indicator_.observable = Observable() indicator_.observable.observable_composition = \ observable_composition_ return(indicator_) else: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type=endpoint, id_=crits_id)) return(None) except: e = sys.exc_info()[0] config['logger'].error(log.log_messages['obj_convert_error'].format( src_type='crits', src_obj='indicator', id_=crits_id, dest_type='stix', dest_obj='indicator')) config['logger'].exception(e) return(None)
def main(): ###################################################################### # MODIFICARE LE VARIABILI SEGUENTI MyTITLE = "APT28 / Fancy Bear" DESCRIPTION = "Emanuele De Lucia - APT28 / Fancy Bear still targeting military institutions - https://www.emanueledelucia.net/apt28-targeting-military-institutions/" sha256 = [] md5 = [ '43D7FFD611932CF51D7150B176ECFC29', '549726B8BFB1919A343AC764D48FDC81' ] sha1 = [] domains = ['beatguitar.com'] urls = [ 'https://beatguitar.com/aadv/gJNn/X2/ep/VQOA/3.SMPTE292M/?ct=+lMQKtXi0kf+3MVk38U=', 'https://beatguitar.com/n2qqSy/HPSe0/SY/yAsFy8/mSaYZP/lw.sip/?n=VxL0BnijNmtTnSFIcoQ=' ] ips = ['185.99.133.72'] emails = [] ###################################################################### # Costruzione STIX file 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() info_src = InformationSource() info_src.identity = Identity(name="CyberSaiyan Community") 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, description=DESCRIPTION, short_description=SHORT) wrapper.stix_header.handling = handling # HASH indicators indicatorHASH = Indicator() indicatorHASH.title = MyTITLE + " - HASH" indicatorHASH.add_indicator_type("File Hash Watchlist") for idx, sha256 in enumerate(sha256): filei = File() filei.add_hash(Hash(sha256)) obsi = Observable(filei) indicatorHASH.add_observable(obsi) for idx, md5 in enumerate(md5): filej = File() filej.add_hash(Hash(md5)) obsj = Observable(filej) indicatorHASH.add_observable(obsj) for idx, sha1 in enumerate(sha1): filek = File() filek.add_hash(Hash(sha1)) obsk = Observable(filek) indicatorHASH.add_observable(obsk) # DOMAIN indicators indiDOMAIN = Indicator() indiDOMAIN.title = MyTITLE + " - DOMAIN" indiDOMAIN.add_indicator_type("Domain Watchlist") for idu, domains in enumerate(domains): url = URI() url.value = domains url.type_ = URI.TYPE_DOMAIN url.condition = "Equals" obsu = Observable(url) indiDOMAIN.add_observable(obsu) # URL indicators indiURL = Indicator() indiURL.title = MyTITLE + " - URL" indiURL.add_indicator_type("URL Watchlist") for idu, urls in enumerate(urls): url = URI() url.value = urls url.type_ = URI.TYPE_URL url.condition = "Equals" obsu = Observable(url) indiURL.add_observable(obsu) # IP indicators indiIP = Indicator() indiIP.title = MyTITLE + " - IP" indiIP.add_indicator_type("IP Watchlist") for idu, ips in enumerate(ips): ip = Address() ip.address_value = ips obsu = Observable(ip) indiIP.add_observable(obsu) # EMAIL indicators indiEMAIL = Indicator() indiEMAIL.title = MyTITLE + " - EMAIL" indiEMAIL.add_indicator_type("Malicious E-mail") for idu, emails in enumerate(emails): email = EmailAddress() email.address_value = emails obsu = Observable(email) indiEMAIL.add_observable(obsu) # add all indicators wrapper.add_indicator(indicatorHASH) wrapper.add_indicator(indiDOMAIN) wrapper.add_indicator(indiURL) wrapper.add_indicator(indiIP) wrapper.add_indicator(indiEMAIL) print(wrapper.to_xml())
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 = [] 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)
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 main(iocs=iocs): stix_header = STIXHeader(title=iocs['title'], description=iocs['desc'], package_intents=["Indicators - Watchlist"]) stix_package = STIXPackage(stix_header=stix_header) # add indicator - file hash if iocs.get('hash'): indicator_file_hash = Indicator(title="Malicious File") indicator_file_hash.add_indicator_type("File Hash Watchlist") for file_hash in iocs['hash']: file_object = File() file_object.add_hash(Hash(file_hash)) file_object.hashes[0].simple_hash_value.condition = "Equals" file_object.hashes[0].type_.condition = "Equals" indicator_file_hash.add_observable(file_object) stix_package.add_indicator(indicator_file_hash) # add indicator - file name if iocs.get('fname'): indicator_filename = Indicator(title="Malicious File Name") for file in iocs['fname']: file_object = File() file_object.file_name = file indicator_filename.add_observable(file_object) stix_package.add_indicator(indicator_filename) # add indicator - ip address if iocs.get('ips'): indicator_ip = Indicator(title="Malicious IP Address") indicator_ip.add_indicator_type("IP Watchlist") for ip in iocs['ips']: addr = Address(address_value=ip, category=Address.CAT_IPV4) addr.condition = "Equals" indicator_ip.add_observable(addr) stix_package.add_indicator(indicator_ip) # add indicator - domains if iocs.get('domains'): indicator_domains = Indicator(title="Malicious Domains") indicator_domains.add_indicator_type("Domain Watchlist") for domain in iocs['domains']: domain_name = DomainName() domain_name.value = domain indicator_domains.add_observable(domain_name) stix_package.add_indicator(indicator_domains) # add indicator - url if iocs.get('urls'): indicator_url = Indicator(title='Malicious URL') indicator_url.add_indicator_type("URL Watchlist") for _url in iocs['urls']: url = URI() url.value = _url url.type_ = URI.TYPE_URL url.value.condition = "Equals" # url.value.condition = "Contains" indicator_url.add_observable(url) stix_package.add_indicator(indicator_url) # add indicator - email subject if iocs.get('subject'): indicator_email_subject = Indicator(title='Malicious E-mail Subject') indicator_email_subject.add_indicator_type("Malicious E-mail") for subject in iocs['subject']: email_subject_object = EmailMessage() email_subject_object.header = EmailHeader() email_subject_object.header.subject = subject email_subject_object.header.subject.condition = "StartsWith" indicator_email_subject.add_observable(email_subject_object) stix_package.add_indicator(indicator_email_subject) # add indicator - email sender if iocs.get('senders'): indicator_email_sender = Indicator(title='Malicious E-mail Sender') indicator_email_sender.add_indicator_type("Malicious E-mail") for sender in iocs['senders']: email_sender_object = EmailMessage() email_sender_object.header = EmailHeader() email_sender_object.header.sender = sender email_sender_object.header.sender.condition = "Equals" indicator_email_sender.add_observable(email_sender_object) stix_package.add_indicator(indicator_email_sender) # print(stix_package.to_xml(encoding=None)) # print(type(stix_package.to_xml(encoding=None))) return stix_package.to_xml(encoding=None)