def ICMPObj(icmp): # block types 0 (ping response), 8 (ping request) nc = NetworkConnection() indicator = Indicator() nc.layer3_protocol = "ICMP" if icmp[0] == 0: # echo-reply if icmp[1] != VMIP: # incoming reply from a server VM pinged ssocketaddress = SocketAddress() ssocketaddress.ip_address = icmp[1] nc.source_socket_address = ssocketaddress indicator.title = "ICMP echo-reply" indicator.description = ("0") else: # outgoing reply to a server that pinged you dsocketaddress = SocketAddress() dsocketaddress.ip_address = icmp[2] nc.destination_socket_address = dsocketaddress indicator.title = "ICMP echo-reply" indicator.description = ("0") elif icmp[0] == 8: # echo-request if icmp[1] != VMIP: # incoming ping request from a server ssocketaddress = SocketAddress() ssocketaddress.ip_address = icmp[1] nc.source_socket_address = ssocketaddress indicator.title = "ICMP echo-request" indicator.description = ("8") else: # VM is sending a ping request dsocketaddress = SocketAddress() dsocketaddress.ip_address = icmp[2] nc.destination_socket_address = dsocketaddress indicator.title = "ICMP echo-request" indicator.description = ("8") indicator.set_produced_time(utils.dates.now()) indicator.add_object(nc) return indicator
def resolveObjects(incident, ttps, objects, eventTags, org): for obj in objects: tmp_incident = Incident() resolveAttributes(tmp_incident, ttps, obj["Attribute"], eventTags, org) indicator = Indicator( timestamp=getDateFromTimestamp(int(obj["timestamp"]))) indicator.id_ = namespace[1] + ":MispObject-" + obj["uuid"] setProd(indicator, org) if obj["comment"] != "": indicator.description = obj["comment"] tlpTags = eventTags for attr in obj["Attribute"]: tlpTags = mergeTags(tlpTags, attr) setTLP(indicator, obj["distribution"], tlpTags, True) indicator.title = obj["name"] + " (MISP Object #" + obj["id"] + ")" indicator.description = indicator.title indicator.add_indicator_type("Malware Artifacts") indicator.add_valid_time_position(ValidTime()) indicator.observable_composition_operator = "AND" for rindicator in tmp_incident.related_indicators: if rindicator.item.observable: indicator.add_observable(rindicator.item.observable) relatedIndicator = RelatedIndicator(indicator, relationship=obj["meta-category"]) incident.related_indicators.append(relatedIndicator)
def SSHObj(SSH): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" networkconnection.layer7_protocol = "SSH" if SSH[0] != VMIP and SSH[4] == 1 and SSH[5] == 0: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = SSH[0] sport = Port() sport.port_value = SSH[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif SSH[2] != VMIP and SSH[4] == 1 and SSH[5] == 0: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = SSH[2] dport = Port() dport.port_value = SSH[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator = Indicator() if SSH[6] != '': indicator.title = "SSH Request with pulic key" indicator.description = ("SSH public key: " + SSH[6]) else: indicator.title = "SSH Request" indicator.description = ( "An indicator containing information about a SSH request") indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def generateIndicator(attribute): indicator = Indicator(timestamp=getDateFromTimestamp(int(attribute["timestamp"]))) indicator.id_= namespace[1] + ":indicator-" + attribute["uuid"] if attribute["comment"] != "": indicator.description = attribute["comment"] setTLP(indicator, attribute["distribution"]) indicator.title = attribute["category"] + ": " + attribute["value"] + " (MISP Attribute #" + attribute["id"] + ")" indicator.description = indicator.title confidence_description = "Derived from MISP's IDS flag. If an attribute is marked for IDS exports, the confidence will be high, otherwise none" confidence_value = confidence_mapping.get(attribute["to_ids"], None) if confidence_value is None: return indicator indicator.confidence = Confidence(value=confidence_value, description=confidence_description, timestamp=getDateFromTimestamp(int(attribute["timestamp"]))) return indicator
def generate_indicator(self, attribute, tags, org): indicator = Indicator(timestamp=attribute.timestamp) indicator.id_ = "{}:indicator-{}".format(namespace[1], attribute.uuid) self.set_prod(indicator, org) if attribute.comment: indicator.description = attribute.comment self.set_tlp(indicator, attribute.distribution, self.merge_tags(tags, attribute)) indicator.title = "{}: {} (MISP Attribute #{})".format(attribute.category, attribute.value, attribute.id) indicator.description = indicator.title confidence_description = "Derived from MISP's IDS flag. If an attribute is marked for IDS exports, the confidence will be high, otherwise none" confidence_value = confidence_mapping.get(attribute.to_ids, None) if confidence_value is None: return indicator indicator.confidence = Confidence(value=confidence_value, description=confidence_description, timestamp=attribute.timestamp) return indicator
def _dostix(hashes): '''This function creates a STIX packages containing hashes.''' print("[+] Creating STIX Package") title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now()) _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix']) stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = title stix_package.stix_header.handling = _marking() try: indicator = Indicator() indicator.set_producer_identity(SETTINGS['stix']['producer']) indicator.set_produced_time(indicator.timestamp) indicator.set_received_time(indicator.timestamp) indicator.add_kill_chain_phase(PHASE_DELIVERY) indicator.confidence = "Low" indicator.title = title indicator.add_indicator_type("File Hash Watchlist") indicator.description = SETTINGS['stix']['ind_desc'] try: indicator.add_indicated_ttp( TTP(idref=SETTINGS['indicated_ttp'], timestamp=indicator.timestamp)) indicator.suggested_coas.append( CourseOfAction(idref=SETTINGS['suggested_coa'], timestamp=indicator.timestamp)) except KeyError: pass for info in hashes: try: file_name = info['filename'] file_object = File() file_object.file_name = file_name file_object.file_name.condition = "Equals" file_object.file_extension = "." + file_name.split('.')[-1] file_object.file_extension.condition = "Equals" file_object.size_in_bytes = info['filesize'] file_object.size_in_bytes.condition = "Equals" file_object.file_format = info['fileformat'] file_object.file_format.condition = "Equals" file_object.add_hash(Hash(info['md5'])) file_object.add_hash(Hash(info['sha1'])) file_object.add_hash(Hash(info['sha256'])) file_object.add_hash(Hash(info['sha512'])) file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP)) for hashobj in file_object.hashes: hashobj.simple_hash_value.condition = "Equals" hashobj.type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + file_name indicator.add_observable(file_obs) except TypeError: pass stix_package.add_indicator(indicator) return stix_package except KeyError: pass
def 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 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 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(): # 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 test_indicator(self): i = Indicator() i.title = UNICODE_STR i.description = UNICODE_STR i.short_description = UNICODE_STR i2 = round_trip(i) self._test_equal(i, i2)
def UDPRequestObj(udpinfo): u = NetworkConnection() u.layer3_protocol = "IPv4" u.layer4_protocol = "UDP" ssocketaddress = SocketAddress() if udpinfo[3] != VMIP: ssocketaddress.ip_address = udpinfo[3] sport = Port() sport.port_value = udpinfo[0] sport.layer4_protocol = "UDP" ssocketaddress.port = sport u.source_socket_address = ssocketaddress dsocketaddress = SocketAddress() if udpinfo[2] != VMIP: dsocketaddress.ip_address = udpinfo[2] dport = Port() dport.port_value = udpinfo[1] dport.layer4_protocol = "UDP" dsocketaddress.port = dport u.destination_socket_address = dsocketaddress indicator = Indicator() indicator.title = "UDP connection" indicator.description = ( "An indicator containing information about a UDP connection") indicator.set_produced_time(utils.dates.now()) indicator.add_object(u) return indicator
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 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 DNSRequestObj(dnsinfo): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "UDP" networkconnection.layer7_protocol = "DNS" ssocketaddress = SocketAddress() sport = Port() sport.port_value = dnsinfo[1] sport.layer4_protocol = "UDP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress dsocketaddress = SocketAddress() dsocketaddress.ip_address = dnsinfo[2] dport = Port() dport.port_value = dnsinfo[3] dport.layer4_protocol = "UDP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress layer7connections = Layer7Connections() dqr = DNSQuery() indicator = Indicator() dnsques = DNSQuestion() dnsques.qname = dnsinfo[4] dnsques.qtype = translateType(dnsinfo[5]) dqr.question = dnsques indicator.title = "DNS Request" indicator.description = ( "An indicator containing information about a DNS Request") layer7connections.dns_query = dqr networkconnection.layer7_connections = layer7connections indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def create_indicator(self, ce1sus_indicator, event_permissions, user): indicator = Indicator() indicator.id_ = 'ce1sus:Indicator-{0}'.format(ce1sus_indicator.uuid) indicator.title = ce1sus_indicator.title indicator.description = ce1sus_indicator.description indicator.short_description = ce1sus_indicator.short_description if ce1sus_indicator.confidence: indicator.confidence = ce1sus_indicator.confidence.title() else: indicator.confidence = 'Low' # TODO: handling # TODO: markings for type_ in ce1sus_indicator.types: indicator.add_indicator_type(type_.name) if ce1sus_indicator.operator: indicator.observable_composition_operator = ce1sus_indicator.operator # Todo Add confidence # indicator_attachment.confidence = "Low" creator = self.create_stix_identity(ce1sus_indicator) time = self.cybox_mapper.get_time( produced_time=ce1sus_indicator.created_at) info_source = InformationSource(identity=creator, time=time) indicator.producer = info_source observables = ce1sus_indicator.get_observables_for_permissions( event_permissions, user) for obs in observables: cybox_obs = self.create_observable(obs, event_permissions, user) indicator.add_observable(cybox_obs) valid_time = ValidTime(start_time=ce1sus_indicator.created_at, end_time=ce1sus_indicator.created_at) indicator.add_valid_time_position(valid_time) return indicator
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 main(): f = File() f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now(tzutc())) indicator.add_object(f) party_name = PartyName(name_lines=["Foo", "Bar"], person_names=["John Smith", "Jill Smith"], organisation_names=["Foo Inc.", "Bar Corp."]) ident_spec = 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") identity = CIQIdentity3_0Instance(specification=ident_spec) indicator.set_producer_identity(identity) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example 05" stix_package.stix_header = stix_header stix_package.add_indicator(indicator) xml = stix_package.to_xml() print(xml)
def TCPConnectionEstablishedObj(tcpinfo): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" if tcpinfo[0] != VMIP: # incoming connection networkconnection.destination_tcp_state = "ESTABLISHED" ssocketaddress = SocketAddress() ssocketaddress.ip_address = tcpinfo[0] sport = Port() sport.port_value = tcpinfo[2] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif tcpinfo[1] != VMIP: # outgoing connection networkconnection.source_tcp_state = "ESTABLISHED" dsocketaddress = SocketAddress() dsocketaddress.ip_address = tcpinfo[1] dport = Port() dport.port_value = tcpinfo[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator = Indicator() indicator.title = "TCP Connection Established" indicator.description = ( "An indicator containing information about a successful TCP hand shake" ) indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def main(): f = File() f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now(tzutc())) indicator.add_object(f) party_name = PartyName(name_lines=["Foo", "Bar"], person_names=["John Smith", "Jill Smith"], organisation_names=["Foo Inc.", "Bar Corp."]) ident_spec = 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") identity = CIQIdentity3_0Instance(specification=ident_spec) indicator.set_producer_identity(identity) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example" stix_package.stix_header = stix_header stix_package.add_indicator(indicator) xml = stix_package.to_xml() print(xml)
def main(): # get args parser = argparse.ArgumentParser( description="Parse an input JSON file and output STIX XML ", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("infile",help="input file") parser.add_argument("--outfile","-o", help="output file") args = parser.parse_args() # We assume the input file is a flat JSON file # format 'bot_name':[list,of,ips] content = json.load(open(args.infile)) # Set up STIX document stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = "C2 Server IP Addresses" stix_header.add_package_intent (PackageIntent.TERM_INDICATORS_WATCHLIST) stix_package.stix_header = stix_header # Create Indicator and TTP for each item in JSON document for item in content: # Create TTP for C2 server ttp = TTP() ttp.title = item stix_package.add_ttp(ttp) # Create Indicator for C2 IP addresses indicator = Indicator() indicator.title = "IP addresses for known C2 channel" indicator.description = "Bot connecting to control server" # Add IPs for C2 node addr = Address(address_value=content[item], category=Address.CAT_IPV4) addr.address_value.condition= "Equals" indicator.add_object(addr) # Relate Indicator and TTP indicator.add_indicated_ttp(TTP(idref=ttp.id_)) # Add Indicator to STIX PAckage stix_package.add_indicator(indicator) # Output to given file # The context manager is just to make the output look nicer by ignoring # warnings from to_xml() with warnings.catch_warnings(): warnings.simplefilter("ignore") stix_out = stix_package.to_xml() if args.outfile: fd = open(args.outfile,'w') fd.write(stix_out) else: print stix_out
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 generateIndicator(attribute): indicator = Indicator(timestamp=getDateFromTimestamp(int(attribute["timestamp"]))) indicator.id_ = namespace[1] + ":indicator-" + attribute["uuid"] if attribute["comment"] != "": indicator.description = attribute["comment"] setTLP(indicator, attribute["distribution"]) indicator.title = attribute["category"] + ": " + attribute["value"] + " (MISP Attribute #" + attribute["id"] + ")" indicator.description = indicator.title confidence_description = "Derived from MISP's IDS flag. If an attribute is marked for IDS exports, the confidence will be high, otherwise none" confidence_value = confidence_mapping.get(attribute["to_ids"], None) if confidence_value is None: return indicator indicator.confidence = Confidence( value=confidence_value, description=confidence_description, timestamp=getDateFromTimestamp(int(attribute["timestamp"])), ) return indicator
def susIPfound(ip): a = Address() a.address_value = ip a.category = a.CAT_IPV4 indicator = Indicator() indicator.title = "Suspicious IP address" indicator.description = ( "An indicator containing a suspicious IPv4 address found statically in the sample" ) indicator.set_produced_time(utils.dates.now()) indicator.add_object(a) return indicator
def _add_stix_indicators(self, final_indicator_objects, ttp_id): """Create and add STIX Indicators for a list of Object History entries. Link each Indicator to their Indicated TTP. Note: Each STIX Indicator is added to the STIX Package stored in the ``stix_package`` class member. Args: final_indicator_objects: a list of ``maec.bundle.object_history.ObjectHistoryEntry`` objects representing the final, pruned list of Objects to be used in the STIX Indicators. ttp_id: the id of the STIX TTP that each STIX Indicator should reference as its Indicated TTP. """ object_values_list = [] actions_list = [] final_object_list = [] # Deduplicate the Objects and combine their Actions for entry in final_indicator_objects: object = entry.object # Test if we've already created an Indicator for this Object obj_values = BundleDeduplicator.get_object_values(object) if obj_values not in object_values_list: object_values_list.append(obj_values) final_object_list.append(object) actions_list.append(entry.get_action_names()) else: object_index = object_values_list.index(obj_values) existing_actions = actions_list[object_index] existing_actions += entry.get_action_names() # Create the STIX Indicators for object in final_object_list: object_index = final_object_list.index(object) indicator = Indicator() indicator.title = "Malware Artifact Extracted from MAEC Document" indicator.add_indicator_type("Malware Artifacts") indicator.add_observable(object.properties) # Add the Action-derived description to the Indicator description = "Corresponding Action(s): " for action_name in actions_list[object_index]: description += (action_name + ", ") indicator.description = description[:-2] # Set the proper Confidence on the Indicator confidence = Confidence() confidence.value = "Low" confidence.description = "Tool-generated Indicator. It is HIGHLY recommended that it be vetted by a human analyst before usage." indicator.confidence = confidence # Link the Indicator to its Indicated TTP ttp = TTP(idref=ttp_id) indicator.add_indicated_ttp(ttp) # Add the Indicator to the STIX Package self.stix_package.add_indicator(indicator)
def domainNameobj(domain): # cybox stuff d = DomainName() d.value = domain # stix stuff indicator1 = Indicator() indicator1.title = "Domain name" indicator1.description = ( "An indicator containing a suspicious domain name") indicator1.set_produced_time(utils.dates.now()) indicator1.add_object(d) return indicator1
def susIP(ip): a = Address() a.address_value = ip a.category = a.CAT_IPV4 indicator = Indicator() indicator.title = "Suspicious IP address" indicator.description = ( "An indicator containing a IPv4 address resolved from a suspicious domain" ) indicator.set_produced_time(utils.dates.now()) indicator.add_object(a) return indicator
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 to_stix_rfi(obj): from stix.indicator import Indicator as S_Ind list_rfis = [] for each in obj.rfi: ind = S_Ind() ind.title = "CRITs RFI" ind.timestamp = each.date ind.description = each.topic ind.id_ = each.source list_rfis.append(ind) for item in each.instance: ind_2 = S_Ind() ind_2.title = "CRITs RFI" ind_2.timestamp = each.date ind_2.description = each.topic ind_2.producer = to_source(item) ind_2.id_ = each.source list_rfis.append(ind_2) return list_rfis
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 to_stix_relationship(obj): from stix.indicator import Indicator ind_rel = [] for relationship in obj.relationships: #if not relationship.private: #testing ind = Indicator() ind.title = "MARTI Relation" ind.timestamp = relationship.relationship_date ind.confidence = relationship.rel_confidence.title() ind.id_ = relationship.url_key ind.add_indicator_type(get_indicator_type(relationship.rel_type)) ind.description = relationship.rel_reason ind.short_description = relationship.relationship ind_rel.append(ind) return ind_rel
def buildIndicator(input_dict): indicator = Indicator() indicator.description = input_dict["description"] if input_dict["confidence"]: indicator.confidence = input_dict["confidence"] if input_dict["impact"]: indicator.likely_impact = input_dict["impact"] if input_dict["producer"]: indicator.producer = InformationSource() indicator.producer.identity = Identity(input_dict["producer"]) indicator.title = input_dict["title"] indicator.add_valid_time_position(valid_time.ValidTime(input_dict["starttime"], input_dict["endtime"])) if input_dict["type"]: indicator.add_indicator_type(input_dict["type"]) return indicator
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 to_stix_comments(obj): from crits.comments.handlers import get_comments from stix.indicator import Indicator as S_Ind comments = get_comments(obj.id, obj._meta['crits_type'], False) ind_comments = [] for each in comments: if not each.private: ind = S_Ind() ind.title = "CRITs Comment(s)" ind.description = each.comment ind.short_description = each.url_key ind.producer = to_stix_information_source(each) ind.timestamp = each.edit_date #should be date, but for some reason, it's not getting the correct value ind_comments.append(ind) return ind_comments
def main(): f = File() # This automatically detects that it's an MD5 hash based on the length f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now(tzutc())) indicator.add_object(f) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example " stix_package.stix_header = stix_header stix_package.add_indicator(indicator) print(stix_package.to_xml())
def test_markable_text_nodes(self): """Test that text selector is used on resulting xpath. Does not check for accuracy of marked data.""" container = stixmarx.new() package = container.package red_marking = generate_marking_spec(generate_red_marking_struct()) indicator = Indicator(title="Test") # STIX 1.1.1 doesn't have multiple descriptions indicator.description = "Test description" observable = generate_observable() indicator.add_observable(observable) package.add_indicator(indicator) observable.object_.properties.address_value.value = \ container.add_marking( observable.object_.properties.address_value.value, red_marking ) indicator.description.value = \ container.add_marking( indicator.description.value, red_marking ) self.assertTrue(package.stix_header is None) self.assertTrue(package.indicators[0].handling is None) container.flush() self.assertTrue(package.stix_header is None) self.assertTrue(package.indicators[0].handling is not None) for marking in package.indicators[0].handling.marking: selector = marking.controlled_structure.split("/")[-1] self.assertTrue("text()" == selector) print(package.to_xml().decode("utf-8"))
def main(): shv = Hash() shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F" f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now()) indicator.add_object(f) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example 02" stix_package.stix_header = stix_header stix_package.add_indicator(indicator) print(stix_package.to_xml())
def main(): stix_pkg = STIXPackage() # make indicator ind = Indicator() ind.title = "Malicious executable" ind.description = "Resident binary which implements infostealing and credit card grabber" # link to "Installation" phase and kill chain by ID values infect = KillChainPhase(name="Infect Machine") exfil = KillChainPhase(name="Exfiltrate Data") mychain = KillChain(name="Organization-specific Kill Chain") mychain.kill_chain_phases = [infect, exfil] stix_pkg.ttps.kill_chains.append(mychain) stix_pkg.add_indicator(ind) # add referenced phase to indicator ind.kill_chain_phases.append(KillChainPhaseReference(phase_id=infect.phase_id,kill_chain_id = mychain.id_)) print stix_pkg.to_xml()
def main(): f = File() f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") indicator = Indicator() indicator.title = "File Hash Example" indicator.description = "An indicator containing a File observable with an associated hash" indicator.set_producer_identity("The MITRE Corporation") indicator.set_produced_time(datetime.now()) indicator.add_object(f) party_name = PartyName(name_lines=["Foo", "Bar"], person_names=["John Smith", "Jill Smith"], organisation_names=["Foo Inc.", "Bar Corp."]) ident_spec = STIXCIQIdentity3_0(party_name=party_name) identity = CIQIdentity3_0Instance(specification=ident_spec) indicator.set_producer_identity(identity) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Example 05" stix_package.stix_header = stix_header stix_package.add_indicator(indicator) print(stix_package.to_xml())
def stix(json): """ Created a stix file based on a json file that is being handed over """ # Create a new STIXPackage stix_package = STIXPackage() # Create a new STIXHeader stix_header = STIXHeader() # Add Information Source. This is where we will add the tool information. stix_header.information_source = InformationSource() # Create a ToolInformation object. Use the initialization parameters # to set the tool and vendor names. # # Note: This is an instance of cybox.common.ToolInformation and NOT # stix.common.ToolInformation. tool = ToolInformation( tool_name="viper2stix", tool_vendor="The Viper group http://viper.li - developed by Alexander Jaeger https://github.com/deralexxx/viper2stix" ) #Adding your identity to the header identity = Identity() identity.name = Config.get('stix', 'producer_name') stix_header.information_source.identity=identity # Set the Information Source "tools" section to a # cybox.common.ToolInformationList which contains our tool that we # created above. stix_header.information_source.tools = ToolInformationList(tool) stix_header.title = Config.get('stix', 'title') # Set the produced time to now stix_header.information_source.time = Time() stix_header.information_source.time.produced_time = datetime.now() marking_specification = MarkingSpecification() marking_specification.controlled_structure = "../../../descendant-or-self::node()" tlp = TLPMarkingStructure() tlp.color = Config.get('stix', 'TLP') marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) # Set the header description stix_header.description = Config.get('stix', 'description') # Set the STIXPackage header stix_package.stix_header = stix_header stix_package.stix_header.handling = handling try: pp = pprint.PrettyPrinter(indent=5) pp.pprint(json['default']) #for key, value in json['default'].iteritems(): # print key, value for item in json['default']: #logger.debug("item %s", item) indicator = Indicator() indicator.title = "File Hash" indicator.description = ( "An indicator containing a File observable with an associated hash" ) # Create a CyboX File Object f = File() sha_value = item['sha256'] if sha_value is not None: sha256 = Hash() sha256.simple_hash_value = sha_value h = Hash(sha256, Hash.TYPE_SHA256) f.add_hash(h) sha1_value = item['sha1'] if sha_value is not None: sha1 = Hash() sha1.simple_hash_value = sha1_value h = Hash(sha1, Hash.TYPE_SHA1) f.add_hash(h) sha512_value = item['sha512'] if sha_value is not None: sha512 = Hash() sha512.simple_hash_value = sha512_value h = Hash(sha512, Hash.TYPE_SHA512) f.add_hash(h) f.add_hash(item['md5']) #adding the md5 hash to the title as well stix_header.title+=' '+item['md5'] #print(item['type']) f.size_in_bytes=item['size'] f.file_format=item['type'] f.file_name = item['name'] indicator.description = "File hash served by a Viper instance" indicator.add_object(f) stix_package.add_indicator(indicator) except Exception, e: logger.error('Error: %s',format(e)) return False
def 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())
def _dostix(hashes): '''This function creates a STIX packages containing hashes.''' print("[+] Creating STIX Package") title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now()) _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix']) stix_package = STIXPackage() stix_package.stix_header = STIXHeader() stix_package.stix_header.title = title stix_package.stix_header.handling = _marking() try: indicator = Indicator() indicator.set_producer_identity(SETTINGS['stix']['producer']) indicator.set_produced_time(indicator.timestamp) indicator.set_received_time(indicator.timestamp) indicator.add_kill_chain_phase(PHASE_DELIVERY) indicator.confidence = "Low" indicator.title = title indicator.add_indicator_type("File Hash Watchlist") indicator.description = SETTINGS['stix']['ind_desc'] try: indicator.add_indicated_ttp( TTP(idref=SETTINGS['indicated_ttp'], timestamp=indicator.timestamp)) indicator.suggested_coas.append( CourseOfAction( idref=SETTINGS['suggested_coa'], timestamp=indicator.timestamp)) except KeyError: pass for info in hashes: try: file_name = info['filename'] file_object = File() file_object.file_name = file_name file_object.file_name.condition = "Equals" file_object.file_extension = "." + file_name.split('.')[-1] file_object.file_extension.condition = "Equals" file_object.size_in_bytes = info['filesize'] file_object.size_in_bytes.condition = "Equals" file_object.file_format = info['fileformat'] file_object.file_format.condition = "Equals" file_object.add_hash(Hash(info['md5'])) file_object.add_hash(Hash(info['sha1'])) file_object.add_hash(Hash(info['sha256'])) file_object.add_hash(Hash(info['sha512'])) file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP)) for hashobj in file_object.hashes: hashobj.simple_hash_value.condition = "Equals" hashobj.type_.condition = "Equals" file_obs = Observable(file_object) file_obs.title = "File: " + file_name indicator.add_observable(file_obs) except TypeError: pass stix_package.add_indicator(indicator) return stix_package except KeyError: pass
def genStixDoc( outputDir_, targetFileSha1_, targetFileSha256_, targetFileSha512_, targetFileSsdeep_, targetFileMd5_, targetFileSize_, targetFileName_, ipv4Addresses_, hostNames_): """ Generate Stix document from the input values. The doc structure is the file object along with the related network items: addresses, domain names. Output is written to files, which are then wrapped with taxii and uploaded using a separate script. """ parsedTargetFileName = reFileName(targetFileName_)[1] parsedTargetFilePrefix = reFileName(targetFileName_)[0] stix.utils.set_id_namespace({"http://www.equifax.com/cuckoo2Stix" : "cuckoo2Stix"}) NS = cybox.utils.Namespace("http://www.equifax.com/cuckoo2Stix", "cuckoo2Stix") cybox.utils.set_id_namespace(NS) stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = 'File: ' + parsedTargetFileName + ' with the associated hashes, network indicators' stix_header.description = 'File: ' + parsedTargetFileName + ' with the associated hashes, network indicators' stix_package.stix_header = stix_header # Create the ttp malware_instance = MalwareInstance() malware_instance.add_name(parsedTargetFileName) malware_instance.description = targetFileSha1_ ttp = TTP(title='TTP: ' + parsedTargetFileName) ttp.behavior = Behavior() ttp.behavior.add_malware_instance(malware_instance) stix_package.add_ttp(ttp) # Create the indicator for the ipv4 addresses ipv4Object = Address(ipv4Addresses_, Address.CAT_IPV4) ipv4Object.condition = 'Equals' ipv4Indicator = Indicator() ipv4Indicator.title = parsedTargetFileName + ': ipv4 addresses' ipv4Indicator.add_indicator_type('IP Watchlist') ipv4Indicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship='Indicates Malware')) ipv4Indicator.observable = ipv4Object ipv4Indicator.confidence = 'Low' # Create the indicator for the domain names domainNameObject = DomainName() domainNameObject.value = hostNames_ domainNameObject.condition = 'Equals' domainNameIndicator = Indicator() domainNameIndicator.title = parsedTargetFileName + ': domain names' domainNameIndicator.add_indicator_type('Domain Watchlist') domainNameIndicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship='Indicates Malware')) domainNameIndicator.observable = domainNameObject domainNameIndicator.confidence = 'Low' # Create the indicator for the file fileObject = File() fileObject.file_name = parsedTargetFileName fileObject.file_name.condition = 'Equals' fileObject.size_in_bytes = targetFileSize_ fileObject.size_in_bytes.condition = 'Equals' fileObject.add_hash(Hash(targetFileSha1_, type_='SHA1', exact=True)) fileObject.add_hash(Hash(targetFileSha256_, type_='SHA256', exact=True)) fileObject.add_hash(Hash(targetFileSha512_, type_='SHA512', exact=True)) fileObject.add_hash(Hash(targetFileSsdeep_, type_='SSDEEP', exact=True)) fileObject.add_hash(Hash(targetFileMd5_, type_='MD5', exact=True)) fileIndicator = Indicator() fileIndicator.title = parsedTargetFileName + ': hashes' fileIndicator.description = parsedTargetFilePrefix fileIndicator.add_indicator_type('File Hash Watchlist') fileIndicator.add_indicated_ttp(RelatedTTP(TTP(idref=ttp.id_), relationship="Indicates Malware")) fileIndicator.observable = fileObject fileIndicator.confidence = 'Low' stix_package.indicators = [fileIndicator, ipv4Indicator, domainNameIndicator] stagedStixDoc = stix_package.to_xml() stagedStixDoc = fixAddressObject(stagedStixDoc) stagedStixDoc = fixDomainObject(stagedStixDoc) today = datetime.datetime.now() now = today.strftime('%Y-%m-%d_%H%M%S') if not os.path.exists(outputDir_): os.makedirs(outputDir_) with open (outputDir_ + '/' + now + '-' + targetFileSha1_ + '.stix.xml', 'a') as myfile: myfile.write(stagedStixDoc) _l.debug('Wrote file: ' + now + '-' + targetFileSha1_ + '.stix.xml') return
def main(): # NOTE: ID values will differ due to being regenerated on each script execution pkg1 = STIXPackage() pkg1.title = "Example of Indicator Composition for an aggregate indicator composition" # USE CASE: Indicator with aggregate pattern # Add TTP for malware usage malware_ttp = TTP() malware_ttp.behavior = Behavior() malware = MalwareInstance() malware.title = "foobar malware" malware.add_type("Remote Access Trojan") malware_ttp.behavior.add_malware_instance(malware) c2_ttp = TTP() c2_ttp.resources = Resource() c2_ttp.resources.infrastructure = Infrastructure() c2_ttp.resources.infrastructure.add_type(VocabString("Malware C2")) pkg1.add_ttp(c2_ttp) pkg1.add_ttp(malware_ttp) nw_ind = Indicator() nw_ind.description = "Indicator for a particular C2 infstructure IP address." # add network network connection to this indicator obs = NetworkConnection() sock = SocketAddress() sock.ip_address = "46.123.99.25" sock.ip_address.category = "ipv4-addr" sock.ip_address.condition = "Equals" obs.destination_socket_address = sock nw_ind.add_observable(obs) nw_ind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) # create File Hash indicator w/ embedded Observable file_ind = Indicator() file_ind.description = "Indicator for the hash of the foobar malware." file_ind.add_indicator_type("File Hash Watchlist") file_obs = File() file_obs.add_hash("01234567890abcdef01234567890abcdef") file_obs.hashes[0].type_ = "MD5" file_obs.hashes[0].type_.condition = "Equals" file_ind.add_observable(file_obs) # create references file_ind.add_indicated_ttp(TTP(idref=malware_ttp.id_)) # create container indicator ind = Indicator() ind.add_indicator_type(VocabString("Campaign Characteristics")) ind.description = "Indicator for a composite of characteristics for the use of specific malware and C2 infrastructure within a Campaign." # Add campaign with related camp = Campaign() camp.title = "holy grail" pkg1.add_campaign(camp) camp.related_ttps.append(TTP(idref=c2_ttp.id_)) camp.related_ttps.append(TTP(idref=malware_ttp.id_)) # Add threat actor ta = ThreatActor() ta.identity = Identity() ta.identity.name = "boobear" ta.observed_ttps.append(TTP(idref=malware_ttp.id_)) pkg1.add_threat_actor(ta) # Create composite expression ind.composite_indicator_expression = CompositeIndicatorExpression() ind.composite_indicator_expression.operator = "AND" ind.composite_indicator_expression.append(file_ind) ind.composite_indicator_expression.append(nw_ind) pkg1.add_indicator(ind) print pkg1.to_xml() # USE CASE: Indicator with partial matching pkg2 = STIXPackage() pkg2.title = "Example of Indicator Composition for a one of many indicator composition" # create container indicator watchlistind = Indicator() watchlistind.add_indicator_type("IP Watchlist") watchlistind.description = "This Indicator specifies a pattern where any one or more of a set of three IP addresses are observed." watchlistind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) # Create composite expression watchlistind.composite_indicator_expression = CompositeIndicatorExpression() watchlistind.composite_indicator_expression.operator = "OR" ips = ['23.5.111.68', '23.5.111.99', '46.123.99.25'] for ip in ips: new_ind = Indicator() new_ind.description = "This Indicator specifies a pattern where one specific IP address is observed" # add network network connection to this indicator obs = Address() obs.address_value = ip obs.address_value.condition = "Equals" new_ind.add_observable(obs) new_ind.add_indicated_ttp(TTP(idref=c2_ttp.id_)) watchlistind.composite_indicator_expression.append(new_ind) pkg2.add_indicator(watchlistind) print pkg2.to_xml() # USE CASE: Indicator with compound detection pkg3 = STIXPackage() pkg3.title = "Example of Indicator Composition for compound detection" # create container indicator watchlistind2 = Indicator() watchlistind2.add_indicator_type("IP Watchlist") watchlistind2.description = "This Indicator specifies a composite condition of two preexisting Indicators (each identifying a particular TTP with low confidence) that in aggregate identify the particular TTP with high confidence." # Create composite expression watchlistind2.composite_indicator_expression = CompositeIndicatorExpression() watchlistind2.composite_indicator_expression.operator = "OR" watchlistind2.add_indicated_ttp(TTP(idref=c2_ttp.id_)) watchlistind2.confidence = "High" nw_ind.description = "Indicator for a particular C2 IP address used by a malware variant." nw_ind.confidence = "Low" nw_ind.indicator_types = ["C2"] file_ind.description = "Indicator that contains malicious file hashes for a particular malware variant." file_ind.confidence = "Low" watchlistind2.composite_indicator_expression.append(nw_ind) watchlistind2.composite_indicator_expression.append(file_ind) pkg3.add_indicator(watchlistind2) print pkg3.to_xml()
def transform(self, event): self._set_namespace(self.config['contact_domain'], self.config['contact_name']) stix_package = STIXPackage() self._add_header(stix_package, "Unauthorized traffic to honeypot", "Describes one or more honeypot incidents") incident = Incident(id_="%s:%s-%s" % (self.config['contact_name'], 'incident', event['session_id'])) initial_time = StixTime() initial_time.initial_compromise = event['timestamp'].isoformat() incident.time = initial_time incident.title = "Conpot Event" incident.short_description = "Traffic to Conpot ICS honeypot" incident.add_category(VocabString(value='Scans/Probes/Attempted Access')) tool_list = ToolInformationList() tool_list.append(ToolInformation.from_dict({ 'name': "Conpot", 'vendor': "Conpot Team", 'version': conpot.__version__, 'description': textwrap.dedent('Conpot is a low interactive server side Industrial Control Systems ' 'honeypot designed to be easy to deploy, modify and extend.') })) incident.reporter = InformationSource(tools=tool_list) incident.add_discovery_method("Monitoring Service") incident.confidence = "High" # Victim Targeting by Sector ciq_identity = CIQIdentity3_0Instance() #identity_spec = STIXCIQIdentity3_0() #identity_spec.organisation_info = OrganisationInfo(industry_type="Electricity, Industrial Control Systems") #ciq_identity.specification = identity_spec ttp = TTP(title="Victim Targeting: Electricity Sector and Industrial Control System Sector") ttp.victim_targeting = VictimTargeting() ttp.victim_targeting.identity = ciq_identity incident.leveraged_ttps.append(ttp) indicator = Indicator(title="Conpot Event") indicator.description = "Conpot network event" indicator.confidence = "High" source_port = Port.from_dict({'port_value': event['remote'][1], 'layer4_protocol': 'tcp'}) dest_port = Port.from_dict({'port_value': self.protocol_to_port_mapping[event['data_type']], 'layer4_protocol': 'tcp'}) source_ip = Address.from_dict({'address_value': event['remote'][0], 'category': Address.CAT_IPV4}) dest_ip = Address.from_dict({'address_value': event['public_ip'], 'category': Address.CAT_IPV4}) source_address = SocketAddress.from_dict({'ip_address': source_ip.to_dict(), 'port': source_port.to_dict()}) dest_address = SocketAddress.from_dict({'ip_address': dest_ip.to_dict(), 'port': dest_port.to_dict()}) network_connection = NetworkConnection.from_dict( {'source_socket_address': source_address.to_dict(), 'destination_socket_address': dest_address.to_dict(), 'layer3_protocol': u"IPv4", 'layer4_protocol': u"TCP", 'layer7_protocol': event['data_type'], 'source_tcp_state': u"ESTABLISHED", 'destination_tcp_state': u"ESTABLISHED", } ) indicator.add_observable(Observable(network_connection)) artifact = Artifact() artifact.data = json.dumps(event['data']) artifact.packaging.append(ZlibCompression()) artifact.packaging.append(Base64Encoding()) indicator.add_observable(Observable(artifact)) incident.related_indicators.append(indicator) stix_package.add_incident(incident) stix_package_xml = stix_package.to_xml() return stix_package_xml
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 __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 to_stix(obj, items_to_convert=[], loaded=False, bin_fmt="raw"): """ Converts a CRITs object to a STIX document. The resulting document includes standardized representations of all related objects noted within items_to_convert. :param items_to_convert: The list of items to convert to STIX/CybOX :type items_to_convert: Either a list of CRITs objects OR a list of {'_type': CRITS_TYPE, '_id': CRITS_ID} dicts :param loaded: Set to True if you've passed a list of CRITs objects as the value for items_to_convert, else leave False. :type loaded: bool :param bin_fmt: Specifies the format for Sample data encoding. Options: None (don't include binary data in STIX output), "raw" (include binary data as is), "base64" (base64 encode binary data) :returns: A dict indicating which items mapped to STIX indicators, ['stix_indicators'] which items mapped to STIX observables, ['stix_observables'] which items are included in the resulting STIX doc, ['final_objects'] and the STIX doc itself ['stix_obj']. """ from cybox.common import Time, ToolInformationList, ToolInformation from stix.common import StructuredText, InformationSource from stix.core import STIXPackage, STIXHeader from stix.common.identity import Identity # These lists are used to determine which CRITs objects # go in which part of the STIX document. ind_list = ['Indicator'] obs_list = ['Certificate', 'Domain', 'Email', 'IP', 'PCAP', 'RawData', 'Sample'] actor_list = ['Actor'] # Store message stix_msg = { 'stix_incidents': [], 'stix_indicators': [], 'stix_observables': [], 'stix_actors': [], 'final_objects': [] } if not loaded: # if we have a list of object metadata, load it before processing items_to_convert = [class_from_id(item['_type'], item['_id']) for item in items_to_convert] # add self to the list of items to STIXify if obj not in items_to_convert: items_to_convert.append(obj) # add any email attachments attachments = [] for obj in items_to_convert: if obj._meta['crits_type'] == 'Email': for rel in obj.relationships: if rel.relationship == RelationshipTypes.CONTAINS: atch = class_from_id('Sample', rel.object_id) if atch not in items_to_convert: attachments.append(atch) items_to_convert.extend(attachments) # grab ObjectId of items refObjs = {key.id: 0 for key in items_to_convert} relationships = {} stix = [] from stix.indicator import Indicator as S_Ind for obj in items_to_convert: obj_type = obj._meta['crits_type'] if obj_type == class_from_type('Event')._meta['crits_type']: stx, release = to_stix_incident(obj) stix_msg['stix_incidents'].append(stx) elif obj_type in ind_list: # convert to STIX indicators stx, releas = to_stix_indicator(obj) stix_msg['stix_indicators'].append(stx) refObjs[obj.id] = S_Ind(idref=stx.id_) elif obj_type in obs_list: # convert to CybOX observable if obj_type == class_from_type('Sample')._meta['crits_type']: stx, releas = to_cybox_observable(obj, bin_fmt=bin_fmt) else: stx, releas = to_cybox_observable(obj) # wrap in stix Indicator ind = S_Ind() for ob in stx: ind.add_observable(ob) ind.title = "CRITs %s Top-Level Object" % obj_type ind.description = ("This is simply a CRITs %s top-level " "object, not actually an Indicator. " "The Observable is wrapped in an Indicator" " to facilitate documentation of the " "relationship." % obj_type) ind.confidence = 'None' stx = ind stix_msg['stix_indicators'].append(stx) refObjs[obj.id] = S_Ind(idref=stx.id_) elif obj_type in actor_list: # convert to STIX actor stx, releas = to_stix_actor(obj) stix_msg['stix_actors'].append(stx) # get relationships from CRITs objects for rel in obj.relationships: if rel.object_id in refObjs: relationships.setdefault(stx.id_, {}) relationships[stx.id_][rel.object_id] = (rel.relationship, rel.rel_confidence.capitalize(), rel.rel_type) stix_msg['final_objects'].append(obj) stix.append(stx) # set relationships on STIX objects for stix_obj in stix: for rel in relationships.get(stix_obj.id_, {}): if isinstance(refObjs.get(rel), S_Ind): # if is STIX Indicator stix_obj.related_indicators.append(refObjs[rel]) rel_meta = relationships.get(stix_obj.id_)[rel] stix_obj.related_indicators[-1].relationship = rel_meta[0] stix_obj.related_indicators[-1].confidence = rel_meta[1] # Add any Email Attachments to CybOX EmailMessage Objects if isinstance(stix_obj, S_Ind): if 'EmailMessage' in stix_obj.observable.object_.id_: if rel_meta[0] == 'Contains' and rel_meta[2] == 'Sample': email = stix_obj.observable.object_.properties email.attachments.append(refObjs[rel].idref) tool_list = ToolInformationList() tool = ToolInformation("CRITs", "MITRE") tool.version = settings.CRITS_VERSION tool_list.append(tool) i_s = InformationSource( time=Time(produced_time= datetime.now()), identity=Identity(name=settings.COMPANY_NAME), tools=tool_list) if obj._meta['crits_type'] == "Event": stix_desc = obj.description() stix_int = obj.event_type() stix_title = obj.title() else: stix_desc = "STIX from %s" % settings.COMPANY_NAME stix_int = "Collective Threat Intelligence" stix_title = "Threat Intelligence Sharing" header = STIXHeader(information_source=i_s, description=StructuredText(value=stix_desc), package_intents=[stix_int], title=stix_title) stix_msg['stix_obj'] = STIXPackage(incidents=stix_msg['stix_incidents'], indicators=stix_msg['stix_indicators'], threat_actors=stix_msg['stix_actors'], stix_header=header, id_=uuid.uuid4()) return stix_msg
def build(self): self.stix_header.title = self.pulse["name"] self.stix_header.description = self.pulse["description"] self.stix_header.short_description = "%spulse/%s" % (PULSE_SERVER_BASE, str(self.pulse["id"])) self.stix_header.package_intents.append(PackageIntent.TERM_INDICATORS) self.stix_header.information_source = InformationSource() self.stix_header.information_source.time = Time() self.stix_header.information_source.description = "Alienvault OTX - https://otx.alienvault.com/" self.stix_header.information_source.time.produced_time = self.pulse["modified"] self.stix_header.information_source.identity = Identity() self.stix_header.information_source.identity.name = "Alienvault OTX" self.stix_package.stix_header = self.stix_header hashes = [] addresses = [] domains = [] urls = [] mails = [] for p_indicator in self.pulse["indicators"]: if p_indicator["type"] in self.hash_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) file_ = File() hash_ = Hash(p_indicator["indicator"], self.hash_translation[p_indicator["type"]]) file_.add_hash(hash_) observable_ = Observable(file_) elif p_indicator["type"] in self.address_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) ipv4_ = Address.from_dict({'address_value': p_indicator["indicator"], 'category': self.address_translation[p_indicator["type"]]}) observable_ = Observable(ipv4_) elif p_indicator["type"] in self.name_translation: new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) domain_ = DomainName.from_dict({'value': p_indicator["indicator"], 'type':'FQDN'}) observable_ = Observable(domain_) elif p_indicator["type"] == "URL": new_ind = Indicator() new_ind.description = p_indicator["description"] new_ind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) url_ = URI.from_dict({'value': p_indicator["indicator"], 'type': URI.TYPE_URL}) observable_ = Observable(url_) elif p_indicator["type"] == "email": email_ = Address.from_dict({'address_value': p_indicator["indicator"], 'category': Address.CAT_EMAIL}) observable_ = Observable(email_) #elif p_indicator["type"] == "CVE": # vuln_ = Vulnerability() # vuln_.cveid = p_indicator["indicator"].upper() # observable_ = Observable(vuln_) elif p_indicator["type"] == "Mutex": mutex_ = Mutex.from_dict({'named': True, 'name': p_indicator["indicator"]}) observable_ = Observable(mutex_) elif p_indicator["type"] == "CIDR": nrange = IP(p_indicator["indicator"]) nrange_values = nrange.strNormal(3).replace("-", ",") ipv4_ = Address.from_dict({'address_value': nrange_values, 'category': Address.CAT_IPV4}) ipv4_.address_value.condition = "InclusiveBetween" observable_ = Observable(ipv4_) else: continue mind = Indicator() mind.description = p_indicator["description"] mind.title = "%s from %spulse/%s" % (p_indicator["indicator"], PULSE_SERVER_BASE, str(self.pulse["id"])) observable_.title = "%s - %s" % (p_indicator["type"], p_indicator["indicator"]) mind.add_observable(observable_) self.stix_package.add_indicator(mind)
def _create_indicator(self, d): def _md5(keypair): shv = Hash() shv.simple_hash_value = keypair.get('observable') f = File() h = Hash(shv, Hash.TYPE_MD5) f.add_hash(h) return f def _sha1(keypair): shv = Hash() shv.simple_hash_value = keypair.get('observable') f = File() h = Hash(shv, Hash.TYPE_SHA1) f.add_hash(h) return f def _sha256(keypair): shv = Hash() shv.simple_hash_value = keypair.get('observable') f = File() h = Hash(shv, Hash.TYPE_SHA256) f.add_hash(h) return f def _address_ipv4(address): if re.search('^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}', address): return 1 def _address_fqdn(address): if re.search('^[a-zA-Z0-9.\-_]+\.[a-z]{2,6}$', address): return 1 def _address_url(address): if re.search('^(ftp|https?):\/\/', address): return 1 def _address(keypair): address = keypair.get('observable') if _address_fqdn(address): return Address(address, 'fqdn') elif _address_ipv4(address): return Address(address, 'ipv4-addr') elif _address_url(address): return Address(address, 'url') indicator = Indicator(timestamp=arrow.get(d.get('reporttime')).datetime) indicator.set_producer_identity(d.get('provider')) indicator.set_produced_time(arrow.utcnow().datetime) indicator.description = ','.join(d.get('tags')) otype = d.get('otype') if otype == 'md5': f = _md5(d) elif otype == 'sha1': f = _sha1(d) elif otype == 'sha256': f = _sha256(d) else: f = _address(d) indicator.add_object(f) return indicator
def main(): # get args parser = argparse.ArgumentParser ( description = "Parse a given CSV from Shadowserver and output STIX XML to stdout" , formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("--infile","-f", help="input CSV with bot data", default = "bots.csv") args = parser.parse_args() # setup stix document stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = "Bot Server IP addresses" stix_header.description = "IP addresses connecting to bot control servers at a given port" stix_header.add_package_intent ("Indicators - Watchlist") # add marking mark = Marking() markspec = MarkingSpecification() markstruct = SimpleMarkingStructure() markstruct.statement = "Usage of this information, including integration into security mechanisms implies agreement with the Shadowserver Terms of Service available at https://www.shadowserver.org/wiki/pmwiki.php/Shadowserver/TermsOfService" markspec.marking_structures.append(markstruct) mark.add_marking(markspec) stix_header.handling = mark # include author info stix_header.information_source = InformationSource() stix_header.information_source.time = Time() stix_header.information_source.time.produced_time =datetime.now(tzutc()) stix_header.information_source.tools = ToolInformationList() stix_header.information_source.tools.append("ShadowBotnetIP-STIXParser") stix_header.information_source.identity = Identity() stix_header.information_source.identity.name = "MITRE STIX Team" stix_header.information_source.add_role(VocabString("Format Transformer")) src = InformationSource() src.description = "https://www.shadowserver.org/wiki/pmwiki.php/Services/Botnet-CCIP" srcident = Identity() srcident.name = "shadowserver.org" src.identity = srcident src.add_role(VocabString("Originating Publisher")) stix_header.information_source.add_contributing_source(src) stix_package.stix_header = stix_header # add TTP for overall indicators bot_ttp = TTP() bot_ttp.title = 'Botnet C2' bot_ttp.resources = Resource() bot_ttp.resources.infrastructure = Infrastructure() bot_ttp.resources.infrastructure.title = 'Botnet C2' stix_package.add_ttp(bot_ttp) # read input data fd = open (args.infile, "rb") infile = csv.DictReader(fd) for row in infile: # split indicators out, may be 1..n with positional storage, same port and channel, inconsistent delims domain = row['Domain'].split() country = row['Country'].split() region = row['Region'].split('|') state = row['State'].split('|') asn = row['ASN'].split() asname = row['AS Name'].split() asdesc = row['AS Description'].split('|') index = 0 for ip in row['IP Address'].split(): indicator = Indicator() indicator.title = "IP indicator for " + row['Channel'] indicator.description = "Bot connecting to control server" # point to overall TTP indicator.add_indicated_ttp(TTP(idref=bot_ttp.id_)) # add our IP and port sock = SocketAddress() sock.ip_address = ip # add sighting sight = Sighting() sight.timestamp = "" obs = Observable(item=sock.ip_address) obsref = Observable(idref=obs.id_) sight.related_observables.append(obsref) indicator.sightings.append(sight) stix_package.add_observable(obs) # add pattern for indicator sock_pattern = SocketAddress() sock_pattern.ip_address = ip port = Port() port.port_value = row['Port'] sock_pattern.port = port sock_pattern.ip_address.condition= "Equals" sock_pattern.port.port_value.condition= "Equals" indicator.add_object(sock_pattern) stix_package.add_indicator(indicator) # add domain domain_obj = DomainName() domain_obj.value = domain[index] domain_obj.add_related(sock.ip_address,"Resolved_To", inline=False) stix_package.add_observable(domain_obj) # add whois obs whois_obj = WhoisEntry() registrar = WhoisRegistrar() registrar.name = asname[index] registrar.address = state[index] + region[index] + country[index] whois_obj.registrar_info = registrar whois_obj.add_related(sock.ip_address,"Characterizes", inline=False) stix_package.add_observable(whois_obj) # add ASN obj asn_obj = AutonomousSystem() asn_obj.name = asname[index] asn_obj.number = asn[index] asn_obj.handle = "AS" + str(asn[index]) asn_obj.add_related(sock.ip_address,"Contains", inline=False) stix_package.add_observable(asn_obj) # iterate index = index + 1 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)