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 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 create_ipv4_observable(ipv4_address): ipv4_object = Address.from_dict({"address_value": ipv4_address, "category": Address.CAT_IPV4}) ipv4_observable = Observable(ipv4_object) ipv4_observable.title = "Malware Artifact - IP" ipv4_observable.description = "IP derived from sandboxed malware sample." ipv4_observable.short_description = "IP from malware." return ipv4_observable
def create_url_observable(url): url_object = URI.from_dict({'value': url, 'type': URI.TYPE_URL}) url_observable = Observable(url_object) url_observable.title = "Malware Artifact - URL" url_observable.description = "URL derived from sandboxed malware sample." url_observable.short_description = "URL from malware." return url_observable
def create_url_observable(url): url_object = URI.from_dict({"value": url, "type": URI.TYPE_URL}) url_observable = Observable(url_object) url_observable.title = "Malware Artifact - URL" url_observable.description = "URL derived from sandboxed malware sample." url_observable.short_description = "URL from malware." return url_observable
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 create_domain_name_observable(domain_name): domain_name_object = URI.from_dict({"value": domain_name, "type": URI.TYPE_DOMAIN}) domain_name_observable = Observable(domain_name_object) domain_name_observable.title = "Malware Artifact - Domain" domain_name_observable.description = "Domain derived from sandboxed malware sample." domain_name_observable.short_description = "Domain from malware." return domain_name_observable
def add_url_observable(self, url): if url in self.__urls: return self.__urls.add(url) url_object = URI.from_dict({'value': url, 'type': URI.TYPE_URL}) url_observable = Observable(url_object) url_observable.title = "Malware Artifact - URL" url_observable.description = "URL derived from sandboxed malware sample." url_observable.short_description = "URL from malware." self.url_indicator.add_observable(url_observable)
def test_round_trip(self): o = Observable() o.title = "An observable" o.description = "some text" o.description.structuring_format = "plain" o.id_ = "abc123" o.object_ = Object() o2 = cybox.test.round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
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 create_ipv4_observable(ipv4_address): ipv4_object = Address.from_dict({ 'address_value': ipv4_address, 'category': Address.CAT_IPV4 }) ipv4_observable = Observable(ipv4_object) ipv4_observable.title = "Malware Artifact - IP" ipv4_observable.description = "IP derived from sandboxed malware sample." ipv4_observable.short_description = "IP from malware." return ipv4_observable
def create_domain_name_observable(domain_name): domain_name_object = URI.from_dict({ 'value': domain_name, 'type': URI.TYPE_DOMAIN }) domain_name_observable = Observable(domain_name_object) domain_name_observable.title = "Malware Artifact - Domain" domain_name_observable.description = "Domain derived from sandboxed malware sample." domain_name_observable.short_description = "Domain from malware." return domain_name_observable
def add_ipv4_observable(self, ipv4_address): if ipv4_address in self.__ipv4: return self.__ipv4.add(ipv4_address) ipv4_object = Address.from_dict({'address_value': ipv4_address, 'category': Address.CAT_IPV4}) ipv4_observable = Observable(ipv4_object) ipv4_observable.title = "Malware Artifact - IP" ipv4_observable.description = "IP derived from sandboxed malware sample." ipv4_observable.short_description = "IP from malware." self.ip_indicator.add_observable(ipv4_observable)
def add_domain_name_observable(self, domain_name): if domain_name in self.__domains: return self.__domains.add(domain_name) domain_name_object = URI.from_dict({'value': domain_name, 'type': URI.TYPE_DOMAIN}) domain_name_observable = Observable(domain_name_object) domain_name_observable.title = "Malware Artifact - Domain" domain_name_observable.description = "Domain derived from sandboxed malware sample." domain_name_observable.short_description = "Domain from malware." self.domain_indicator.add_observable(domain_name_observable)
def cybox_mutex(observable, observable_type, objects): nsname, nsurl = observable.namespace.last().namespace.split(':', 1) NS = cybox.utils.Namespace(nsurl, nsname) cybox.utils.set_id_namespace(NS) observables = Observables() for obj in objects: m = Mutex() m.name = obj.mutex_name o = Observable(m) o.title = observable.name o.description = observable.description observables.add(o) return observables
def to_cybox_observable(self): """ Convert a RawData 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 = Artifact(self.data, Artifact.TYPE_FILE) obj.packaging.append(Base64Encoding()) obs = Observable(obj) obs.description = self.description return ([obs], self.releasability)
def add_registry_observable(self, mode, value): if (mode, value) in self.__regkeys: return self.__regkeys.add((mode, value)) # FIXME value is not parse properly _key = '\\'.join(value.split('\\')[3:]) hive = value.split('\\')[2] reg_object = WinRegistryKey.from_dict({'key': _key, 'hive': hive}) reg_observable = Observable(reg_object) reg_observable.title = "Malware Artifact - Registry" reg_observable.description = "Registry access derived from sandboxed malware sample." reg_observable.short_description = "Registry access from malware." self.reg_indicator.add_observable(reg_observable)
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) if attribute["comment"] != "": observable.description = attribute["comment"] return observable
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 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 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) if attribute["comment"] != "": observable.description = attribute["comment"] return 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 cybox_http(observable, observable_type, objects): nsname, nsurl = observable.namespace.last().namespace.split(':', 1) NS = cybox.utils.Namespace(nsurl, nsname) cybox.utils.set_id_namespace(NS) observables = Observables() for obj in objects: h = cybox_object_http(obj) # get related objects related_objects_list = get_related_objects_for_object(obj.id, observable_type) o = Observable(h) o.title = observable.name o.description = observable.description observables.add(o) return observables
def cybox_http(observable, observable_type, objects): nsname, nsurl = observable.namespace.split(':', 1) NS = cybox.utils.Namespace(nsurl, nsname) cybox.utils.set_id_namespace(NS) observables = Observables() for obj in objects: h = cybox_object_http(obj) # get related objects related_objects_list = get_related_objects_for_object(obj.id, observable_type) o = Observable(h) o.title = observable.name o.description = observable.description observables.add(o) return observables
def test_round_trip(self): o = Observable() o.title = "An observable" o.description = "some text" o.description.structuring_format = "plain" o.id_ = "abc123" o.object_ = Object() pf = PatternFidelity() ot = ObfuscationTechnique() ot.description = "X0Rz" pf.evasion_techniques = ObfuscationTechniques() pf.evasion_techniques.append(ot) o.pattern_fidelity = pf o2 = round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
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 main(): test_file = os.path.join(os.path.dirname(__file__), "test.pcap") with open(test_file) as f: data = f.read() a = Artifact(data, Artifact.TYPE_NETWORK) a.packaging.append(Base64Encoding()) o = Observable(a) o.description = ("This Observable specifies an instance of an Artifact " "object, specifically some network traffic that was " "captured in a PCAP file and then base64 encoded for " "transport.") print(Observables(o).to_xml())
def main(): test_file = os.path.join(os.path.dirname(__file__), "test.pcap") with open(test_file, "rb") as f: data = f.read() a = Artifact(data, Artifact.TYPE_NETWORK) a.packaging.append(Base64Encoding()) o = Observable(a) o.description = ("This Observable specifies an instance of an Artifact " "object, specifically some network traffic that was " "captured in a PCAP file and then base64 encoded for " "transport.") print(Observables(o).to_xml(encoding=None))
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 main(): NS = cybox.utils.Namespace("http://example.com/", "example") cybox.utils.set_id_namespace(NS) test_file = os.path.join(os.path.dirname(__file__), "test.pcap") with open(test_file) as f: data = f.read() a = Artifact(data, Artifact.TYPE_NETWORK) a.packaging.append(Base64Encoding()) o = Observable(a) o.description = ("This Observable specifies an instance of an Artifact " "object, specifically some network traffic that was " "captured in a PCAP file and then base64 encoded for " "transport.") print Observables(o).to_xml()
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 cybox_file(observable, observable_type, objects): nsname, nsurl = observable.namespace.split(':', 1) NS = cybox.utils.Namespace(nsurl, nsname) cybox.utils.set_id_namespace(NS) observables = Observables() for obj in objects: for meta in obj.file_meta.all(): f = cybox_object_file(obj, meta) # get related objects related_objects_list = get_related_objects_for_object(obj.id, observable_type) for rel_obj_dict in related_objects_list: for rel_obj in rel_obj_dict['objects']: if isinstance(rel_obj, EmailMessage_Object): rel_o, attachments_list = cybox_object_email(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) for att in attachments_list: observables.add(Observable(att)) continue elif isinstance(rel_obj, File_Object): for rel_meta in rel_obj.file_meta.all(): rel_o = cybox_object_file(rel_obj, rel_meta) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, Address_Object): rel_o = cybox_object_address(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, URI_Object): rel_o = cybox_object_uri(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, HTTPSession_Object): rel_o = cybox_object_http(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue o = Observable(f) o.title = observable.name o.description = observable.description observables.add(o) return observables
def cybox_file(observable, observable_type, objects): nsname, nsurl = observable.namespace.last().namespace.split(':', 1) NS = cybox.utils.Namespace(nsurl, nsname) cybox.utils.set_id_namespace(NS) observables = Observables() for obj in objects: for meta in obj.file_meta.all(): f = cybox_object_file(obj, meta) # get related objects related_objects_list = get_related_objects_for_object(obj.id, observable_type) for rel_obj_dict in related_objects_list: for rel_obj in rel_obj_dict['objects']: if isinstance(rel_obj, EmailMessage_Object): rel_o, attachments_list = cybox_object_email(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) for att in attachments_list: observables.add(Observable(att)) continue elif isinstance(rel_obj, File_Object): for rel_meta in rel_obj.file_meta.all(): rel_o = cybox_object_file(rel_obj, rel_meta) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, Address_Object): rel_o = cybox_object_address(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, URI_Object): rel_o = cybox_object_uri(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue elif isinstance(rel_obj, HTTPSession_Object): rel_o = cybox_object_http(rel_obj) f.add_related(rel_o, rel_obj_dict['relation'], True) continue o = Observable(f) o.title = observable.name o.description = observable.description observables.add(o) return observables
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 __add_dns_query_observable(self, qname, qtype, qclass): dns_query_object = DNSQuery.from_dict({'value': dns_query, 'type': URI.TYPE_DOMAIN}) dns_query_observable = Observable(dns_query_object) dns_query_observable.title = "Malware Artifact - DNS query" dns_query_observable.description = "DNS query derived from sandboxed malware sample." dns_query_observable.short_description = "DNS query from malware."
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 index2stix(local_index, orig_stix): #============= # Build package metadata #============= new_stix = STIXPackage() new_stix.stix_header = STIXHeader() new_stix.stix_header.title = "TG3390 - Enrichment" new_stix.stix_header.description = "Enrichment stix file to the Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/" marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) new_stix.stix_header.handling = handling enrich_IPs = Indicator(title="Suspected TG3390 IP Addresses obtained through automated enrichment") enrich_IPs.add_indicator_type("IP Watchlist") enrich_IPs.confidence = "Low" related_IPs = Indicator(title="Related indicator wrapper for source of enrichment") related_IPs.add_indicator_type("IP Watchlist") related_IPs.confidence = "Medium" enrich_Domains = Indicator(title="Suspected TG3390 Domains obtained through automated enrichment") enrich_Domains.add_indicator_type("Domain Watchlist") enrich_Domains.confidence = "Low" related_Domains = Indicator(title="Related indicator wrapper for source of enrichment") related_Domains.add_indicator_type("Domain Watchlist") related_Domains.confidence = "Medium" # START with the ones that already have ids: #if verbose: #print_chain(local_index) new_ref_created = True while new_ref_created: new_ref_created = False for ind_type in local_index: for obs in local_index[ind_type]: id_tobe_referenced = local_index[ind_type][obs][0] #print id_tobe_referenced[:10] if id_tobe_referenced[:10] != '{{no_ref}}': ref_obs = Observable() ref_obs.id_ = id_tobe_referenced.replace("{{no_ref}}","") ref_obs.description = 'Source of enrichment for: ' create_ref_obs = False for entry in local_index[ind_type][obs]: if type(entry) is list: if len(entry)>0: for item in entry: ref, child_ind_type = get_ref_from_obs(item, local_index) #print item if ref == '{{no_ref}}' or ref == '': create_ref_obs = True new_ref_created = True #print 'Create new, complete, observable for ' + item #print child_ind_type #Create the new observable for item and add as object to appropriate Indicator if child_ind_type == 'DomainName': append_ind = enrich_Domains related_ind = related_Domains new_obj = DomainName() new_obj.value = item #enrich_Domains.add_object(domain_obj) elif child_ind_type == 'Address': append_ind = enrich_IPs related_ind = related_IPs new_obj = Address() new_obj.category = "ipv4-addr" new_obj.address_value = item #enrich_IPs.add_object(ipv4_obj) else: print 'Unsupported indicator type: ' + child_ind_type new_obs = Observable(new_obj) new_obs_ref = new_obs.id_ append_ind.add_observable(new_obs) ref = new_obs_ref #local_index[item][0] = ref set_obs_ref(item, new_obs_ref, local_index) #print 'Adding ref to: ' + ref_obs.id_ + ' of ' + ref ref_obs.description = str(ref_obs.description) + ref.replace("{{no_ref}}","") + ', ' if create_ref_obs: #Add the new ref obs to Related Indicators related_ind.add_observable(ref_obs) #print related_ind.to_xml() create_ref_obs = False related_ind1 = RelatedIndicator(related_IPs, relationship='Source of enrichment for IPs') related_ind2 = RelatedIndicator(related_Domains, relationship='Source of enrichment for Domains') enrich_IPs.related_indicators.append(related_ind1) enrich_Domains.related_indicators.append(related_ind2) new_stix.add_indicator(enrich_IPs) new_stix.add_indicator(enrich_Domains) #new_stix_json = json.loads(new_stix.to_json()) #new_stix_xml = new_stix.to_xml() #if verbose: #print new_stix.to_xml() return new_stix