def main(): # Creamos el indicador con la información de la que disponemos threatActor = ThreatActor() threatActor.title = "Ip/Domain/Hostname" threatActor.description = ("A threatActor commited with malicious tasks") threatActor.information_source = ("Malshare") threatActor.timestamp = ("01/05/2019") threatActor.identity = ("106.113.123.197") threatActor.types = ("eCrime Actor - Spam Service") # Creamos el indicador con la información de la que disponemos indicator = Indicator() indicator.title = "Risk Score" indicator.description = ( "An indicator containing the appropriate Risk Score") indicator.set_produced_time("01/05/2019") indicator.likely_impact = ("Risk Score: 2(Medium)") # Creamos el reporte en STIX, con una brve descripción stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Feeds in STIX format with their Risk Scores" stix_package.stix_header = stix_header # Añadimos al reporte el indicador que hemos construido antes stix_package.add(threatActor) stix_package.add(indicator) # Imprimimos el xml en pantalla print(stix_package.to_xml())
def url(ip,provider,reporttime): vuln = Vulnerability() vuln.cve_id = "IPV4-" + str(ip) vuln.description = "maliciousURL" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) addr = Address(address_value=str(ip), category=Address.CAT_IPV4) addr.condition = "Equals" # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "URL-" + str(ip) indicator.description = ("Malicious URL " + str(ip) + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) indicator.add_observable(addr) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/URL/' + str(ip) + '.xml','w') f.write(stix_package.to_xml()) f.close()
def test_identity_from_xml(self): obj = self.klass.from_dict(self._full_dict) sp = STIXPackage() sp.add(obj) s = BytesIO(sp.to_xml()) pkg = STIXPackage.from_xml(s) self.assertTrue("CIQIdentity3.0InstanceType" in text_type(pkg.to_xml()))
def md5(hash,provider,reporttime): vuln = Vulnerability() vuln.cve_id = "MD5-" + hash vuln.description = "maliciousMD5" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) # Create a CyboX File Object f = File() # This automatically detects that it's an MD5 hash based on the length f.add_hash(hash) # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "MD5-" + hash indicator.description = ("Malicious hash " + hash + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_observable(f) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/MD5/' + hash + '.xml','w') f.write(stix_package.to_xml()) f.close()
def main(): # Crea un objeto vÃa CybOX f = File() # Asocia el hash a dicho objeto, la tipologÃa del hash la detecta automáticamente en función de su amplitud f.add_hash("8994a4713713e4683117e35d8689ea24") # Creamos el indicador con la información de la que disponemos indicator = Indicator() indicator.title = "Feeds and Risk Score" indicator.description = ( "An indicator containing the feed and the appropriate Risk Score" ) indicator.set_producer_identity("Malshare") indicator.set_produced_time("01/05/2019") indicator.likely_impact = ("Risk Score: 4(Critical)") # Asociamos el hash anterior a nuestro indicador indicator.add_object(f) # Creamos el reporte en STIX, con una brve descripción stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Feeds in STIX format with their Risk Scores" stix_package.stix_header = stix_header # Añadimos al reporte el indicador que hemos construido antes stix_package.add(indicator) # Imprimimos el xml en pantalla print(stix_package.to_xml())
def main(): # Create our CybOX Simple Hash Value shv = Hash() shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F" # Create a CybOX File Object and add the Hash we created above. f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) # Create the STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader() stix_header.description = "Simple File Hash Observable Example" stix_package.stix_header = stix_header # Add the File Hash Observable to the STIX Package. The add() method will # inspect the input and add it to the top-level stix_package.observables # collection. stix_package.add(f) # Print the XML! print(stix_package.to_xml())
def main(): # Create a CyboX File Object f = File() # This automatically detects that it's an MD5 hash based on the length f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "File Hash Example" indicator.description = ( "An indicator containing a File observable with an associated hash" ) indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(utils.dates.now()) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_object(f) # Create a STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader() stix_header.description = "File Hash Indicator Example" stix_package.stix_header = stix_header # Add our Indicator object. The add() method will inspect the input and # append it to the `stix_package.indicators` collection. stix_package.add(indicator) # Print the XML! print(stix_package.to_xml())
def main(hash_value, title, description, confidence_value): # Create a CyboX File Object f = File() # This automatically detects that it's an MD5 hash based on the length f.add_hash(hash_value) # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = title indicator.description = (description) indicator.confidence = confidence_value indicator.set_producer_identity("Information Security") indicator.set_produced_time(utils.dates.now()) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_object(f) # Create a STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader() stix_header.description = description stix_package.stix_header = stix_header # Add our Indicator object. The add() method will inspect the input and # append it to the `stix_package.indicators` collection. stix_package.add(indicator) # Print the XML! with open('FileHash_indicator.xml', 'w') as the_file: the_file.write(stix_package.to_xml().decode('utf-8'))
def url(ip, provider, reporttime): vuln = Vulnerability() vuln.cve_id = "IPV4-" + str(ip) vuln.description = "maliciousURL" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) addr = Address(address_value=str(ip), category=Address.CAT_IPV4) addr.condition = "Equals" # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "URL-" + str(ip) indicator.description = ("Malicious URL " + str(ip) + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) indicator.add_observable(addr) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/URL/' + str(ip) + '.xml', 'w') f.write(stix_package.to_xml()) f.close()
def md5(hash, provider, reporttime): vuln = Vulnerability() vuln.cve_id = "MD5-" + hash vuln.description = "maliciousMD5" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) # Create a CyboX File Object f = File() # This automatically detects that it's an MD5 hash based on the length f.add_hash(hash) # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "MD5-" + hash indicator.description = ("Malicious hash " + hash + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_observable(f) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/MD5/' + hash + '.xml', 'w') f.write(stix_package.to_xml()) f.close()
def main(): # Create a CybOX File Object with a contained hash f = File() f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "File Hash Example" indicator.description = ( "An indicator containing a File observable with an associated hash") indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(utils.dates.now()) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_object(f) # Build our STIX CIQ Identity object party_name = stix_ciq.PartyName(name_lines=("Foo", "Bar"), person_names=("John Smith", "Jill Smith"), organisation_names=("Foo Inc.", "Bar Corp.")) ident_spec = stix_ciq.STIXCIQIdentity3_0(party_name=party_name) ident_spec.add_electronic_address_identifier("*****@*****.**") ident_spec.add_free_text_line("Demonstrating Free Text!") ident_spec.add_contact_number("555-555-5555") ident_spec.add_contact_number("555-555-5556") # Build and add a CIQ Address addr = stix_ciq.Address(free_text_address='1234 Example Lane.', country='USA', administrative_area='An Admin Area') ident_spec.add_address(addr) identity = stix_ciq.CIQIdentity3_0Instance(specification=ident_spec) # Set the Indicator producer identity to our CIQ Identity indicator.set_producer_identity(identity) # Build our STIX Package stix_package = STIXPackage() # Build a STIX Header and add a description stix_header = STIXHeader() stix_header.description = "STIX CIQ Identity Extension Example" # Set the STIX Header on our STIX Package stix_package.stix_header = stix_header # Add our Indicator object. The add() method will inspect the input and # append it to the `stix_package.indicators` collection. stix_package.add(indicator) # Print the XML! print(stix_package.to_xml()) # Print a dictionary! pprint(stix_package.to_dict())
def fqdn(fqdn,provider,reporttime): currentTime = time.time() parsed_uri = urlparse( str(fqdn) ) domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) if domain.startswith('https'): domain = domain[8:] else: domain = domain[7:] if domain.endswith('/'): domain = domain[:-1] vuln = Vulnerability() vuln.cve_id = "FQDN-" + str(domain) + '_' + str(currentTime) vuln.description = "maliciousIPV4" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) url = URI() url.value = fqdn url.type_ = URI.TYPE_URL url.condition = "Equals" # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "FQDN-" + str(fqdn) indicator.description = ("Malicious FQDN " + str(fqdn) + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) indicator.add_observable(url) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/FQDN/' + str(domain) + '_' + str(currentTime) + '.xml','w') f.write(stix_package.to_xml()) f.close()
def fqdn(fqdn, provider, reporttime): currentTime = time.time() parsed_uri = urlparse(str(fqdn)) domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) if domain.startswith('https'): domain = domain[8:] else: domain = domain[7:] if domain.endswith('/'): domain = domain[:-1] vuln = Vulnerability() vuln.cve_id = "FQDN-" + str(domain) + '_' + str(currentTime) vuln.description = "maliciousIPV4" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) url = URI() url.value = fqdn url.type_ = URI.TYPE_URL url.condition = "Equals" # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "FQDN-" + str(fqdn) indicator.description = ("Malicious FQDN " + str(fqdn) + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) indicator.add_observable(url) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open( '/opt/TARDIS/Observables/FQDN/' + str(domain) + '_' + str(currentTime) + '.xml', 'w') f.write(stix_package.to_xml()) f.close()
from stix.core import STIXPackage from stix.report import Report from stix.report.header import Header stix_package = STIXPackage() stix_report = Report() stix_report.header = Header() stix_report.header.description = "Getting Started" stix_package.add(stix_report) print(stix_package.to_xml())
def create_stix_file(): # List of indicators to be deduped hostnames = [] ips = [] urls = [] md5s = [] sha1s = [] # Set namespace NAMESPACE = {PRODUCER_URL: PRODUCER_NAME} set_id_namespace(NAMESPACE) # JSON load the POSTed request data try: data_recv = request.data data = json.loads(data_recv) except: return make_response( jsonify({'Error': "Unable to decode json object"}), 400) # Parse the JSON object try: # Get MD5 of sample malware_sample = data['alert']['explanation']['malware-detected'][ 'malware'] count = 0 sample_hash = "" try: for entry in malware_sample: if "md5sum" in malware_sample[count]: sample_hash = malware_sample[count]['md5sum'] count += 1 except: if "md5sum" in malware_sample: sample_hash = malware_sample['md5sum'] # If all else fails if sample_hash == "": sample_hash = "Unknown" # Indicators # Domains domain_indicator = Indicator() domain_indicator.title = "Malware Artifacts - Domain" domain_indicator.type = "Malware Artifacts" domain_indicator.description = ( "Domains derived from sandboxed malware sample. MD5 Hash: " + sample_hash) domain_indicator.short_description = ("Domainss from " + sample_hash) domain_indicator.set_producer_identity(PRODUCER_NAME) domain_indicator.set_produced_time(utils.dates.now()) domain_indicator.indicator_types.append("Domain Watchlist") # IPs ip_indicator = Indicator() ip_indicator.title = "Malware Artifacts - IP" ip_indicator.description = ( "IPs derived from sandboxed malware sample. MD5 Hash: " + sample_hash) ip_indicator.short_description = ("IPs from " + sample_hash) ip_indicator.set_producer_identity(PRODUCER_NAME) ip_indicator.set_produced_time(utils.dates.now()) ip_indicator.indicator_types.append("IP Watchlist") # URLs url_indicator = Indicator() url_indicator.title = "Malware Artifacts - URL" url_indicator.description = ( "URLs derived from sandboxed malware sample. MD5 Hash: " + sample_hash) url_indicator.short_description = ("URLs from " + sample_hash) url_indicator.set_producer_identity(PRODUCER_NAME) url_indicator.set_produced_time(utils.dates.now()) url_indicator.indicator_types.append("URL Watchlist") # Hashs hash_indicator = Indicator() hash_indicator.title = "Malware Artifacts - File Hash" hash_indicator.description = ( "File hashes derived from sandboxed malware sample. MD5 Hash: " + sample_hash) hash_indicator.short_description = ("Hash from " + sample_hash) hash_indicator.set_producer_identity(PRODUCER_NAME) hash_indicator.set_produced_time(utils.dates.now()) hash_indicator.indicator_types.append("File Hash Watchlist") # Create a STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader({"Indicators - Malware Artifacts"}) stix_header.description = PRODUCER_NAME + ": FireEye Sample ID " + str( data['alert']['id']) stix_package.stix_header = stix_header if "network" in data['alert']['explanation']['os-changes']: # Add indicators for network for entry in data['alert']['explanation']['os-changes']['network']: if "hostname" in entry: hostnames.append(entry['hostname']) if "ipaddress" in entry: ips.append(entry['ipaddress']) if "http_request" in entry: domain = re.search('~~Host:\s(.*?)~~', entry['http_request']) url = re.search('^.*\s(.*?)\sHTTP', entry['http_request']) if domain: domain_name = domain.group(1) if url: url_string = url.group(1) urls.append(domain_name + url_string) # Add indicators for files for entry in data['alert']['explanation']['os-changes']['network']: if "md5sum" in entry['processinfo']: filename = re.search('([\w-]+\..*)', entry['processinfo']['imagepath']) if filename: md5s.append((filename.group(1), entry['processinfo']['md5sum'])) if "process" in data['alert']['explanation']['os-changes']: # Add indicators from process for entry in data['alert']['explanation']['os-changes']['process']: if "md5sum" in entry: filename = re.search('([\w-]+\..*)', entry['value']) if filename: md5s.append((filename.group(1), entry['md5sum'])) if "sha1sum" in entry: filename = re.search('([\w-]+\..*)', entry['value']) if filename: sha1s.append((filename.group(1), entry['sha1sum'])) # Dedupe lists for hostname in set(hostnames): hostname_observable = create_domain_name_observable(hostname) domain_indicator.add_observable(hostname_observable) for ip in set(ips): ip_observable = create_ipv4_observable(ip) ip_indicator.add_observable(ip_observable) for url in set(urls): url_observable = create_url_observable(url) url_indicator.add_observable(url_observable) for hash in set(md5s): hash_observable = create_file_hash_observable(hash[0], hash[1]) hash_indicator.add_observable(hash_observable) for hash in set(sha1s): hash_observable = create_file_hash_observable(hash[0], hash[1]) hash_indicator.add_observable(hash_observable) # Add those to the package stix_package.add(domain_indicator) stix_package.add(ip_indicator) stix_package.add(url_indicator) stix_package.add(hash_indicator) # Save to file save_as = SAVE_DIRECTORY + "/fireeye_" + str( data['alert']['id']) + ".xml" f = open(save_as, 'w') f.write(stix_package.to_xml()) f.close # Return success response return make_response( jsonify({'Success': "STIX document succesfully generated"}), 200) # Unable to parse object except: return make_response(jsonify({'Error': "Unable to parse JSON object"}), 400)
class StixManager(object): def __init__(self, threat_name="Generic Threat", threat_descr="Generic Threat", author="Nozomi Networks Labs" , log=True): for i in ADDITIONAL_NAMESPACES: nsparser.STIX_NAMESPACES.add_namespace(i) mixbox.namespaces.register_namespace(i) self._pkg = STIXPackage() self.set_stix_header(threat_name, threat_descr) self._src_file = None self.__author = author self._lookup = set() self.__log = log def _is_ascii(self, value): return value.isascii() def load_raw_file(self, fname): with open(fname, 'r') as f: rawdata = f.readlines() for line in rawdata: ioc = line.strip() if len(ioc) > 0: res = self.add_raw_indicator(ioc) if res is True: if self.__log is True: logging.info("Auto-detected indicator: %s", ioc) else: if self.__log is True: logging.warning("Unknown indicator format: %s", ioc) self._src_file = fname return True def save_stix_file(self , file_name): try: with open(file_name, 'wb') as f: f.write(self._pkg.to_xml()) return True except Exception as e: if self.__log is True: logging.error(e) return False def set_stix_header(self, threat_name, threat_descr, threat_source=None, reference=None): # Create a STIX Package hdr = STIXHeader() hdr.title = threat_name hdr.add_description(threat_descr) hdr.information_source = InformationSource() if threat_source is not None: hdr.information_source.description = threat_source if reference is not None: hdr.information_source.references = fields.TypedField(reference, References) # Set the produced time to now hdr.information_source.time = Time() hdr.information_source.time.produced_time = datetime.utcnow() self._pkg.stix_header = hdr def add_raw_indicator(self , orig_indicator, ts=None): indicator_value = orig_indicator if not self._is_ascii(indicator_value): return False indicator_type, _ = guess_type(indicator_value) # Create a CyboX File Object if indicator_type == StixItemType.IPADDR: title = "Malicious IPv4 - %s" % indicator_value descr = "Malicious IPv4 involved with %s" % self._pkg.stix_header.title cybox = Address(indicator_value , Address.CAT_IPV4) elif indicator_type == StixItemType.DOMAIN: title = "Malicious domain - %s" % indicator_value descr = "Malicious domain involved with %s" % self._pkg.stix_header.title cybox = DomainName() cybox.value = indicator_value elif indicator_type == StixItemType.MD5: title = "Malicious MD5 - %s" % indicator_value descr = "Malicious MD5 involved with %s" % self._pkg.stix_header.title cybox = File() cybox.add_hash(indicator_value ) elif indicator_type == StixItemType.SHA256: title = "Malicious SHA256 - %s" % indicator_value descr = "Malicious SHA256 involved with %s" % self._pkg.stix_header.title cybox = File() cybox.add_hash(indicator_value ) elif indicator_type == StixItemType.SHA1: title = "Malicious SHA1 - %s" % indicator_value descr = "Malicious SHA1 involved with %s" % self._pkg.stix_header.title cybox = File() cybox.add_hash(indicator_value ) elif indicator_type == StixItemType.URL: title = "Malicious URL - %s" % indicator_value descr = "Malicious URL involved with %s" % self._pkg.stix_header.title cybox = URI() cybox.value = indicator_value cybox.type_ = URI.TYPE_URL if indicator_type == StixItemType.UNKNOWN: return False indicator = Indicator() indicator.title = title indicator.description = descr indicator.add_object(cybox) indicator.set_producer_identity(self.__author) if ts: indicator.set_produced_time(ts) else: indicator.set_produced_time(utils.dates.now()) self._add(indicator) return True def _add(self, indicator): ioc = self._parse_indicator(indicator) assert len(ioc) == 1, "Multiple observables in a single indicator not supported yet" ioc = ioc.pop() # Check for duplicates if self.is_duplicated(ioc.value): if self.__log is True: logging.warning("Skipping duplicated indicator: %s", ioc.value) return False # Update description _, type_descr = guess_type(ioc.value) indicator.title = "Malicious %s - %s" % (type_descr, ioc.value) indicator.description = "Malicious %s involved with the threat %s" % (type_descr, self._pkg.stix_header.title) # Update the lookup table self._lookup.add(ioc.value) self._pkg.add(indicator) return True def is_duplicated(self, ivalue): return ivalue in self._lookup def _parse_indicator(self, indicator): processed_indicators = set() title = indicator.title description = indicator.description timestamp = indicator.get_produced_time() if timestamp: timestamp = timestamp.value else: logging.warning("Failed to get produced time") for obj in indicator.observables: # Object attributes obj_val = None obj_type = None # Extract the object properties obj_prop = obj.to_obj().Object.Properties if isinstance(obj_prop, domain_name_object.DomainNameObjectType): obj_val = obj_prop.Value.valueOf_ obj_type = StixItemType.DOMAIN elif isinstance(obj_prop, file_object.FileObjectType): # TODO: support multiple hashes obj_hash = obj_prop.Hashes.get_Hash()[0] obj_hash_type = obj_hash.Type.valueOf_.upper() if obj_hash_type in ['SHA256', 'SHA1', 'MD5']: obj_val = obj_hash.get_Simple_Hash_Value().valueOf_ if obj_hash_type == 'SHA256': obj_type = StixItemType.SHA256 elif obj_hash_type == 'SHA1': obj_type = StixItemType.SHA1 elif obj_hash_type == 'MD5': obj_type = StixItemType.MD5 else: obj_type = StixItemType.UNKNOWN else: if self.__log is True: logging.warning("Unsupported hash type: %s" % obj_hash_type) elif isinstance(obj_prop, uri_object.URIObjectType): obj_val = obj_prop.Value.valueOf_ obj_type = StixItemType.URL elif isinstance(obj_prop, address_object.AddressObjectType): obj_val = obj_prop.Address_Value.valueOf_ obj_type = StixItemType.IPADDR else: obj_val = indicator obj_type = StixItemType.UNKNOWN # Strip-out the value obj_val = obj_val.strip() ioc = StixIndicator(obj_type, obj_val, title, description, timestamp) processed_indicators.add(ioc) # Return indicators return processed_indicators
c.close() response = buffer.getvalue().decode("utf-8") response = response.strip('OK:') response = response.strip('\r\n') stxf = File() stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Malicious File Hash Indicator" stix_package.stix_header = stix_header indicator = Indicator() indicator.title = "File Observable" indicator.description = ( "An indicator containing a File observable with an associated hash") root = ElementTree.fromstring(response) for child in root: for child2 in child: for child3 in child2: for filenames in child3.iter('fileJoined.filename'): indicator.add_short_description(filenames.text) for hashes in child3.iter('fileJoined.md5'): stxf.add_hash(hashes.text) indicator.set_producer_identity("McAfee LLC.") indicator.set_produced_time(utils.dates.now()) indicator.add_object(stxf) stix_package.add(indicator) stxout = open(stixfilename, "wb") stxout.write(stix_package.to_xml()) stxout.close()
def gatherIOCs(folderPath, synConn, synackConn, ackConn, resolvedIPs, results, fullHTTPArray, udpconn, dnspacket, icmpPacket, ftpconn, sshconn, foundIPs): stix_package = STIXPackage() stix_report = stixReport() # need to add indicator references to this stix_header_information_source = InformationSource() stix_header_information_source.description = "From Cuckoo sandbox IOC_STIX reporting module" stix_report.header = Header() stix_report.header.title = "A bunch of related indicators" stix_report.header.short_description = "A short description for the indicators oooooh!" stix_report.header.information_source = stix_header_information_source # IP address for susip in resolvedIPs: stix_package.add(susIP(susip)) stix_report.add_indicator(Indicator()) # IPs found as static strings in the file for IP in foundIPs: stix_package.add(susIPfound(IP)) stix_report.add_indicator(Indicator()) # TCP Connection attempt and Connection established for tcp in synConn: if tcp not in ackConn: stix_package.add(TCPConnectionAttemptFailedObj(tcp)) stix_report.add_indicator(Indicator()) for tcpest in synConn: if tcpest in synackConn and tcpest in ackConn: stix_package.add(TCPConnectionEstablishedObj(tcpest)) stix_report.add_indicator(Indicator()) # Full HTTP Request for ht in fullHTTPArray: stix_package.add(HTTPFullObj(ht)) stix_report.add_indicator(Indicator()) # UDP Connection for udp in udpconn: if udp[0] != '53' and udp[ 1] != '53': # ignore DNS UDP packets (they are logged else where) stix_package.add(UDPRequestObj(udp)) stix_report.add_indicator(Indicator()) # DNS Connection for dns in dnspacket: stix_package.add(DNSRequestObj(dns)) stix_report.add_indicator(Indicator()) # ICMP Connection for icmp in icmpPacket: if icmp[0] == 0 or icmp[0] == 8: stix_package.add(ICMPObj(icmp)) stix_report.add_indicator(Indicator()) # FTP Connection for ftp in ftpconn: if ftp[4] == '220' or ftp[4] == '230' or ftp[4] == '250': stix_package.add(FTPObj(ftp)) stix_report.add_indicator(Indicator()) elif ftp[5] == "USER" or ftp[5] == "PASS" or ftp[5] == "STOR" or ftp[ 5] == "RETR": stix_package.add(FTPObj(ftp)) stix_report.add_indicator(Indicator()) # SSH Connection for ssh in sshconn: stix_package.add(SSHObj(ssh)) stix_report.add_indicator(Indicator()) stix_package.add_report(stix_report) IOCStix = open( folderPath + "/" + str(results["target"]["file"]["name"]) + ".xml", 'w') IOCStix.write(stix_package.to_xml()) IOCStix.close()
class PackageBuilder(object): def __init__(self, alert): self.__urls = set() self.__domains = set() self.__ipv4 = set() self.__hashes = set() self.__regkeys = set() self.__files = set() self.__emails = set() PRODUCER_NAME = alert.product # Domains domain_indicator = Indicator() domain_indicator.title = "Malware Artifacts - Domain" domain_indicator.type = "Malware Artifacts" domain_indicator.description = ("Domains derived from sandboxed malware sample. AlertID: %d" % alert.id) domain_indicator.short_description = ("Domains from %d" % alert.id) domain_indicator.set_producer_identity(PRODUCER_NAME) domain_indicator.set_produced_time(utils.dates.now()) domain_indicator.indicator_types.append(IndicatorType_1_1.TERM_DOMAIN_WATCHLIST) self.domain_indicator = domain_indicator # IPs ip_indicator = Indicator() ip_indicator.title = "Malware Artifacts - IP" ip_indicator.description = ("IPs derived from sandboxed malware sample. AlertID: %d" % alert.id) ip_indicator.short_description = ("IPs from %d" % alert.id) ip_indicator.set_producer_identity(PRODUCER_NAME) ip_indicator.set_produced_time(utils.dates.now()) ip_indicator.indicator_types.append(IndicatorType_1_1.TERM_IP_WATCHLIST) self.ip_indicator = ip_indicator # URLs url_indicator = Indicator() url_indicator.title = "Malware Artifacts - URL" url_indicator.description = ("URLs derived from sandboxed malware sample. AlertID: %d" % alert.id) url_indicator.short_description = ("URLs from %d" % alert.id) url_indicator.set_producer_identity(PRODUCER_NAME) url_indicator.set_produced_time(utils.dates.now()) url_indicator.indicator_types.append(IndicatorType_1_1.TERM_URL_WATCHLIST) self.url_indicator = url_indicator # Hashs hash_indicator = Indicator() hash_indicator.title = "Malware Artifacts - Files" hash_indicator.description = ("Files derived from sandboxed malware sample. AlertID: %d" % alert.id) hash_indicator.short_description = ("File from %d" % alert.id) hash_indicator.set_producer_identity(PRODUCER_NAME) hash_indicator.set_produced_time(utils.dates.now()) hash_indicator.indicator_types.append(IndicatorType_1_1.TERM_FILE_HASH_WATCHLIST) self.hash_indicator = hash_indicator # Registry reg_indicator = Indicator() reg_indicator.title = "Malware Artifacts - Registry entries" reg_indicator.description = ("File hashes derived from sandboxed malware sample. AlertID: %d" % alert.id) reg_indicator.short_description = ("Registry entries from %d" % alert.id) reg_indicator.set_producer_identity(PRODUCER_NAME) reg_indicator.set_produced_time(utils.dates.now()) reg_indicator.indicator_types.append(IndicatorType_1_1.TERM_MALWARE_ARTIFACTS) self.reg_indicator = reg_indicator # email_indicator email_indicator = Indicator() email_indicator.title = "Malware Artifacts - Malicious " email_indicator.description = ("Email headers. AlertID: %d" % alert.id) email_indicator.short_description = ("Email headers from %d" % alert.id) email_indicator.set_producer_identity(PRODUCER_NAME) email_indicator.set_produced_time(utils.dates.now()) email_indicator.indicator_types.append(IndicatorType_1_1.TERM_MALICIOUS_EMAIL ) self.email_indicator = email_indicator # Create a STIX Package self.stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader({"Indicators - Malware Artifacts"}) stix_header.description = "FireEye Sample ID %d" % alert.id self.stix_package.stix_header = stix_header 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 __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." # FIXME TODO 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 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 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 add_email_observable(self, headers): e = EmailMessage() h = EmailHeader.from_dict(headers) e.header = h self.__emails.add(e) email_observable = Observable(e) self.email_indicator.add_observable(email_observable) def finalize(self): # Add those to the package if len(self.__domains) > 0: self.stix_package.add(self.domain_indicator) if len(self.__ipv4) > 0: self.stix_package.add(self.ip_indicator) if len(self.__urls) > 0: self.stix_package.add(self.url_indicator) if len(self.__hashes) > 0: self.stix_package.add(self.hash_indicator) if len(self.__regkeys) > 0: self.stix_package.add(self.reg_indicator) if len(self.__emails) > 0: self.stix_package.add(self.email_indicator)
def create_stix_file(): # List of indicators to be deduped hostnames = [] ips = [] urls = [] md5s = [] sha1s = [] # Set namespace NAMESPACE = {PRODUCER_URL: PRODUCER_NAME} set_id_namespace(NAMESPACE) # JSON load the POSTed request data try: data_recv = request.data data = json.loads(data_recv) except: return make_response(jsonify({"Error": "Unable to decode json object"}), 400) # Parse the JSON object try: # Get MD5 of sample malware_sample = data["alert"]["explanation"]["malware-detected"]["malware"] count = 0 sample_hash = "" try: for entry in malware_sample: if "md5sum" in malware_sample[count]: sample_hash = malware_sample[count]["md5sum"] count += 1 except: if "md5sum" in malware_sample: sample_hash = malware_sample["md5sum"] # If all else fails if sample_hash == "": sample_hash = "Unknown" # Indicators # Domains domain_indicator = Indicator() domain_indicator.title = "Malware Artifacts - Domain" domain_indicator.type = "Malware Artifacts" domain_indicator.description = "Domains derived from sandboxed malware sample. MD5 Hash: " + sample_hash domain_indicator.short_description = "Domainss from " + sample_hash domain_indicator.set_producer_identity(PRODUCER_NAME) domain_indicator.set_produced_time(utils.dates.now()) domain_indicator.indicator_types.append("Domain Watchlist") # IPs ip_indicator = Indicator() ip_indicator.title = "Malware Artifacts - IP" ip_indicator.description = "IPs derived from sandboxed malware sample. MD5 Hash: " + sample_hash ip_indicator.short_description = "IPs from " + sample_hash ip_indicator.set_producer_identity(PRODUCER_NAME) ip_indicator.set_produced_time(utils.dates.now()) ip_indicator.indicator_types.append("IP Watchlist") # URLs url_indicator = Indicator() url_indicator.title = "Malware Artifacts - URL" url_indicator.description = "URLs derived from sandboxed malware sample. MD5 Hash: " + sample_hash url_indicator.short_description = "URLs from " + sample_hash url_indicator.set_producer_identity(PRODUCER_NAME) url_indicator.set_produced_time(utils.dates.now()) url_indicator.indicator_types.append("URL Watchlist") # Hashs hash_indicator = Indicator() hash_indicator.title = "Malware Artifacts - File Hash" hash_indicator.description = "File hashes derived from sandboxed malware sample. MD5 Hash: " + sample_hash hash_indicator.short_description = "Hash from " + sample_hash hash_indicator.set_producer_identity(PRODUCER_NAME) hash_indicator.set_produced_time(utils.dates.now()) hash_indicator.indicator_types.append("File Hash Watchlist") # Create a STIX Package stix_package = STIXPackage() # Create the STIX Header and add a description. stix_header = STIXHeader({"Indicators - Malware Artifacts"}) stix_header.description = PRODUCER_NAME + ": FireEye Sample ID " + str(data["alert"]["id"]) stix_package.stix_header = stix_header if "network" in data["alert"]["explanation"]["os-changes"]: # Add indicators for network for entry in data["alert"]["explanation"]["os-changes"]["network"]: if "hostname" in entry: hostnames.append(entry["hostname"]) if "ipaddress" in entry: ips.append(entry["ipaddress"]) if "http_request" in entry: domain = re.search("~~Host:\s(.*?)~~", entry["http_request"]) url = re.search("^.*\s(.*?)\sHTTP", entry["http_request"]) if domain: domain_name = domain.group(1) if url: url_string = url.group(1) urls.append(domain_name + url_string) # Add indicators for files for entry in data["alert"]["explanation"]["os-changes"]["network"]: if "md5sum" in entry["processinfo"]: filename = re.search("([\w-]+\..*)", entry["processinfo"]["imagepath"]) if filename: md5s.append((filename.group(1), entry["processinfo"]["md5sum"])) if "process" in data["alert"]["explanation"]["os-changes"]: # Add indicators from process for entry in data["alert"]["explanation"]["os-changes"]["process"]: if "md5sum" in entry: filename = re.search("([\w-]+\..*)", entry["value"]) if filename: md5s.append((filename.group(1), entry["md5sum"])) if "sha1sum" in entry: filename = re.search("([\w-]+\..*)", entry["value"]) if filename: sha1s.append((filename.group(1), entry["sha1sum"])) # Dedupe lists for hostname in set(hostnames): hostname_observable = create_domain_name_observable(hostname) domain_indicator.add_observable(hostname_observable) for ip in set(ips): ip_observable = create_ipv4_observable(ip) ip_indicator.add_observable(ip_observable) for url in set(urls): url_observable = create_url_observable(url) url_indicator.add_observable(url_observable) for hash in set(md5s): hash_observable = create_file_hash_observable(hash[0], hash[1]) hash_indicator.add_observable(hash_observable) for hash in set(sha1s): hash_observable = create_file_hash_observable(hash[0], hash[1]) hash_indicator.add_observable(hash_observable) # Add those to the package stix_package.add(domain_indicator) stix_package.add(ip_indicator) stix_package.add(url_indicator) stix_package.add(hash_indicator) # Save to file save_as = SAVE_DIRECTORY + "/fireeye_" + str(data["alert"]["id"]) + ".xml" f = open(save_as, "w") f.write(stix_package.to_xml()) f.close # Return success response return make_response(jsonify({"Success": "STIX document succesfully generated"}), 200) # Unable to parse object except: return make_response(jsonify({"Error": "Unable to parse JSON object"}), 400)
def main(): # Create a CybOX File Object with a contained hash f = File() f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "File Hash Example" indicator.description = ( "An indicator containing a File observable with an associated hash" ) indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(utils.dates.now()) # Add The File Object to the Indicator. This will promote the CybOX Object # to a CybOX Observable internally. indicator.add_object(f) # Build our STIX CIQ Identity object party_name = stix_ciq.PartyName( name_lines=("Foo", "Bar"), person_names=("John Smith", "Jill Smith"), organisation_names=("Foo Inc.", "Bar Corp.") ) ident_spec = stix_ciq.STIXCIQIdentity3_0(party_name=party_name) ident_spec.add_electronic_address_identifier("*****@*****.**") ident_spec.add_free_text_line("Demonstrating Free Text!") ident_spec.add_contact_number("555-555-5555") ident_spec.add_contact_number("555-555-5556") # Build and add a CIQ Address addr = stix_ciq.Address( free_text_address='1234 Example Lane.', country='USA', administrative_area='An Admin Area' ) ident_spec.add_address(addr) # Build and add a nationality nationality = stix_ciq.Country("Norway") ident_spec.add_nationality(nationality) identity = stix_ciq.CIQIdentity3_0Instance(specification=ident_spec) # Set the Indicator producer identity to our CIQ Identity indicator.set_producer_identity(identity) # Build our STIX Package stix_package = STIXPackage() # Build a STIX Header and add a description stix_header = STIXHeader() stix_header.description = "STIX CIQ Identity Extension Example" # Set the STIX Header on our STIX Package stix_package.stix_header = stix_header # Add our Indicator object. The add() method will inspect the input and # append it to the `stix_package.indicators` collection. stix_package.add(indicator) # Print the XML! print(stix_package.to_xml()) # Print a dictionary! pprint(stix_package.to_dict())
#!/usr/bin/env python # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. """ Description: Build a STIX Indicator document containing a File observable with an associated hash. """ from stix.core import STIXPackage# Imporet the STIX Package API from stix.report import Report# Import the STIX Report API from stix.report.header import Header# Import the STIX Report Header API stix_package = STIXPackage()# Create an instance of STIX stix_report = Report()# Create a Report instance stix_report.header = Header()# Create a header for the report stix_report.header.description = "Getting Started!"# Set the description stix_package.add(stix_report)# Add the report to our STIX Package print(stix_package.to_xml())