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 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 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 __parse_email_message(self, msg): """ Parses the supplied message Returns a map of message parts expressed as cybox objects. Keys: 'message', 'files', 'urls' """ files = [] url_list = [] domain_list = [] message = EmailMessage() # Headers are required (for now) message.header = self.__create_cybox_headers(msg) if self.include_attachments: files = self.__create_cybox_files(msg) message.attachments = Attachments() for f in files: message.attachments.append(f.parent.id_) f.add_related(message, "Contained_Within", inline=False) if self.include_raw_headers: raw_headers_str = self.__get_raw_headers(msg).strip() if raw_headers_str: message.raw_header = String(raw_headers_str) # need this for parsing urls AND raw body text raw_body = "\n".join(self.__get_raw_body_text(msg)).strip() if self.include_raw_body and raw_body: message.raw_body = String(raw_body) if self.include_urls: (url_list, domain_list) = self.__parse_urls(raw_body) if url_list: links = Links() for u in url_list: links.append(LinkReference(u.parent.id_)) if links: message.links = links # Return a list of all objects we've built return [message] + files + url_list + domain_list
def test_round_trip_list(self): a = Attachments() a.append("example:File-A1") a.append("example:File-A3") a2 = cybox.test.round_trip(a, list_=True) self.assertEqual(a.to_list(), a2.to_list())
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 convert_email_message_c_o(em20, em1x, obs20_id): em1x.header = EmailHeader() convert_obj(em20, em1x, EMAIL_MESSAGE_MAP, obs20_id) if "from_ref" in em20: if em20["from_ref"] in _STIX1X_OBJS: em1x.header.from_ = _STIX1X_OBJS[em20["from_ref"]] else: warn("%s is not an index found in %s, property 'from_ref'", 306, em20["from_ref"], obs20_id) if "sender_ref" in em20: if em20["sender_ref"] in _STIX1X_OBJS: em1x.header.sender = _STIX1X_OBJS[em20["sender_ref"]] else: warn("%s is not an index found in %s, property 'sender_refs'", 306, em20["sender_ref"], obs20_id) if "to_refs" in em20: to_address_objects = [] for to_ref in em20["to_refs"]: if to_ref in _STIX1X_OBJS: to_address_objects.append(_STIX1X_OBJS[to_ref]) em1x.header.to = to_address_objects else: warn("%s is not an index found in %s, property 'to_refs'", 306, to_ref, obs20_id) if "cc_refs" in em20: cc_address_objects = [] for cc_ref in em20["cc_refs"]: if cc_ref in _STIX1X_OBJS: cc_address_objects.append(_STIX1X_OBJS[cc_ref]) em1x.header.cc = cc_address_objects else: warn("%s is not an index found in %s, property 'cc_refs'", 306, cc_ref, obs20_id) if "bcc_refs" in em20: bcc_address_objects = [] for bcc_ref in em20["bcc_refs"]: if bcc_ref in _STIX1X_OBJS: bcc_address_objects.append(_STIX1X_OBJS[bcc_ref]) em1x.header.bcc = bcc_address_objects else: warn("%s is not an index found in %s, property 'bcc_refs'", 306, bcc_ref, obs20_id) if "content_type" in em20: em1x.header.content_type = em20["content_type"] if "received_lines" in em20: em1x.header.received_lines = ReceivedLineList() for rl20 in em20["received_lines"]: rl1x = ReceivedLine() em1x.header.received_lines.append(rl1x) populate_received_line(rl20, rl1x, obs20_id) if "additional_header_fields" in em20: populate_other_header_fields(em20["additional_header_fields"], em1x.header, obs20_id) if "raw_email_refs" in em20: warn( "STIX 1.x can only store the body and headers of an email message in %s independently", 523, obs20_id) if "body" in em20: if em20["is_multipart"]: warn( "The is_multipart property in %s should be 'false' if the body property is present", 313, obs20_id) em1x.raw_body = em20["body"] else: if em20["is_multipart"]: warn( "The is_multipart property in %s should be 'true' if the body property is not present", 313, obs20_id) if "body_multipart" in em20: if not em20["is_multipart"]: warn( "The is_multipart property in %s should be 'true' if the body_multipart property is present", 313, obs20_id) attachments = [] for part in em20["body_multipart"]: # content_disposition is optional, so we can't depend upon it # if "content_disposition" in part and part["content_disposition"].find("attachment"): if "body_raw_ref" in part: if part["body_raw_ref"] in _STIX1X_OBJS: obj = _STIX1X_OBJS[part["body_raw_ref"]] # TODO: can we handle other object/content types? if isinstance(obj, File) or isinstance(obj, Artifact): attachments.append(obj) else: warn("%s is not an index found in %s", 306, part["body_raw_ref"], obs20_id) if "body" in part: em1x.raw_body = part["body"] if attachments: em1x.attachments = Attachments() for a in attachments: em1x.add_related(a, "Contains", inline=True) em1x.attachments.append(a.parent.id_) else: if em20["is_multipart"]: warn( "The is_multipart property in %s should be 'false' if the body_multipart property is not present", 313, obs20_id)
def test_round_trip_list(self): a = Attachments() a.append("example:File-A1") a.append("example:File-A3") a2 = cybox.test.round_trip(a, list_=True) self.assertEqual(a.to_list(), a2.to_list())
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 execute(self, device_info, extracted_data_dir_path): original_app_path = '/data/data/com.android.email' headers_db_rel_file_path = os.path.join('databases', 'EmailProvider.db') bodies_db_rel_file_path = os.path.join('databases', 'EmailProviderBody.db') original_headers_db_file_path = os.path.join(original_app_path, headers_db_rel_file_path) original_bodies_db_file_path = os.path.join(original_app_path, bodies_db_rel_file_path) headers_db_file_path = os.path.join(extracted_data_dir_path, headers_db_rel_file_path) bodies_db_file_path = os.path.join(extracted_data_dir_path, bodies_db_rel_file_path) source_objects = [ create_file_object(headers_db_file_path, original_headers_db_file_path), create_file_object(bodies_db_file_path, original_bodies_db_file_path) ] inspected_objects = {} cursor, conn = execute_query(headers_db_file_path, 'SELECT * FROM message') for row in cursor: header = EmailHeader() header.to = row['toList'] header.cc = row['ccList'] header.bcc = row['bccList'] header.from_ = row['fromList'] header.subject = row['subject'] header.in_reply_to = row['replyToList'] header.date = datetime.fromtimestamp(row['timeStamp'] / 1000) # Convert from milliseconds to seconds header.message_id = row['messageId'] email = EmailMessage() email.header = header email.add_related(source_objects[0], ObjectRelationship.TERM_EXTRACTED_FROM, inline=False) # Add the email to the inspected_objects dict using its _id value as key. email_id = row['_id'] inspected_objects[email_id] = email cursor.close() conn.close() # Add full raw body to emails. cursor, conn = execute_query(bodies_db_file_path, 'SELECT _id, htmlContent, textContent FROM body') for row in cursor: email_id = row['_id'] email = inspected_objects.get(email_id) if email is not None: if row['htmlContent'] != '': email.raw_body = row['htmlContent'] email.header.content_type = 'text/html' else: email.raw_body = row['textContent'] email.header.content_type = 'text/plain' email.add_related(source_objects[1], ObjectRelationship.TERM_EXTRACTED_FROM, inline=False) cursor.close() # Add attachments to emails. cursor, conn = execute_query(headers_db_file_path, 'SELECT messageKey, contentUri FROM attachment') # Iteration over attachments for row in cursor: # Get current attachment email_id. email_id = row['messageKey'] # Find email in inspected_objects. email = inspected_objects.get(email_id) # If email has non attachments, initialize them. if email.attachments is None: email.attachments = Attachments() # Using contentUri, get attachment folder_prefix and file_name. attachment_rel_path_dirs = re.search('.*//.*/(.*)/(.*)/.*', row['contentUri']) # Group(1): contains attachment folder. # Group(2): contains attachment file_name. attachment_rel_file_path = os.path.join('databases', attachment_rel_path_dirs.group(1) + '.db_att', attachment_rel_path_dirs.group(2)) # Build attachment absolute file path in extracted_data. attachment_file_path = os.path.join(extracted_data_dir_path, attachment_rel_file_path) # Build attachment original file_path in device. original_attachment_file_path = os.path.join(original_app_path, attachment_rel_file_path) # Create attachment source_file. attachment = create_file_object(attachment_file_path, original_attachment_file_path) # Add attachment to email's attachments. email.attachments.append(attachment.parent.id_) # Add relation between attachment and it's email. attachment.add_related(email, ObjectRelationship.TERM_CONTAINED_WITHIN, inline=False) source_objects.append(attachment) cursor.close() conn.close() return inspected_objects.values(), source_objects
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(attached_file_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(attached_file_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.add_indicator(combined_indicator) stix_package.add_indicator(email_subject_indicator) stix_package.add_indicator(indicator_attachment) print(stix_package.to_xml(encoding=None))
def to_cybox_observable(self, exclude=None): """ Convert an email to a CybOX Observables. Pass parameter exclude to specify fields that should not be included in the returned object. 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. """ if exclude == None: exclude = [] observables = [] obj = EmailMessage() # Assume there is going to be at least one header obj.header = EmailHeader() if 'message_id' not in exclude: obj.header.message_id = String(self.message_id) if 'subject' not in exclude: obj.header.subject = String(self.subject) if 'sender' not in exclude: obj.header.sender = Address(self.sender, Address.CAT_EMAIL) if 'reply_to' not in exclude: obj.header.reply_to = Address(self.reply_to, Address.CAT_EMAIL) if 'x_originating_ip' not in exclude: obj.header.x_originating_ip = Address(self.x_originating_ip, Address.CAT_IPV4) if 'x_mailer' not in exclude: obj.header.x_mailer = String(self.x_mailer) if 'boundary' not in exclude: obj.header.boundary = String(self.boundary) if 'raw_body' not in exclude: obj.raw_body = self.raw_body if 'raw_header' not in exclude: obj.raw_header = self.raw_header #copy fields where the names differ between objects if 'helo' not in exclude and 'email_server' not in exclude: obj.email_server = String(self.helo) if ('from_' not in exclude and 'from' not in exclude and 'from_address' not in exclude): obj.header.from_ = EmailAddress(self.from_address) if 'date' not in exclude and 'isodate' not in exclude: obj.header.date = DateTime(self.isodate) obj.attachments = Attachments() observables.append(Observable(obj)) return (observables, self.releasability)
def cybox_object_email(obj): e = EmailMessage() e.raw_body = obj.raw_body e.raw_header = obj.raw_header # Links e.links = Links() for link in obj.links.all(): pass # Attachments e.attachments = Attachments() attachment_objects = [] for att in obj.attachments.all(): for meta in att.file_meta.all(): fobj = cybox_object_file(att, meta) e.attachments.append(fobj.parent.id_) fobj.add_related(e, "Contained_Within", inline=False) attachment_objects.append(fobj) # construct header information h = EmailHeader() h.subject = obj.subject h.date = obj.email_date h.message_id = obj.message_id h.content_type = obj.content_type h.mime_version = obj.mime_version h.user_agent = obj.user_agent h.x_mailer = obj.x_mailer # From for from_ in obj.from_string.all(): from_address = EmailAddress(from_.sender) from_address.is_spoofed = from_.is_spoofed from_address.condition = from_.condition h.from_ = from_address # Sender for sender in obj.sender.all(): sender_address = EmailAddress(sender.sender) sender_address.is_spoofed = sender.is_spoofed sender_address.condition = sender.condition h.sender.add(sender_address) # To recipients = EmailRecipients() for recipient in obj.recipients.all(): rec_address = EmailAddress(recipient.recipient) rec_address.is_spoofed = recipient.is_spoofed rec_address.condition = recipient.condition recipients.append(rec_address) h.to = recipients # CC recipients = EmailRecipients() for recipient in obj.recipients_cc.all(): rec_address = EmailAddress(recipient.recipient) rec_address.is_spoofed = recipient.is_spoofed rec_address.condition = recipient.condition recipients.append(rec_address) h.cc = recipients # BCC recipients = EmailRecipients() for recipient in obj.recipients_bcc.all(): rec_address = EmailAddress(recipient.recipient) rec_address.is_spoofed = recipient.is_spoofed rec_address.condition = recipient.condition recipients.append(rec_address) h.bcc = recipients e.header = h return e, attachment_objects
# get all comments for the current attachment objectid comments = db.comments.find({'obj_id': ObjectId(yid)}) for comment in comments: # check if the comments contain string 'analyst note' if comment['comment'].lower().startswith('analyst note'): acomment = re.sub(r'\banalyst note\b', '', comment['comment'], flags=re.IGNORECASE) else: # no comments acomment = 'none' # 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 = xfilename attached_file_object.file_name.condition = "Equals" file_attachment_object.add_related(attached_file_object, "Contains", inline=True) file_attachment_object.attachments.append( attached_file_object.parent.id_) attachdescription = "Phishing email attachment\nFrom: %s\nSubj: %s\n Filename: %s\nSize: %s\nMD5: %s\nSHA1: %s\nSHA256: %s\nSSDEEP: %s\nAnalyst Notes: %s\n"\ %(xfrom,xsubject,xfilename,xfilesize,xmd5,xsha1,xsha256,xssdeep,acomment) indicator_attachment = Indicator(description=attachdescription) indicator_attachment.title = "Phishing E-mail Attachment"