def main(): # Create our CybOX Simple Hash Value shv = Hash() shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F" # Create a CybOX File Object and add the Hash we created above. f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) # Create the STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader() stix_header.description = "Simple File Hash Observable Example" stix_package.stix_header = stix_header # Add the File Hash Observable to the STIX Package. The add() method will # inspect the input and add it to the top-level stix_package.observables # collection. stix_package.add(f) # Print the XML! print(stix_package.to_xml())
def _md5(keypair): shv = Hash() shv.simple_hash_value = keypair.get('observable') f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) return f
def _sha256(keypair): shv = Hash() shv.simple_hash_value = keypair.get('observable') f = File() h = Hash(shv, Hash.TYPE_SHA256) f.add_hash(h) return f
def _sha1(keypair): shv = Hash() shv.simple_hash_value = keypair.get('indicator') f = File() h = Hash(shv, Hash.TYPE_SHA1) f.add_hash(h) return f
def test_add_vocabstring(self): from cybox.common import Hash from cybox.common.vocabs import ActionName action = ActionName(ActionName.TERM_ADD_USER) h = Hash() h.type_ = action self.assertEqual(action, h.type_)
def main(): shv = Hash() shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F" f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example 03" stix_package.stix_header = stix_header stix_package.add_observable(f) print(stix_package.to_xml())
def from_dict(stream_dict): if not stream_dict: return None stream_ = Stream() for hash_ in stream_dict.get('hashes',[]): stream_.add(Hash.from_dict(hash_)) stream_.name = String.from_dict(stream_dict.get('name')) stream_.size_in_bytes = UnsignedLong.from_dict(stream_dict.get('size_in_bytes')) return stream_
def from_obj(stream_obj): if not stream_obj: return None stream_ = Stream() for hash_ in stream_obj.get_Hash(): stream_.add(Hash.from_obj(hash_)) stream_.name = String.from_obj(stream_dict.get('name')) stream_.size_in_bytes = UnsignedLong.from_obj(stream_dict.get('size_in_bytes')) return stream_
def main(): shv = Hash() shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F" f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now()) indicator.add_object(f) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example 02" stix_package.stix_header = stix_header stix_package.add_indicator(indicator) print(stix_package.to_xml())
def test_autotype(self): h = Hash() h.simple_hash_value = "0123456789abcdef0123456789abcdef" self.assertEqual(h.type_, Hash.TYPE_MD5) h.type_ = Hash.TYPE_OTHER self.assertEqual(h.type_, Hash.TYPE_OTHER) h.simple_hash_value = "0123456789abcdef0123456789abcdef" self.assertEqual(h.type_, Hash.TYPE_OTHER) h2 = Hash() h2.type_ = Hash.TYPE_OTHER h2.simple_hash_value = "0123456789abcdef0123456789abcdef" self.assertEqual(h2.type_, Hash.TYPE_OTHER)
def print_match(self, fpath, page, name, match): # Resolve all hashes to single HASH reference to avoid repetition if name == "MD5" or name == "SHA1" or name == "SHA256": name = "HASH" if name in ind_dict: indicator = ind_dict[name] add_ind_list.append(name) indicator.title = fpath # =========== # Add new object handlers here: if name == "IP": new_obj = Address(address_value=match, category=Address.CAT_IPV4) elif name == "HASH": new_obj = File() new_obj.add_hash(Hash(match)) elif name == "URL": new_obj = URI(type_=URI.TYPE_URL, value=match) elif name == "Host": new_obj = URI(type_=URI.TYPE_DOMAIN, value=match) elif name == "Email": new_obj = Address( address_value=match, category=Address.CAT_EMAIL ) ## Not sure if this is right - should this be using the email_message_object? elif name == "Registry": new_obj = WinRegistryKey(values=match) # =========== new_obs = Observable(new_obj) new_obs.title = "Page Ref: " + str(page) indicator.add_observable(new_obs)
def test_add_bad_value(self): from cybox.common import Hash h = Hash() self.assertRaises(ValueError, setattr, h, 'type_', "BAD VALUE")
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 json2observable(config, src, dest, endpoint, json_, crits_id): # TODO split into smaller functions '''transform crits observables into cybox''' 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 == 'ips': crits_types = { 'Address - cidr': 'cidr', 'Address - ipv4-addr': 'ipv4-addr', 'Address - ipv4-net': 'ipv4-net', 'Address - ipv4-net-mask': 'ipv4-netmask', 'Address - ipv6-addr': 'ipv6-addr', 'Address - ipv6-net': 'ipv6-net', 'Address - ipv6-net-mask': 'ipv6-netmask' } addr = Address(address_value=json_['ip'], category=crits_types[json_['type']]) addr.condition = 'Equals' observable_ = Observable(addr) elif endpoint == 'domains': domain = DomainName() domain.type_ = 'FQDN' domain.value = json_['domain'] domain.condition = 'Equals' observable_ = Observable(domain) elif endpoint == 'samples': crits_types = { 'md5': 'MD5', 'sha1': 'SHA1', 'sha224': 'SHA224', 'sha256': 'SHA256', 'sha384': 'SHA384', 'sha512': 'SHA512', 'ssdeep': 'SSDEEP' } file_object = File() file_object.file_name = json_['filename'] for hash in crits_types.keys(): if hash in json_: file_object.add_hash( Hash(json_[hash], type_=crits_types[hash])) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" observable_ = Observable(file_object) elif endpoint == 'emails': crits_types = { 'subject': 'subject', 'to': 'to', 'cc': 'cc', 'from_address': 'from_', 'sender': 'sender', 'date': 'date', 'message_id': 'message_id', 'reply_to': 'reply_to', 'boundary': 'boundary', 'x_mailer': 'x_mailer', 'x_originating_ip': 'x_originating_ip' } email = EmailMessage() email.header = EmailHeader() for k in crits_types.keys(): val = json_.get(k, None) if val: email.header.__setattr__(crits_types[k], val) email.header.__getattribute__(crits_types[k]).condition = \ 'Equals' observable_ = Observable(email) else: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type=endpoint, id_=crits_id)) return (None) observable_.id = xmlns_name + ':observable-' + crits_id observable_.id_ = observable_.id return (observable_) except: e = sys.exc_info()[0] config['logger'].error(log.log_messages['obj_convert_error'].format( src_type='crits', src_obj='observable', id_=crits_id, dest_type='cybox', dest_obj='observable')) config['logger'].exception(e) return (None)
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)
def test_round_trip2(self): hash_dict = {'simple_hash_value': EMPTY_MD5, 'type': Hash.TYPE_MD5} hash_obj = Hash.object_from_dict(hash_dict) hash_dict2 = Hash.dict_from_object(hash_obj) self.assertEqual(hash_dict, hash_dict2)
def build(self): """Define the STIX report.""" self.stix_header.title = self.pulse["name"] self.stix_header.description = self.pulse["description"] self.stix_header.package_intents = "Indicators" self.stix_header.information_source = InformationSource() self.stix_header.information_source.time = Time() self.stix_header.information_source.time.received_time = self.pulse[ "modified"] self.stix_header.information_source.time.produced_time = self.stix_package.timestamp self.stix_header.information_source.identity = Identity() self.stix_header.information_source.identity.name = IDENTITY_NAME # self.stix_package.stix_header = self.stix_header # self.stix_package.stix_header.handling = self._marking() # self.report = Report() # self.report.header = Header() # self.report.header.title = self.pulse["name"] # self.report.header.descriptions = self.pulse["description"] # self.report.header.intents = "Indicators" # self.report.header.short_description = "%spulse/%s" % ( # PULSE_SERVER_BASE, str(self.pulse["id"])) # self.report.header.information_source = InformationSource() # self.report.header.information_source.time = Time() # self.report.header.information_source.time.received_time = self.pulse[ # "modified"] # self.report.header.information_source.time.produced_time = self.report.timestamp # self.report.header.information_source.identity = Identity() # self.report.header.information_source.identity.name = IDENTITY_NAME hashes = False addresses = False emails = False domains = False urls = False mutex = False hash_indicator = Indicator() hash_indicator.set_producer_identity(IDENTITY_NAME) hash_indicator.set_produced_time(hash_indicator.timestamp) hash_indicator.set_received_time(self.pulse["modified"]) hash_indicator.title = "[OTX] [Files] " + self.pulse["name"] hash_indicator.add_indicator_type("File Hash Watchlist") hash_indicator.confidence = "Low" address_indicator = Indicator() address_indicator.set_producer_identity(IDENTITY_NAME) address_indicator.set_produced_time(address_indicator.timestamp) address_indicator.set_received_time(self.pulse["modified"]) address_indicator.title = "[OTX] [IP] " + self.pulse["name"] address_indicator.add_indicator_type("IP Watchlist") address_indicator.confidence = "Low" domain_indicator = Indicator() domain_indicator.set_producer_identity(IDENTITY_NAME) domain_indicator.set_produced_time(domain_indicator.timestamp) domain_indicator.set_received_time(self.pulse["modified"]) domain_indicator.title = "[OTX] [Domain] " + self.pulse["name"] domain_indicator.add_indicator_type("Domain Watchlist") domain_indicator.confidence = "Low" url_indicator = Indicator() url_indicator.set_producer_identity(IDENTITY_NAME) url_indicator.set_produced_time(url_indicator.timestamp) url_indicator.set_received_time(self.pulse["modified"]) url_indicator.title = "[OTX] [URL] " + self.pulse["name"] url_indicator.add_indicator_type("URL Watchlist") url_indicator.confidence = "Low" email_indicator = Indicator() email_indicator.set_producer_identity(IDENTITY_NAME) email_indicator.set_produced_time(email_indicator.timestamp) email_indicator.set_received_time(self.pulse["modified"]) email_indicator.title = "[OTX] [Email] " + self.pulse["name"] email_indicator.add_indicator_type("Malicious E-mail") email_indicator.confidence = "Low" mutex_indicator = Indicator() mutex_indicator.set_producer_identity(IDENTITY_NAME) mutex_indicator.set_produced_time(mutex_indicator.timestamp) mutex_indicator.set_received_time(self.pulse["modified"]) mutex_indicator.title = "[OTX] [Mutex] " + self.pulse["name"] mutex_indicator.add_indicator_type("Malware Artifacts") mutex_indicator.confidence = "Low" for p_indicator in self.pulse["indicators"]: if p_indicator["type"] in self.hash_translation: file_object = File() file_object.add_hash(Hash(p_indicator["indicator"])) file_object.hashes[0].simple_hash_value.condition = "Equals" file_object.hashes[0].type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + \ str(file_object.hashes[0].type_) + \ " - " + p_indicator["indicator"] hash_indicator.add_observable(file_obs) try: hash_indicator.description = p_indicator["description"] except KeyError: hash_indicator.description = "" hashes = True elif p_indicator["type"] in self.address_translation: ip = Address() ip.address_value = p_indicator["indicator"] ip.category = self.address_translation[p_indicator["type"]] ip.address_value.condition = "Equals" ip_obs = Observable(ip) ip_obs.title = "Address: " + str(ip.address_value) address_indicator.add_observable(ip_obs) try: address_indicator.description = p_indicator["description"] except KeyError: address_indicator.description = "" addresses = True elif p_indicator["type"] in self.name_translation: domain = DomainName() domain.value = p_indicator["indicator"] domain.type_ = "FQDN" domain.value.condition = "Equals" domain_obs = Observable(domain) domain_obs.title = "Domain: " + str(domain.value) domain_indicator.add_observable(domain_obs) try: domain_indicator.description = p_indicator["description"] except KeyError: domain_indicator.description = "" domains = True elif p_indicator["type"] == "URL": url = URI() url.value = p_indicator["indicator"] url.type_ = URI.TYPE_URL url.value.condition = "Equals" url_obs = Observable(url) url_obs.title = "URI: " + str(url.value) url_indicator.add_observable(url_obs) try: url_indicator.description = p_indicator["description"] except KeyError: url_indicator.description = "" urls = True elif p_indicator["type"] == "email": email = Address() email.address_value = p_indicator["indicator"] email.category = "e-mail" email.address_value.condition = "Equals" email_obs = Observable(email) email_obs.title = "Address: " + str(email.address_value) email_indicator.add_observable(email_obs) try: email_indicator.description = p_indicator["indicator"] except KeyError: email_indicator.description = "" emails = True elif p_indicator["type"] == "Mutex": mutex = Mutex() mutex.name = p_indicator["indicator"] mutex.named = True mutex_obs = Observable(mutex) mutex_obs.title = "Mutex: " + str(mutex.name) mutex_indicator.add_observable(mutex_obs) try: mutex_indicator.description = p_indicator["indicator"] except KeyError: mutex_indicator.description = "" mutex = True else: continue if hashes: self.stix_package.add_indicator(hash_indicator) if addresses: self.stix_package.add_indicator(address_indicator) if domains: self.stix_package.add_indicator(domain_indicator) if urls: self.stix_package.add_indicator(url_indicator) if emails: self.stix_package.add_indicator(email_indicator) if mutex: self.stix_package.add_indicator(mutex_indicator)
from maec.bundle import Bundle, MalwareAction, Capability from maec.package import Analysis, MalwareSubject, Package # Instantiate the Bundle, Package, MalwareSubject, and Analysis classes bundle = Bundle(defined_subject=False) package = Package() subject = MalwareSubject() analysis = Analysis() # Create the Object for use in the Malware Instance Object Attributes subject_object = Object() subject_object.properties = File() subject_object.properties.name = 'foobar.exe' subject_object.properties.size_in_bytes = '35532' subject_object.properties.hashes = HashList() subject_object.properties.hashes.append( Hash("8743b52063cd84097a65d1633f5c74f5")) # Set the Malware Instance Object Attributes with an Object constructed from the dictionary subject.set_malware_instance_object_attributes(subject_object) # Create the Associated Object Dictionary for use in the Action associated_object = AssociatedObject() associated_object.properties = File() associated_object.properties.file_name = 'abcd.dll' associated_object.properties.size_in_bytes = '123456' associated_object.association_type = VocabString() associated_object.association_type.value = 'output' associated_object.association_type.xsi_type = 'maecVocabs:ActionObjectAssociationTypeVocab-1.0' # Create the Action from another dictionary action = MalwareAction() action.name = VocabString() action.name.value = 'create file' action.name.xsi_type = 'maecVocabs:FileActionNameVocab-1.0'
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 gen_stix_observable_sample(config, target=None, datatype=None, title='random test data', description='random test data', package_intents='Indicators - Watchlist', tlp_color='WHITE'): '''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) # ...and stuff it full of random sample data :-) if datatype == 'ip': addr = Address(address_value=datagen.generate_random_ip_address(), category='ipv4-addr') addr.condition = 'Equals' stix_package.add_observable(Observable(addr)) elif datatype == 'domain': domain = DomainName() domain.type_ = 'FQDN' domain.value = datagen.generate_random_domain(config) domain.condition = 'Equals' stix_package.add_observable(Observable(domain)) elif datatype == 'filehash': file_object = File() file_object.file_name = str(uuid.uuid4()) + '.exe' hashes = datagen.generate_random_hashes() for hash in hashes.keys(): file_object.add_hash(Hash(hashes[hash], type_=hash.upper())) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" stix_package.add_observable(Observable(file_object)) elif datatype == 'email': try: msg = datagen.get_random_spam_msg(config) email = EmailMessage() email.header = EmailHeader() header_map = { 'Subject': 'subject', 'To': 'to', 'Cc': 'cc', 'Bcc': 'bcc', 'From': 'from_', 'Sender': 'sender', 'Date': 'date', 'Message-ID': 'message_id', 'Reply-To': 'reply_to', 'In-Reply-To': 'in_reply_to', 'Content-Type': 'content_type', 'Errors-To': 'errors_to', 'Precedence': 'precedence', 'Boundary': 'boundary', 'MIME-Version': 'mime_version', 'X-Mailer': 'x_mailer', 'User-Agent': 'user_agent', 'X-Originating-IP': 'x_originating_ip', 'X-Priority': 'x_priority' } # TODO handle received_lines for key in header_map.keys(): val = msg.get(key, None) if val: email.header.__setattr__(header_map[key], val) email.header.__getattribute__(header_map[key]).condition = \ 'Equals' # TODO handle email bodies (it's mostly all there except for # handling weird text encoding problems that were making # libcybox stacktrace) # body = get_email_payload(random_spam_msg) # if body: # email.raw_body = body stix_package.add_observable(Observable(email)) except: return (None) observable_id = stix_package.observables.observables[0].id_ return (observable_id, stix_package)
def main(): # "hardcoded" values ns = "urn:example.com:marks_malware_metadata_mart" ns_alias = "m4" # Set the STIX ID Namespace stix_namespace = {ns: ns_alias} stix_sin(stix_namespace) # Set the CybOX ID Namespace cybox_namespace = Namespace(ns, ns_alias) cybox_sin(cybox_namespace) ttp_id = 'ttp-d539bb85-9363-4814-83c8-fa9975045686' ttp_timestamp = '2014-09-30T15:56:27.000000+00:00' # Fake database values md5_hash = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' object_id = 'File-927731f2-cc2c-421c-a40e-dc6f4a6c75a4' observable_id = 'Observable-45e3e64c-8438-441e-bc49-51e417466e29' confidence = 'High' confidence_timestamp = '2014-09-29T14:32:00.000000' indicator_id = 'Indicator-54baefc1-4742-4b40-ba83-afd51115015b' indicator_timestamp = '2014-09-29T14:32:00.000000' # Code to create the STIX Package sp = STIXPackage() sp.stix_header = STIXHeader() sp.stix_header.title = "File Hash Reputation for %s" % md5_hash sp.stix_header.add_package_intent("Indicators - Malware Artifacts") sp.stix_header.information_source = InformationSource() sp.stix_header.information_source.identity = Identity() sp.stix_header.information_source.identity.name = "Mark's Malware Metadata Mart" file_hash = Hash(hash_value=md5_hash, type_='MD5', exact=True) file_hash.type_.condition = "Equals" file_obj = File() file_obj.id_ = (ns_alias + ':' + object_id) file_obj.add_hash(file_hash) indicator = Indicator(title="File Hash Reputation", id_=(ns_alias + ':' + indicator_id), timestamp=indicator_timestamp) indicator.indicator_type = "File Hash Reputation" indicator.add_observable(file_obj) indicator.observables[0].id_ = ns_alias + ':' + observable_id ttp = TTP() ttp.id_ = ns_alias + ':' + ttp_id ttp.timestamp = ttp_timestamp ttp.title = "Malicious File" indicator.add_indicated_ttp(TTP(idref=ttp.id_, timestamp=ttp.timestamp)) indicator.indicated_ttps[0].confidence = confidence indicator.indicated_ttps[0].confidence.timestamp = confidence_timestamp sp.add_indicator(indicator) sp.add_ttp(ttp) stix_xml = sp.to_xml() poll_response = tm11.PollResponse(message_id=generate_message_id(), in_response_to="1234", collection_name='file_hash_reputation') cb = tm11.ContentBlock(content_binding=CB_STIX_XML_111, content=stix_xml) poll_response.content_blocks.append(cb) print poll_response.to_xml(pretty_print=True)
def createMetaData(stix_package, metadata, strings): indicator = Indicator() fl = WinExecutableFile() if metadata["malfilename"] != "": fl.file_name = metadata["malfilename"] if metadata["malmd5"] != "": fl.md5 = metadata["malmd5"] if metadata["malsha1"] != "": fl.sha1 = metadata["malsha1"] if metadata["malsha256"] != "": fl.sha256 = metadata["malsha256"] if metadata["malsha512"] != "": fl.sha512 = metadata["malsha512"] if metadata["malmd54k"] != "": md54k = Hash() md54k.simple_hash_value = metadata["malmd54k"] h = Hash(md54k, Hash.TYPE_OTHER) fl.add_hash(h) if metadata["malssdeep"] != "": ssdeep = Hash() ssdeep.simple_hash_value = metadata["malssdeep"] h = Hash(ssdeep, Hash.TYPE_SSDEEP) fl.add_hash(h) if metadata["malfilesize"] != "": fl.size_in_bytes = metadata["malfilesize"] if metadata["malfiletype"] != "": fl.file_format = metadata["malfiletype"] # peindicator = Indicator() peimportlist = PEImportList() peimport = PEImport() peimportedfunctions = PEImportedFunctions() if len(metadata['iocimports']) > 0: for importfunc in metadata['iocimports']: peif = PEImportedFunction() peif.function_name = importfunc peimportedfunctions.append(peif) peimport.imported_functions = peimportedfunctions peimportlist.append(peimport) peexports = PEExports() peexportedfunctions = PEExportedFunctions() if len(metadata['iocexports']) > 0: for exportfunc in metadata['iocexports']: peef = PEExportedFunction() peef.function_name = exportfunc peexportedfunctions.append(peef) peexports.exported_functions = peexportedfunctions pesectionlist = PESectionList() if len(metadata['badpesections']) > 0: for section in metadata['badpesections']: pesection = PESection() pesectionheader = PESectionHeaderStruct() entropy = Entropy() pesectionheader.name = section[0] if len(section[1]) > 0: data_size = section[1].replace("0x", "") if len(data_size) % 2 != 0: data_size = "0" + data_size pesectionheader.size_of_raw_data = data_size entropy.value = float(section[2]) pesection.entropy = entropy pesection.section_header = pesectionheader pesectionlist.append(pesection) peresourcelist = PEResourceList() peversioninforesource = PEVersionInfoResource() if len(metadata['versioninfo']) > 0: peversioninforesource.comments = str( metadata['versioninfo']['Comments']) if ( metadata['versioninfo']['Comments'] is not None) else "" peversioninforesource.companyname = str( metadata['versioninfo']['CompanyName']) if ( metadata['versioninfo']['CompanyName'] is not None) else "" peversioninforesource.filedescription = str( metadata['versioninfo']['FileDescription']) if ( metadata['versioninfo']['FileDescription'] is not None) else "" peversioninforesource.fileversion = str( metadata['versioninfo']['FileVersion']).replace(", ", ".") if ( metadata['versioninfo']['FileVersion'] is not None) else "" peversioninforesource.internalname = str( metadata['versioninfo']['InternalName']) if ( metadata['versioninfo']['InternalName'] is not None) else "" peversioninforesource.langid = "" peversioninforesource.legalcopyright = str( metadata['versioninfo']['LegalCopyright']) if ( metadata['versioninfo']['LegalCopyright'] is not None) else "" peversioninforesource.originalfilename = str( metadata['versioninfo']['OriginalFilename']) if ( metadata['versioninfo']['OriginalFilename'] is not None) else "" peversioninforesource.privatebuild = str( metadata['versioninfo']['PrivateBuild']) if ( metadata['versioninfo']['PrivateBuild'] is not None) else "" peversioninforesource.productname = str( metadata['versioninfo']['ProductName']) if ( metadata['versioninfo']['ProductName'] is not None) else "" peversioninforesource.productversion = str( metadata['versioninfo']['ProductVersion']).replace(", ", ".") if ( metadata['versioninfo']['ProductVersion'] is not None) else "" peversioninforesource.specialbuild = str( metadata['versioninfo']['SpecialBuild']) if ( metadata['versioninfo']['SpecialBuild'] is not None) else "" peresourcelist.append(peversioninforesource) fl.imports = peimportlist fl.exports = peexports fl.sections = pesectionlist fl.resources = peresourcelist addStrings(fl, strings) indicator.add_observable(Observable(fl)) stix_package.add_indicator(indicator) return fl
def test_exact_hash(self): h = Hash(EMPTY_MD5, exact=True) self.assertEqual("Equals", h.simple_hash_value.condition) self.assertEqual("Equals", h.type_.condition)
def test_autotype_other(self): """Hash of unknown length is assigned TYPE_OTHER""" h = Hash("0123456789abcdef") self.assertEqual(h.type_, Hash.TYPE_OTHER)
def test_fuzzy_hash_ssdeep(self): h = Hash("3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C", Hash.TYPE_SSDEEP) self.assertEqual(str(h), "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C") self.assertEqual(h.type_, Hash.TYPE_SSDEEP)
def test_constructor(self): s = HexBinary(EMPTY_MD5) h = Hash(s)
def main(): stix_package = STIXPackage() malware_instance = MalwareInstance() malware_instance.add_name("plugin1.exe") #not really remote access but am not sure what else to put malware_instance.add_type("Remote Access Trojan") ttp = TTP(title="Install+plugin1.exe") ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) #observable 1 Install+plugin1.exe file_object = File() file_object.file_name = "Install+plugin1.exe" file_object.add_hash( Hash("164ecfc36893ee368a3c4cb2fd500b58262f1b87de1e68df74390db0b5445915" )) file_object.hashes[0].simple_hash_value.condition = "Equals" #observable 2 plugin1.exe #http://cybox.readthedocs.io/en/stable/examples.html#creating-observables file_plugin1 = File() file_plugin1.file_name = "plugin1.exe" file_plugin1.file_path = "C:\\Users\\Default\\AppData\\Local\\temp\plugin1" file_plugin1.add_hash( Hash("ae768b62f5fef4dd604e1b736bdbc3ed30417ef4f67bff74bb57f779d794d6df" )) file_plugin1.hashes[0].simple_hash_value.condition = "Equals" #observable 3 registry key #http://cybox.readthedocs.io/en/stable/api/coverage.html registry_object = WinRegistryKey() registry_object.name = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Google Ultron Updater" #observable 4 network traffic #http://stixproject.github.io/documentation/idioms/malware-hash/ #I couldn't figure out how to correctly indicate the source, dest or protocol addr = Address(address_value="192.168.52.219", category=Address.CAT_IPV4) #indicator 1 Install+plugin1.exe indicator = Indicator(title="File hash for Install+plugin.exe") indicator.add_indicator_type("File Hash Watchlist") indicator.add_observable(file_object) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) #indicator 2 plugin1.exe indicator2 = Indicator(title="File hash for plugin1.exe") indicator2.add_indicator_type("File Hash Watchlist") indicator2.add_observable(file_plugin1) indicator2.add_indicated_ttp(TTP(idref=ttp.id_)) #indicator3 registry key indicator3 = Indicator(title="Registry entry for Install+plugin.exe") indicator3.add_indicator_type("Malware Artifacts") indicator3.add_observable(registry_object) indicator3.add_indicated_ttp(TTP(idref=ttp.id_)) #indicator4 network traffic indicator4 = Indicator(title="Network Traffic for plugine1.exe") indicator.add_indicator_type("IP Watchlist") indicator4.add_observable(Observable(addr)) indicator4.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_indicator(indicator2) stix_package.add_indicator(indicator3) stix_package.add_indicator(indicator4) stix_package.add_ttp(ttp) print(stix_package.to_xml(encoding=None))
def main(): ###################################################################### # MODIFICARE LE VARIABILI SEGUENTI # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28) MyTITLE = "Gootkit" # La description strutturiamola come segue # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)> DESCRIPTION = "D3Lab - Malspam Gootkit con dropper da 450+ MB - https://www.d3lab.net/malspam-gootkit-con-dropper-da-450-mb/" # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community IDENTITY = "D3Lab via Cyber Saiyan Community" # ###################################################################### # read IoC files file_sha256 = "CS-sha256.txt" sha256 = loaddata(file_sha256) file_md5 = "CS-md5.txt" md5 = loaddata(file_md5) file_sha1 = "CS-sha1.txt" sha1 = loaddata(file_sha1) file_domains = "CS-domain.txt" domains = loaddata(file_domains) file_urls = "CS-url.txt" urls = loaddata(file_urls) file_ips = "CS-ipv4.txt" ips = loaddata(file_ips) file_emails = "CS-email.txt" emails = loaddata(file_emails) # 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") print "Reading IoC sha256 file..." p = re.compile(r"^[0-9a-f]{64}$", re.IGNORECASE) for idx, sha256 in enumerate(sha256): m = p.match(sha256) if m: filei = File() filei.add_hash(Hash(sha256)) obsi = Observable(filei) indicatorHASH.add_observable(obsi) else: print " Malformed sha256: " + sha256 print print "Reading IoC md5 file..." p = re.compile(r"^[0-9a-f]{32}$", re.IGNORECASE) for idx, md5 in enumerate(md5): m = p.match(md5) if m: filej = File() filej.add_hash(Hash(md5)) obsj = Observable(filej) indicatorHASH.add_observable(obsj) else: print " Malformed md5: " + md5 print print "Reading IoC sha1 file..." p = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE) for idx, sha1 in enumerate(sha1): m = p.match(sha1) if m: filek = File() filek.add_hash(Hash(sha1)) obsk = Observable(filek) indicatorHASH.add_observable(obsk) else: print " Malformed sha1: " + sha1 print # DOMAIN indicators indiDOMAIN = Indicator() indiDOMAIN.title = MyTITLE + " - DOMAIN" indiDOMAIN.add_indicator_type("Domain Watchlist") print "Reading IoC domains file..." for idu, domains in enumerate(domains): if validators.domain(domains): url = URI() url.value = domains url.type_ = URI.TYPE_DOMAIN url.condition = "Equals" obsu = Observable(url) indiDOMAIN.add_observable(obsu) else: print " Malformed domain: " + domains print # URL indicators indiURL = Indicator() indiURL.title = MyTITLE + " - URL" indiURL.add_indicator_type("URL Watchlist") print "Reading IoC url file..." for idu, urls in enumerate(urls): if validators.url(urls): url = URI() url.value = urls url.type_ = URI.TYPE_URL url.condition = "Equals" obsu = Observable(url) indiURL.add_observable(obsu) else: print " Malformed url: " + urls print # IP indicators indiIP = Indicator() indiIP.title = MyTITLE + " - IP" indiIP.add_indicator_type("IP Watchlist") print "Reading IoC IP file..." for idu, ips in enumerate(ips): if validators.ipv4(ips): ip = Address() ip.address_value = ips obsu = Observable(ip) indiIP.add_observable(obsu) else: print " Malformed IP: " + ips print # EMAIL indicators indiEMAIL = Indicator() indiEMAIL.title = MyTITLE + " - EMAIL" indiEMAIL.add_indicator_type("Malicious E-mail") print "Reading IoC email file..." for idu, emails in enumerate(emails): if validators.email(emails): email = EmailAddress() email.address_value = emails obsu = Observable(email) indiEMAIL.add_observable(obsu) else: print " Malformed email: " + emails print # add all indicators 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 build(self): self.stix_header.title = self.pulse["name"] self.stix_header.description = self.pulse["description"] self.stix_header.short_description = "%spulse/%s" % ( PULSE_SERVER_BASE, str(self.pulse["id"])) self.stix_header.package_intents.append(PackageIntent.TERM_INDICATORS) self.stix_header.information_source = InformationSource() self.stix_header.information_source.time = Time() self.stix_header.information_source.description = "Alienvault OTX - https://otx.alienvault.com/" self.stix_header.information_source.time.produced_time = self.pulse[ "modified"] self.stix_header.information_source.identity = Identity() self.stix_header.information_source.identity.name = "Alienvault OTX" self.stix_package.stix_header = self.stix_header hashes = [] addresses = [] domains = [] urls = [] mails = [] for p_indicator in self.pulse["indicators"]: if p_indicator["type"] in self.hash_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % ( p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) file_ = File() hash_ = Hash(p_indicator["indicator"], self.hash_translation[p_indicator["type"]]) file_.add_hash(hash_) observable_ = Observable(file_) elif p_indicator["type"] in self.address_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % ( p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) ipv4_ = Address.from_dict({ 'address_value': p_indicator["indicator"], 'category': self.address_translation[p_indicator["type"]] }) observable_ = Observable(ipv4_) elif p_indicator["type"] in self.name_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % ( p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) domain_ = DomainName.from_dict({ 'value': p_indicator["indicator"], 'type': 'FQDN' }) observable_ = Observable(domain_) elif p_indicator["type"] == "URL": new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % ( p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) url_ = URI.from_dict({ 'value': p_indicator["indicator"], 'type': URI.TYPE_URL }) observable_ = Observable(url_) elif p_indicator["type"] == "email": email_ = Address.from_dict({ 'address_value': p_indicator["indicator"], 'category': Address.CAT_EMAIL }) observable_ = Observable(email_) #elif p_indicator["type"] == "CVE": # vuln_ = Vulnerability() # vuln_.cveid = p_indicator["indicator"].upper() # observable_ = Observable(vuln_) elif p_indicator["type"] == "Mutex": mutex_ = Mutex.from_dict({ 'named': True, 'name': p_indicator["indicator"] }) observable_ = Observable(mutex_) elif p_indicator["type"] == "CIDR": nrange = IP(p_indicator["indicator"]) nrange_values = nrange.strNormal(3).replace("-", ",") ipv4_ = Address.from_dict({ 'address_value': nrange_values, 'category': Address.CAT_IPV4 }) ipv4_.address_value.condition = "InclusiveBetween" observable_ = Observable(ipv4_) else: continue mind = Indicator() mind.description = p_indicator["description"] mind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) observable_.title = "%s - %s" % (p_indicator["type"], p_indicator["indicator"]) mind.add_observable(observable_) self.stix_package.add_indicator(mind)
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 = raw_input("Insert Title Ioc:") # La description strutturiamola come segue # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)> DESCRIPTION = raw_input("Insert Decription:") # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community IDENTITY = raw_input("Insert User Identity:") # File degli IoC IOCFILE = raw_input("Add IoC Source File:") # Prefisso STIX output files STIX 1.2 e STIX 2 OUTFILEPREFIX = "package" # Short Description - UNUSED #SHORT = "Emotet" ###################################################################### VERBOSE = 0 # UTF8 encode TITLE = TITLE.encode('utf8') DESCRIPTION = DESCRIPTION.encode('utf8') IDENTITY = IDENTITY.encode('utf8') print "\nStix File generation in progress...." #print (TITLE) #"TITLE: " + TITLE #print (DESCRIPTION) #"DESCRIPTION: " + DESCRIPTION #print (IDENTITY) #"IDENTITY: " + IDENTITY #print (IOCFILE) #"IOC FILE: " + IOCFILE #print "---------------------" ######################## # Commond data timestamp = datetime.datetime.fromtimestamp( time.time()).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) # 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.MarkingDefinition(definition_type="tlp", definition={"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 ioc = loaddata(IOCFILE) if (VERBOSE): print "Reading IoC file " + IOCFILE + "..." 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: # STIX 1.2 filei = File() filei.add_hash(Hash(ioc)) obsi = Observable(filei) indicatorHASH.add_observable(obsi) if (VERBOSE): print "SHA256: " + ioc notfound = 0 # STIX 2 pattern_sha256.append("[file:hashes.'SHA-256' = '" + ioc + "'] OR ") #md5 p = re.compile(r"^[0-9a-f]{32}$", re.IGNORECASE) m = p.match(ioc) if m and notfound: # STIX 1.2 filej = File() filej.add_hash(Hash(ioc)) obsj = Observable(filej) indicatorHASH.add_observable(obsj) if (VERBOSE): print "MD5: " + ioc notfound = 0 # STIX 2 pattern_md5.append("[file:hashes.'MD5' = '" + ioc + "'] OR ") #sha1 p = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE) m = p.match(ioc) if m and notfound: # STIX 1.2 filek = File() filek.add_hash(Hash(ioc)) obsk = Observable(filek) indicatorHASH.add_observable(obsk) if (VERBOSE): print "SHA1: " + ioc notfound = 0 # STIX 2 pattern_sha1.append("[file:hashes.'SHA1' = '" + ioc + "'] OR ") #domains if validators.domain(ioc) and notfound: # 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 notfound = 0 # STIX 2 pattern_domain.append("[domain-name:value = '" + ioc + "'] OR ") #url if validators.url(ioc) and notfound: # 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 notfound = 0 # STIX 2 pattern_url.append("[url:value = '" + ioc + "'] OR ") #ip if validators.ipv4(ioc) and notfound: # STIX 1.2 ip = Address() ip.address_value = ioc obsu = Observable(ip) indiIP.add_observable(obsu) if (VERBOSE): print "IP: " + ioc notfound = 0 # STIX 2 pattern_ip.append("[ipv4-addr:value = '" + ioc + "'] OR ") #email if validators.email(ioc) and notfound: # STIX 1.2 email = EmailAddress() email.address_value = ioc obsu = Observable(email) indiEMAIL.add_observable(obsu) if (VERBOSE): print "Email: " + ioc notfound = 0 # STIX 2 pattern_email.append("[email-message:from_ref.value = '" + ioc + "'] 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 bundle = stix2.Bundle(objects=bundle_objects) ######################## # save to STIX 1.2 file print print "Writing STIX 1.2 package: " + OUTFILEPREFIX + ".stix" f = open(OUTFILEPREFIX + ".stix", "w") f.write(wrapper.to_xml()) f.close() ######################## # save to STIX 2 file print "Writing STIX 2 package: " + OUTFILEPREFIX + ".stix2" g = open(OUTFILEPREFIX + ".stix2", "w") sys.stdout = g print bundle
def to_cybox_observable(obj, exclude=None, bin_fmt="raw"): """ Convert a CRITs TLO to a CybOX Observable. :param obj: The TLO to convert. :type obj: :class:`crits.core.crits_mongoengine.CRITsBaseAttributes` :param exclude: Attributes to exclude. :type exclude: list :param bin_fmt: The format for the binary (if applicable). :type bin_fmt: str """ type_ = obj._meta['crits_type'] if type_ == 'Certificate': custom_prop = Property( ) # make a custom property so CRITs import can identify Certificate exports custom_prop.name = "crits_type" custom_prop.description = "Indicates the CRITs type of the object this CybOX object represents" custom_prop._value = "Certificate" obje = File() # represent cert information as file obje.md5 = obj.md5 obje.file_name = obj.filename obje.file_format = obj.filetype obje.size_in_bytes = obj.size obje.custom_properties = CustomProperties() obje.custom_properties.append(custom_prop) obs = Observable(obje) obs.description = obj.description data = obj.filedata.read() if data: # if cert data available a = Artifact(data, Artifact.TYPE_FILE) # create artifact w/data a.packaging.append(Base64Encoding()) obje.add_related(a, "Child_Of") # relate artifact to file return ([obs], obj.releasability) elif type_ == 'Domain': obje = DomainName() obje.value = obj.domain obje.type_ = obj.record_type return ([Observable(obje)], obj.releasability) elif type_ == 'Email': if exclude == None: exclude = [] observables = [] obje = EmailMessage() # Assume there is going to be at least one header obje.header = EmailHeader() if 'message_id' not in exclude: obje.header.message_id = String(obj.message_id) if 'subject' not in exclude: obje.header.subject = String(obj.subject) if 'sender' not in exclude: obje.header.sender = Address(obj.sender, Address.CAT_EMAIL) if 'reply_to' not in exclude: obje.header.reply_to = Address(obj.reply_to, Address.CAT_EMAIL) if 'x_originating_ip' not in exclude: obje.header.x_originating_ip = Address(obj.x_originating_ip, Address.CAT_IPV4) if 'x_mailer' not in exclude: obje.header.x_mailer = String(obj.x_mailer) if 'boundary' not in exclude: obje.header.boundary = String(obj.boundary) if 'raw_body' not in exclude: obje.raw_body = obj.raw_body if 'raw_header' not in exclude: obje.raw_header = obj.raw_header #copy fields where the names differ between objects if 'helo' not in exclude and 'email_server' not in exclude: obje.email_server = String(obj.helo) if ('from_' not in exclude and 'from' not in exclude and 'from_address' not in exclude): obje.header.from_ = EmailAddress(obj.from_address) if 'date' not in exclude and 'isodate' not in exclude: obje.header.date = DateTime(obj.isodate) obje.attachments = Attachments() observables.append(Observable(obje)) return (observables, obj.releasability) elif type_ == 'Indicator': observables = [] obje = make_cybox_object(obj.ind_type, obj.value) observables.append(Observable(obje)) return (observables, obj.releasability) elif type_ == 'IP': obje = Address() obje.address_value = obj.ip if obj.ip_type == IPTypes.IPv4_ADDRESS: obje.category = "ipv4-addr" elif obj.ip_type == IPTypes.IPv6_ADDRESS: obje.category = "ipv6-addr" elif obj.ip_type == IPTypes.IPv4_SUBNET: obje.category = "ipv4-net" elif obj.ip_type == IPTypes.IPv6_SUBNET: obje.category = "ipv6-subnet" return ([Observable(obje)], obj.releasability) elif type_ == 'PCAP': obje = File() obje.md5 = obj.md5 obje.file_name = obj.filename obje.file_format = obj.contentType obje.size_in_bytes = obj.length obs = Observable(obje) obs.description = obj.description art = Artifact(obj.filedata.read(), Artifact.TYPE_NETWORK) art.packaging.append(Base64Encoding()) obje.add_related(art, "Child_Of") # relate artifact to file return ([obs], obj.releasability) elif type_ == 'RawData': obje = Artifact(obj.data.encode('utf-8'), Artifact.TYPE_FILE) obje.packaging.append(Base64Encoding()) obs = Observable(obje) obs.description = obj.description return ([obs], obj.releasability) elif type_ == 'Sample': if exclude == None: exclude = [] observables = [] f = File() for attr in ['md5', 'sha1', 'sha256']: if attr not in exclude: val = getattr(obj, attr, None) if val: setattr(f, attr, val) if obj.ssdeep and 'ssdeep' not in exclude: f.add_hash(Hash(obj.ssdeep, Hash.TYPE_SSDEEP)) if 'size' not in exclude and 'size_in_bytes' not in exclude: f.size_in_bytes = UnsignedLong(obj.size) if 'filename' not in exclude and 'file_name' not in exclude: f.file_name = obj.filename # create an Artifact object for the binary if it exists if 'filedata' not in exclude and bin_fmt: data = obj.filedata.read() if data: # if sample data available a = Artifact(data, Artifact.TYPE_FILE) # create artifact w/data if bin_fmt == "zlib": a.packaging.append(ZlibCompression()) a.packaging.append(Base64Encoding()) elif bin_fmt == "base64": a.packaging.append(Base64Encoding()) f.add_related(a, "Child_Of") # relate artifact to file if 'filetype' not in exclude and 'file_format' not in exclude: #NOTE: this doesn't work because the CybOX File object does not # have any support built in for setting the filetype to a # CybOX-binding friendly object (e.g., calling .to_dict() on # the resulting CybOX object fails on this field. f.file_format = obj.filetype observables.append(Observable(f)) return (observables, obj.releasability) else: return (None, 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(): mydata = loaddata() # NAMESPACE = {sanitizer(mydata["NSXURL"]) : sanitizer(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["filename"]) + ": " + sanitizer( mydata["hashes"]["md5"]) ShortDescription = timestamp DESCRIPTION = "STIX Report for: " + sanitizer( mydata["filename"]) + " - " + sanitizer(mydata["hashes"]["md5"]) wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE, description=DESCRIPTION, short_description=ShortDescription) wrapper.stix_header.handling = handling fileobj = File() fileobj.file_name = sanitizer(mydata["filename"]) fileobj.file_format = sanitizer(mydata["file_type"]) fileobj.size_in_bytes = sanitizer(mydata["file_size"]) fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["md5"]))) fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["sha1"]))) fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["sha256"]))) observable = Observable(fileobj) if "URL_file_hosting" in mydata: for idx, mydata["URL_file_hosting"] in enumerate( mydata["URL_file_hosting"]): url = URI() url.value = sanitizer(mydata["URL_file_hosting"]) url.type_ = URI.TYPE_URL url.condition = "Equals" fileobj.add_related(url, "Downloaded_From") indicator = Indicator() indicator.title = MyTITLE indicator.add_indicator_type("File Hash Watchlist") indicator.add_observable(observable) wrapper.add_indicator(indicator) 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 stix(json): """ Created a stix file based on a json file that is being handed over """ # Create a new STIXPackage stix_package = STIXPackage() # Create a new STIXHeader stix_header = STIXHeader() # Add Information Source. This is where we will add the tool information. stix_header.information_source = InformationSource() # Create a ToolInformation object. Use the initialization parameters # to set the tool and vendor names. # # Note: This is an instance of cybox.common.ToolInformation and NOT # stix.common.ToolInformation. tool = ToolInformation( tool_name="viper2stix", tool_vendor="The Viper group http://viper.li - developed by Alexander Jaeger https://github.com/deralexxx/viper2stix" ) #Adding your identity to the header identity = Identity() identity.name = Config.get('stix', 'producer_name') stix_header.information_source.identity=identity # Set the Information Source "tools" section to a # cybox.common.ToolInformationList which contains our tool that we # created above. stix_header.information_source.tools = ToolInformationList(tool) stix_header.title = Config.get('stix', 'title') # Set the produced time to now stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = Config.get('stix', 'TLP') marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) # Set the header description stix_header.description = Config.get('stix', 'description') # Set the STIXPackage header stix_package.stix_header = stix_header stix_package.stix_header.handling = handling try: pp = pprint.PrettyPrinter(indent=5) pp.pprint(json['default']) #for key, value in json['default'].iteritems(): # print key, value for item in json['default']: #logger.debug("item %s", item) indicator = Indicator() indicator.title = "File Hash" indicator.description = ( "An indicator containing a File observable with an associated hash" ) # Create a CyboX File Object f = File() sha_value = item['sha256'] if sha_value is not None: sha256 = Hash() sha256.simple_hash_value = sha_value h = Hash(sha256, Hash.TYPE_SHA256) f.add_hash(h) sha1_value = item['sha1'] if sha_value is not None: sha1 = Hash() sha1.simple_hash_value = sha1_value h = Hash(sha1, Hash.TYPE_SHA1) f.add_hash(h) sha512_value = item['sha512'] if sha_value is not None: sha512 = Hash() sha512.simple_hash_value = sha512_value h = Hash(sha512, Hash.TYPE_SHA512) f.add_hash(h) f.add_hash(item['md5']) #adding the md5 hash to the title as well stix_header.title+=' '+item['md5'] #print(item['type']) f.size_in_bytes=item['size'] f.file_format=item['type'] f.file_name = item['name'] indicator.description = "File hash served by a Viper instance" indicator.add_object(f) stix_package.add_indicator(indicator) except Exception, e: logger.error('Error: %s',format(e)) return False
def main(): ###################################################################### # 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 map_attribtue(self, instance, attribute): definition_name = attribute.definition.name if hasattr(instance, definition_name.lower()): setattr(instance, definition_name.lower(), attribute.value) value = getattr(instance, definition_name.lower()) value.condition = self.get_condition(attribute) else: if 'hash' in definition_name: if attribute.condition.value: if attribute.condition.value: if attribute.condition.value == "Equals": exact = True else: exact = False else: exact = False else: exact = True h = Hash(attribute.value, exact=exact) h.condition = attribute.condition if instance.hashes is None: instance.hashes = HashList() instance.hashes.append(h) pass elif 'email' in definition_name: self.populate_email(instance, attribute) elif definition_name == 'url': instance.type_ = URI.TYPE_URL instance.value = attribute.value instance.value.condition = self.get_condition(attribute) elif 'Full_Path' and isinstance(instance, Process): # TODO: check why this is set?!? pass elif definition_name == 'WindowsRegistryKey_Key': instance.key = attribute.value instance.key.condition = self.get_condition(attribute) elif definition_name == 'WindowsRegistryKey_Hive': instance.hive = attribute.value instance.hive.condition = self.get_condition(attribute) elif 'WindowsRegistryKey_RegistryValue' in definition_name: value = RegistryValue() if definition_name == 'WindowsRegistryKey_RegistryValue_Data': value.data = attribute.value value.data.condition = self.get_condition(attribute) elif definition_name == 'WindowsRegistryKey_RegistryValue_Data': value.name = attribute.value value.name.condition = self.get_condition(attribute) if not instance.values: instance.values = RegistryValues() instance.values.append(value) instance.data = attribute.value elif definition_name == 'ipv4_addr': instance.category = definition_name.replace('_', '-') instance.address_value = attribute.value instance.address_value.condition = self.get_condition( attribute) elif definition_name == 'DomainName_Value': instance.value = attribute.value elif definition_name == 'Raw_Artifact': path = '{0}/{1}'.format(self.fh.get_base_path(), attribute.value) if isfile(path): with open(path, 'r') as f: bin_string = f.read() instance.data = bin_string # TODO find the corect type instance.type_ = Artifact.TYPE_GENERIC instance.packaging.append(Base64Encoding()) else: instance.data = 'MIA' instance.type_ = Artifact.TYPE_GENERIC instance.packaging.append(Base64Encoding()) elif definition_name == 'content_type': instance.type_ = attribute.value elif definition_name == 'URIType': instance.type_ = attribute.value elif not attribute.definition.cybox_std: self.add_custom_property(instance, attribute) elif isinstance(instance, NetworkConnection) and definition_name in [ 'is_type', 'Port' ]: # TODO: check why this is set?!? pass else: raise Ce1susStixMapperException( 'Cannot map {1} on object type {0}'.format( instance.__class__.__name__, definition_name))
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