def generate_file_observable(self, filename, h_value, fuzzy): file_object = File() if filename: if '/' in filename or '\\' in filename: file_object.file_path = ntpath.dirname(filename) file_object.file_path.condition = "Equals" file_object.file_name = ntpath.basename(filename) file_object.file_name.condition = "Equals" else: file_object.file_name = filename file_object.file_name.condition = "Equals" if h_value: file_object.add_hash(Hash(hash_value=h_value, exact=True)) if fuzzy: try: self.resolve_fuzzy(file_object, h_value, "Hashes") except KeyError: field_type = "" for f in file_object._fields: if f.name == "Hashes": field_type = f break if field_type: self.resolve_fuzzy(file_object, h_value, field_type) return file_object
def main(): pkg = STIXPackage() file_object1 = File() file_object1.file_name = "readme.doc.exe" file_object1.size_in_bytes = 40891 file_object1.add_hash( Hash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" )) observable1 = Observable(file_object1) file_object2 = File() file_object2.file_name = "readme.doc.exe" file_object2.size_in_bytes = 40891 file_object2.add_hash( Hash("d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" )) observable2 = Observable(file_object2) incident = Incident(title="Malicious files detected") related_observable1 = RelatedObservable( observable1, relationship="Malicious Artifact Detected") related_observable2 = RelatedObservable( observable2, relationship="Malicious Artifact Detected") incident.related_observables.append(related_observable1) incident.related_observables.append(related_observable2) pkg.add_incident(incident) print(pkg.to_xml(encoding=None))
def generateFileObservable(filenameValue, hashValue): file_object = File() if (filenameValue != ""): if (("/" in filenameValue) or ("\\" in filenameValue)): file_object.file_path = ntpath.dirname(filenameValue) file_object.file_name = ntpath.basename(filenameValue) else: file_object.file_name = filenameValue if (hashValue != ""): file_object.add_hash(Hash(hashValue)) return file_object
def generateFileObservable(filenameValue, hashValue): file_object = File() if (filenameValue != ""): if (("/" in filenameValue) or ("\\" in filenameValue)): file_object.file_path = ntpath.dirname(filenameValue) file_object.file_path.condition = "Equals" file_object.file_name = ntpath.basename(filenameValue) file_object.file_name.condition = "Equals" else: file_object.file_name = filenameValue file_object.file_name.condition = "Equals" if (hashValue != ""): file_object.add_hash(Hash(hash_value=hashValue, exact=True)) return file_object
def test_observables_property_composition(self): f1 = File() f1.file_name = "README.txt" f2 = File() f2.file_name = "README2.txt" obs1 = Observable(f1) obs2 = Observable(f2) comp = Observable(ObservableComposition('AND', [obs1, obs2])) ind = Indicator() ind.observable = comp ind2 = Indicator.from_dict(ind.to_dict()) self.assertEqual([obs1.to_dict(), obs2.to_dict()], [x.to_dict() for x in ind2.observables])
def create_file_hash_observable(fn, hash_value): '''Create a CybOX Observable representing a file hash.''' hash_ = Hash(hash_value) file_ = File() file_.file_name = fn file_.add_hash(hash_) return Observable(file_)
def _dostix(hashes): '''This function creates a STIX packages containing hashes.''' print("[+] Creating STIX Package") title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now()) _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix']) stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = title stix_package.stix_header.handling = _marking() try: indicator = Indicator() indicator.set_producer_identity(SETTINGS['stix']['producer']) indicator.set_produced_time(indicator.timestamp) indicator.set_received_time(indicator.timestamp) indicator.add_kill_chain_phase(PHASE_DELIVERY) indicator.confidence = "Low" indicator.title = title indicator.add_indicator_type("File Hash Watchlist") indicator.description = SETTINGS['stix']['ind_desc'] try: indicator.add_indicated_ttp( TTP(idref=SETTINGS['indicated_ttp'], timestamp=indicator.timestamp)) indicator.suggested_coas.append( CourseOfAction(idref=SETTINGS['suggested_coa'], timestamp=indicator.timestamp)) except KeyError: pass for info in hashes: try: file_name = info['filename'] file_object = File() file_object.file_name = file_name file_object.file_name.condition = "Equals" file_object.file_extension = "." + file_name.split('.')[-1] file_object.file_extension.condition = "Equals" file_object.size_in_bytes = info['filesize'] file_object.size_in_bytes.condition = "Equals" file_object.file_format = info['fileformat'] file_object.file_format.condition = "Equals" file_object.add_hash(Hash(info['md5'])) file_object.add_hash(Hash(info['sha1'])) file_object.add_hash(Hash(info['sha256'])) file_object.add_hash(Hash(info['sha512'])) file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP)) for hashobj in file_object.hashes: hashobj.simple_hash_value.condition = "Equals" hashobj.type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + file_name indicator.add_observable(file_obs) except TypeError: pass stix_package.add_indicator(indicator) return stix_package except KeyError: pass
def to_cybox_observable(self): """ Convert a Certificate to a CybOX Observables. Returns a tuple of (CybOX object, releasability list). To get the cybox object as xml or json, call to_xml() or to_json(), respectively, on the resulting CybOX object. """ 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" obj = File() # represent cert information as file obj.md5 = self.md5 obj.file_name = self.filename obj.file_format = self.filetype obj.size_in_bytes = self.size obj.custom_properties = CustomProperties() obj.custom_properties.append(custom_prop) obs = Observable(obj) obs.description = self.description data = self.filedata.read() if data: # if cert data available a = Artifact(data, Artifact.TYPE_FILE) # create artifact w/data a.packaging.append(Base64Encoding()) obj.add_related(a, "Child_Of") # relate artifact to file return ([obs], self.releasability)
def to_cybox(self, exclude=None): if exclude == None: exclude = [] observables = [] f = File() for attr in ['md5', 'sha1', 'sha256']: if attr not in exclude: val = getattr(self, attr, None) if val: setattr(f, attr, val) if self.ssdeep and 'ssdeep' not in exclude: f.add_hash(Hash(self.ssdeep, Hash.TYPE_SSDEEP)) if 'size' not in exclude and 'size_in_bytes' not in exclude: f.size_in_bytes = UnsignedLong(self.size) if 'filename' not in exclude and 'file_name' not in exclude: f.file_name = self.filename # create an Artifact object for the binary if it exists if 'filedata' not in exclude: data = self.filedata.read() if data: data = base64.b64encode(data) a = Artifact(data=data, type_=Artifact.TYPE_FILE) observables.append(Observable(a)) #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 = self.filetype observables.append(Observable(f)) return (observables, self.releasability)
def to_cybox_observable(self): """ Convert a Certificate to a CybOX Observables. Returns a tuple of (CybOX object, releasability list). To get the cybox object as xml or json, call to_xml() or to_json(), respectively, on the resulting CybOX object. """ 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" obj = File() # represent cert information as file obj.md5 = self.md5 obj.file_name = self.filename obj.file_format = self.filetype obj.size_in_bytes = self.size obj.custom_properties = CustomProperties() obj.custom_properties.append(custom_prop) obs = Observable(obj) obs.description = self.description data = self.filedata.read() if data: # if cert data available a = Artifact(data, Artifact.TYPE_FILE) # create artifact w/data a.packaging.append(Base64Encoding()) obj.add_related(a, "Child_Of") # relate artifact to file return ([obs], self.releasability)
def test_fields(self): f = File() f.file_name = "blah.exe" self.assertEqual(String, type(f.file_name)) f.file_path = "C:\\Temp" self.assertEqual(FilePath, type(f.file_path))
def returnAttachmentComposition(attribute): file_object = File() file_object.file_name = attribute["value"] file_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":FileObject-" + attribute[ "uuid"] observable = Observable() if "data" in attribute: artifact = Artifact(data=attribute["data"]) artifact.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":ArtifactObject-" + attribute[ "uuid"] observable_artifact = Observable(artifact) observable_artifact.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-artifact-" + attribute[ "uuid"] observable_file = Observable(file_object) observable_file.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-file-" + attribute[ "uuid"] composition = ObservableComposition( observables=[observable_artifact, observable_file]) observable.observable_composition = composition else: observable = Observable(file_object) observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute[ "uuid"] if attribute["comment"] != "": observable.description = attribute["comment"] return observable
def main(): stix_package = STIXPackage() ttp = TTP(title="Phishing") stix_package.add_ttp(ttp) # Create the indicator for just the subject email_subject_object = EmailMessage() email_subject_object.header = EmailHeader() email_subject_object.header.subject = "[IMPORTANT] Please Review Before" email_subject_object.header.subject.condition = "StartsWith" email_subject_indicator = Indicator() email_subject_indicator.title = "Malicious E-mail Subject Line" email_subject_indicator.add_indicator_type("Malicious E-mail") email_subject_indicator.observable = email_subject_object email_subject_indicator.confidence = "Low" # Create the indicator for just the attachment file_attachment_object = EmailMessage() file_attachment_object.attachments = Attachments() attached_file_object = File() attached_file_object.file_name = "Final Report" attached_file_object.file_name.condition = "StartsWith" attached_file_object.file_extension = "doc.exe" attached_file_object.file_extension.condition = "Equals" file_attachment_object.add_related(attached_file_object, "Contains", inline=True) file_attachment_object.attachments.append(file_attachment_object.parent.id_) indicator_attachment = Indicator() indicator_attachment.title = "Malicious E-mail Attachment" indicator_attachment.add_indicator_type("Malicious E-mail") indicator_attachment.observable = file_attachment_object indicator_attachment.confidence = "Low" # Create the combined indicator w/ both subject an attachment full_email_object = EmailMessage() full_email_object.attachments = Attachments() # Add the previously referenced file as another reference rather than define it again: full_email_object.attachments.append(file_attachment_object.parent.id_) full_email_object.header = EmailHeader() full_email_object.header.subject = "[IMPORTANT] Please Review Before" full_email_object.header.subject.condition = "StartsWith" combined_indicator = Indicator(title="Malicious E-mail") combined_indicator.add_indicator_type("Malicious E-mail") combined_indicator.confidence = Confidence(value="High") combined_indicator.observable = full_email_object email_subject_indicator.add_indicated_ttp(TTP(idref=ttp.id_)) indicator_attachment.add_indicated_ttp(TTP(idref=ttp.id_)) combined_indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.indicators = [combined_indicator, email_subject_indicator, indicator_attachment] print stix_package.to_xml()
def generateEmailAttachmentObject(indicator, filename): file_object = File() file_object.file_name = filename email = EmailMessage() email.attachments = Attachments() email.add_related(file_object, "Contains", inline=True) email.attachments.append(file_object.parent.id_) indicator.observable = email
def __get_source_objs(self): f1 = File() f1.file_name = 'emailprovider.db' f1.file_path = '/data/data/com.android.providers.email/databases/' f1.file_format = 'SQLite 3.x database' f1.size_in_bytes = '2374' f1.add_hash(Hash("a7a0390e99406f8975a1895860f55f2f")) return [f1]
def test_fields_not_shared(self): # In a previous version of TypedFields, all objects of the same type # shared a single value of each field. Obviously this was a mistake. f = File() f.file_name = "README.txt" self.assertEqual("README.txt", f.file_name) f2 = File() self.assertEqual(None, f2.file_name)
def create_file(file_name=None, md5=None, sha1=None, sha256=None): file_ = File() file_.file_name = file_name file_.md5 = md5 file_.sha1 = sha1 file_.sha256 = sha256 api_object = ApiObject(ty='obs', apiobj=Observable(item=Object(file_))) api_object.api_object = api_object return api_object
def create_file_hash_observable(filename, hash_value): hash_ = Hash(hash_value) file_ = File() file_.file_name = filename file_.add_hash(hash_) file_observable = Observable(file_) file_observable.title = "Malware Artifact - File Hash" file_observable.description = "File hash derived from sandboxed malware sample." file_observable.short_description = "File hash from malware." return file_observable
def test_observables_property_standard(self): f = File() f.file_name = "README.txt" obs = Observable(f) ind = Indicator() ind.observable = obs ind2 = Indicator.from_dict(ind.to_dict()) self.assertEqual([obs.to_dict()], [x.to_dict() for x in ind2.observables])
def returnAttachmentComposition(attribute): file_object = File() file_object.file_name = attribute["value"] observable = Observable() if "data" in attribute: artifact = Artifact(data = attribute["data"]) composition = ObservableComposition(observables = [artifact, file_object]) observable.observable_composition = composition else: observable = Observable(file_object) return observable
def __create_cybox_files(self, msg): """Returns a list of CybOX File objects from the message. Attachments can be identified within multipart messages by their Content-Disposition header. Ex: Content-Disposition: attachment; filename="foobar.jpg" """ files = [] if self.__verbose_output: sys.stderr.write("** parsing attachments\n") # extract the email attachments into their own FileObjectType objects if msg.is_multipart(): for part in msg.get_payload(): if 'content-disposition' in part: # if it's an attachment-type, pull out the filename # and calculate the size in bytes file_name = part.get_filename(failobj='') file_data = part.get_payload(decode=True) #PGP Encrypted could come back as None and '' if file_name or file_data: f = File() #Do what we can with what came back from the payload parsing if file_name: f.file_name = file_name f.file_extension = os.path.splitext(file_name)[1] if file_data: f.size = len(file_data) hashes = [] hashes.append(hashlib.md5(file_data).hexdigest()) hashes.append(hashlib.sha1(file_data).hexdigest()) hashes.append(hashlib.sha256(file_data).hexdigest()) hashes.append(hashlib.sha384(file_data).hexdigest()) for hash in hashes: f.add_hash(hash) files.append(f) #TODO: add support for created and modified dates #modified_date = self.__get_attachment_modified_date(part) #created_date = self.__get_attachment_created_date(part) if self.__verbose_output: sys.stderr.write("** creating file object for: %s, size: %d bytes\n" % (f.file_name, f.size)) return files
def returnAttachmentComposition(attribute): file_object = File() file_object.file_name = attribute["value"] observable = Observable() if "data" in attribute: artifact = Artifact(data=attribute["data"]) composition = ObservableComposition( observables=[artifact, file_object]) observable.observable_composition = composition else: observable = Observable(file_object) return observable
def __create_cybox_main_file(self, fdict): f = File() f.file_name = String(fdict['filename']) try: f.file_extension = String('.'+fdict['filename'].rsplit('.')[-1]) except: f.file_extension = "" f.size_in_bytes = int(fdict['size']) f.add_hash(Hash(fdict['md5'], type_="MD5", exact=True)) f.add_hash(Hash(fdict['sha1'], type_="SHA1", exact=True)) f.add_hash(Hash(fdict['sha256'], type_="SHA256", exact=True)) return f
def generateEmailAttachmentObject(indicator, attribute): file_object = File() file_object.file_name = attribute["value"] email = EmailMessage() email.attachments = Attachments() email.add_related(file_object, "Contains", inline=True) file_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":file-" + attribute["uuid"] email.attachments.append(file_object.parent.id_) email.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":EmailMessage-" + attribute["uuid"] observable = Observable(email) observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute["uuid"] indicator.observable = observable
def generateEmailAttachmentObject(indicator, attribute): file_object = File() file_object.file_name = attribute["value"] file_object.file_name.condition = "Equals" email = EmailMessage() email.attachments = Attachments() email.add_related(file_object, "Contains", inline=True) file_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":file-" + attribute["uuid"] email.attachments.append(file_object.parent.id_) email.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":EmailMessage-" + attribute["uuid"] observable = Observable(email) observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute["uuid"] indicator.observable = observable
def cybox_object_file(obj, meta=None): # TODO: missing File_Custom_Properties f = File() if obj.md5_hash != 'No MD5': f.add_hash(Hash(obj.md5_hash)) if obj.sha256_hash != 'No SHA256': f.add_hash(Hash(obj.sha256_hash)) if meta: f.file_name = meta.file_name f.file_extension = meta.file_extension f.file_path = meta.file_path f.size_in_bytes = meta.file_size return f
def add_file_hash_observable(self, filename, md5_value, sha1_value): if (filename, md5_value, sha1_value) in self.__hashes: return self.__hashes.add((filename, md5_value, sha1_value)) file_ = File() file_.file_name = filename file_.add_hash(Hash(md5_value)) file_.add_hash(Hash(sha1_value)) file_observable = Observable(file_) file_observable.title = "Malware Artifact - File Hash" file_observable.description = "File hash derived from sandboxed malware sample." file_observable.short_description = "File hash from malware." self.hash_indicator.add_observable(file_observable)
def generateFileObservable(filenameValue, hashValue, fuzzy): file_object = File() if (filenameValue != ""): if (("/" in filenameValue) or ("\\" in filenameValue)): file_object.file_path = ntpath.dirname(filenameValue) file_object.file_path.condition = "Equals" file_object.file_name = ntpath.basename(filenameValue) file_object.file_name.condition = "Equals" else: file_object.file_name = filenameValue file_object.file_name.condition = "Equals" if (hashValue != ""): file_object.add_hash(Hash(hash_value=hashValue, exact=True)) if (fuzzy): file_object._fields["Hashes"]._inner[0].simple_hash_value = None file_object._fields["Hashes"]._inner[ 0].fuzzy_hash_value = hashValue file_object._fields["Hashes"]._inner[ 0].fuzzy_hash_value.condition = "Equals" file_object._fields["Hashes"]._inner[0].type_ = Hash.TYPE_SSDEEP file_object._fields["Hashes"]._inner[0].type_.condition = "Equals" return file_object
def add_file_dropped_observable(self, filename): if filename in self.__files: return self.__files.add(filename) #hash_ = Hash(hash_value) file_ = File() file_.file_name = filename #file_.add_hash(hash_) file_observable = Observable(file_) file_observable.title = "Malware Artifact - File Dropped" file_observable.description = "File Dropped derived from sandboxed malware sample." file_observable.short_description = "File Dropped from malware." self.hash_indicator.add_observable(file_observable)
def main(): h = Hash("a7a0390e99406f8975a1895860f55f2f") f = File() f.file_name = "bad_file24.exe" f.file_path = "AppData\Mozilla" f.file_extension = ".exe" f.size_in_bytes = 3282 f.add_hash(h) o = Observable(f) o.description = "This observable specifies a specific file observation." print(Observables(o).to_xml())
def generate_email_attachment_object(self, indicator, attribute): attribute_uuid = attribute.uuid file_object = File() file_object.file_name = attribute.value file_object.file_name.condition = "Equals" file_object.parent.id_ = "{}:FileObject-{}".format(self.namespace_prefix, attribute_uuid) email = EmailMessage() email.attachments = Attachments() email.add_related(file_object, "Contains", inline=True) email.attachments.append(file_object.parent.id_) email.parent.id_ = "{}:EmailMessageObject-{}".format(self.namespace_prefix, attribute_uuid) observable = Observable(email) observable.id_ = "{}:observable-{}".format(self.namespace_prefix, attribute_uuid) indicator.observable = observable
def create_file_object(file_path, original_file_path): """ :type file_path: string :type original_file_path: string :rtype: File """ f = File() f.file_name = os.path.basename(file_path) f.file_extension = os.path.splitext(file_path)[1] f.file_path = original_file_path f.file_format = magic.from_file(file_path) f.size_in_bytes = os.path.getsize(file_path) f.sha256 = sha256_checksum(file_path) return f
def main(): pkg = STIXPackage() file_object1 = File() file_object1.file_name = "readme.doc.exe" file_object1.size_in_bytes = 40891 file_object1.add_hash(Hash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) observable1 = Observable(file_object1) file_object2 = File() file_object2.file_name = "readme.doc.exe" file_object2.size_in_bytes = 40891 file_object2.add_hash(Hash("d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")) observable2 = Observable(file_object2) incident = Incident(title="Malicious files detected") related_observable1 = RelatedObservable(observable1, relationship="Malicious Artifact Detected") related_observable2 = RelatedObservable(observable2, relationship="Malicious Artifact Detected") incident.related_observables.append(related_observable1) incident.related_observables.append(related_observable2) pkg.add_incident(incident) print(pkg.to_xml(encoding=None))
def main(): print '<?xml version="1.0" encoding="UTF-8"?>' h1 = Hash("59a7078444ee3c862e4c08b601ed7e01", exact=True) h2 = Hash("98e969b49ff2aedf66b94eb82c54b916f1a634cd", exact=True) h3 = Hash("1706c7cd14a5c9bbf674b21f9c4f873ac04b7a6f1f2202cd0c5977c48968d188", exact=True) f = File() f.file_name = "notepad.exe" f.file_path = "C:\Temp" f.add_hash(h1) f.add_hash(h2) f.add_hash(h3) print Observables(f).to_xml()
def main(): print '<?xml version="1.0" encoding="UTF-8"?>' attachment = File() attachment.file_name = "FooBar Specification (critical revision).doc" attachment.add_hash(Hash("4EC0027BEF4D7E1786A04D021FA8A67F")) email = EmailMessage() email.attachments.append(attachment) email.subject = String("New modifications to the specification") email.to = EmailRecipients(EmailAddress("*****@*****.**"), EmailAddress("*****@*****.**")) email.from_ = EmailAddress("*****@*****.**") print Observables(email).to_xml()
def main(): NS = cybox.utils.Namespace("http://example.com/", "example") cybox.utils.set_id_namespace(NS) h = Hash("a7a0390e99406f8975a1895860f55f2f") f = File() f.file_name = "bad_file24.exe" f.file_path = "AppData\Mozilla" f.file_extension = ".exe" f.size_in_bytes = 3282 f.add_hash(h) o = Observable(f) o.description = "This observable specifies a specific file observation." print Observables(o).to_xml()
def return_attachment_composition(self, attribute): file_object = File() file_object.file_name = attribute.value file_object.parent.id_ = "{}:FileObject-{}".format(self.namespace_prefix, attribute.uuid) if 'data' in attribute: observable_artifact = self.create_artifact_object(attribute, artifact="a") observable_file = Observable(file_object) observable_file.id_ = "{}:observable-file-{}".format(self.namespace_prefix, attribute.uuid) observable = Observable() composition = ObservableComposition(observables=[observable_artifact, observable_file]) observable.observable_composition = composition else: observable = Observable(file_object) observable.id_ = "{}:observable-{}".format(self.namespace_prefix, attribute.uuid) if attribute.comment: observable.description = attribute.comment return observable
def __create_cybox_dropped_files(self, dropps, main_sha256): dropped = [] if not dropps: return dropped for item in dropps: """ skip original file """ if item['sha256'] == main_sha256: continue f = File() f.file_name = String(item['name']) f.file_extension = String('.'+item['name'].rsplit('.')[-1]) f.size_in_bytes = int(item['size']) f.add_hash(Hash(item['md5'], type_="MD5", exact=True)) f.add_hash(Hash(item['sha1'], type_="SHA1", exact=True)) f.add_hash(Hash(item['sha256'], type_="SHA256", exact=True)) dropped.append(f) return dropped
def cap2cybox(capob): NS = cybox.utils.Namespace("http://example.com/","lift_s") cybox.utils.set_id_namespace(NS) #ファイル情報 files = File() root, ext = os.path.splitext(fpath) path = FilePath(root) files.file_name = os.path.basename(fpath) files.file_path = path files.file_extension = ext capObser = Observable(files) capObser.description = u'ファイル情報' ls = [capObser] for ob in ls: capob.add(ob) return capob
def to_cybox_observable(self): """ Convert a PCAP to a CybOX Observables. Returns a tuple of (CybOX object, releasability list). To get the cybox object as xml or json, call to_xml() or to_json(), respectively, on the resulting CybOX object. """ obj = File() obj.md5 = self.md5 obj.file_name = self.filename obj.file_format = self.contentType obj.size_in_bytes = self.length obs = Observable(obj) obs.description = self.description art = Artifact(self.filedata.read(), Artifact.TYPE_NETWORK) art.packaging.append(Base64Encoding()) obj.add_related(art, "Child_Of") # relate artifact to file return ([obs], self.releasability)
def returnAttachmentComposition(attribute): file_object = File() file_object.file_name = attribute["value"] file_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":file-" + attribute["uuid"] observable = Observable() if "data" in attribute: artifact = Artifact(data = attribute["data"]) artifact.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":artifact-" + attribute["uuid"] observable_artifact = Observable(artifact) observable_artifact.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-artifact-" + attribute["uuid"] observable_file = Observable(file_object) observable_file.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-file-" + attribute["uuid"] composition = ObservableComposition(observables = [observable_artifact, observable_file]) observable.observable_composition = composition else: observable = Observable(file_object) observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute["uuid"] if attribute["comment"] != "": observable.description = attribute["comment"] return observable
def to_cybox_observable(self, exclude=None, bin_fmt="raw"): if exclude == None: exclude = [] observables = [] f = File() for attr in ['md5', 'sha1', 'sha256']: if attr not in exclude: val = getattr(self, attr, None) if val: setattr(f, attr, val) if self.ssdeep and 'ssdeep' not in exclude: f.add_hash(Hash(self.ssdeep, Hash.TYPE_SSDEEP)) if 'size' not in exclude and 'size_in_bytes' not in exclude: f.size_in_bytes = UnsignedLong(self.size) if 'filename' not in exclude and 'file_name' not in exclude: f.file_name = self.filename # create an Artifact object for the binary if it exists if 'filedata' not in exclude and bin_fmt: data = self.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 = self.filetype observables.append(Observable(f)) return (observables, self.releasability)
def main(): # NOTE: ID values will differ due to being regenerated on each script execution pkg = STIXPackage() pkg.title="Examples of Observable Composition" # USE CASE: single obj with single condition obs = File() obs.file_name = "foo.exe" obs.file_name.condition = "Contains" pkg.add_observable(obs) # USE CASE: single obj with multiple conditions obs = File() obs.file_name = "foo" obs.file_name.condition = "Contains" obs.size_in_bytes = '1896000' obs.size_in_bytes.condition = "Equals" pkg.add_observable(obs) # USE CASE: multiple obj with individual conditions obs = EmailMessage() obs.subject = "Syria strategic plans leaked" obs.subject.condition= "Equals" file_obj = File() file_obj.file_name = "bombISIS.pdf" file_obj.file_name.condition = "Equals" obs.add_related(file_obj, "Contains") pkg.add_observable(obs) # USE CASE: multiple objects with complex condition like (A OR B) AND C # orcomp = either of a mutex or file are present orcomp = ObservableComposition() orcomp.operator = "OR" obs = Mutex() obs.name = 'foo' obs.name.condition= "Contains" orcomp.add(obs) obs = File() obs.file_name = "barfoobar" obs.file_name.condition = "Equals" orcomp.add(obs) # andcomp = the above is true AND a network connection is present andcomp = ObservableComposition() andcomp.operator = "AND" andcomp.add(orcomp) obs = NetworkConnection() sock = SocketAddress() sock.ip_address = "46.123.99.25" sock.ip_address.category = "ipv4-addr" sock.ip_address.condition = "Equals" obs.destination_socket_address = sock andcomp.add (obs) pkg.add_observable(andcomp) # USE CASE: single object, one property with multiple values obs = SocketAddress() obs.ip_address = ['10.0.0.0','10.0.0.1','10.0.0.2'] # comma delimiter automagically added obs.ip_address.condition = "Equals" obs.ip_address.apply_condition = "ANY" pkg.add_observable(obs) print pkg.to_xml()
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 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)