def resolveIPType(attribute_value, attribute_type): address_object = Address() cidr = False if ("|" in attribute_value): attribute_value = attribute_value.split('|')[0] if ("/" in attribute_value): ip = attribute_value.split('/')[0] cidr = True else: ip = attribute_value try: socket.inet_aton(ip) ipv4 = True except socket.error: ipv4 = False if (cidr == True): address_object.category = "cidr" condition = "Contains" elif (ipv4 == True): address_object.category = "ipv4-addr" condition = "Equals" else: address_object.category = "ipv6-addr" condition = "Equals" if attribute_type.startswith("ip-src"): address_object.is_source = True address_object.is_destination = False if attribute_type.startswith("ip-dst"): address_object.is_source = False address_object.is_destination = True address_object.address_value = attribute_value address_object.condition = condition return address_object
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 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(): mydata = loaddata() ''' Your Namespace ''' # NAMESPACE = {sanitizer(mydata["NSXURL"]) : (mydata["NS"])} # set_id_namespace(NAMESPACE) NAMESPACE = Namespace(sanitizer(mydata['NSXURL']), sanitizer(mydata['NS'])) set_id_namespace(NAMESPACE) # new ids will be prefixed by "myNS" wrapper = STIXPackage() info_src = InformationSource() info_src.identity = Identity(name=sanitizer(mydata["Identity"])) marking_specification = MarkingSpecification() marking_specification.controlled_structure = "//node() | //@*" tlp = TLPMarkingStructure() tlp.color = sanitizer(mydata["TLP_COLOR"]) marking_specification.marking_structures.append(tlp) handling = Marking() handling.add_marking(marking_specification) timestamp = datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S') MyTITLE = sanitizer(mydata["Title"]) SHORT = timestamp DESCRIPTION = sanitizer(mydata["Description"]) wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE, description=DESCRIPTION, short_description=SHORT) wrapper.stix_header.handling = handling indiDom = Indicator() indiDom.title = MyTITLE indiDom.add_indicator_type("IP Watchlist") for key in mydata["IOC"].keys(): myip = Address(address_value=sanitizer(key), category=Address.CAT_IPV4) myip.condition = "Equals" obsu = Observable(myip) #if mydata[key].size: for idx, mydata["IOC"][key] in enumerate(mydata["IOC"][key]): ioc = File() ioc.add_hash(sanitizer(mydata["IOC"][key])) myip.add_related(ioc, "Downloaded") indiDom.add_observable(obsu) wrapper.add_indicator(indiDom) print(wrapper.to_xml())
def gen_ips(self, count): '''Generate list of IP Addresses''' ip_addresses = [] for i in range(0, count): addr = Address(address_value=self.fake.ipv4(), category=Address.CAT_IPV4) addr.condition = 'Equals' ip_addresses.append(addr) return ip_addresses
def create_ip_indicator(self, ip_indicator): indicator = Indicator() indicator.title = 'IP address of site hosting malware' indicator.add_indicator_type('IP Watchlist') addr = Address(address_value=ip_indicator, category=Address.CAT_IPV4) addr.condition = 'Equals' indicator.add_observable(addr) return indicator
def create_ip_indicator(self, ip_indicator): indicator = Indicator() indicator.title = 'IP address of site hosting malware' indicator.add_indicator_type('IP Watchlist') addr = Address(address_value=ip_indicator, category=Address.CAT_IPV4) addr.condition = 'Equals' indicator.add_observable(addr) return indicator
def stix(self): """Output data as STIX. STIX is highly subjective and difficult to format without getting more data from the user. Passive DNS results are formtted into a STIX watchlist with descriptions and other details about the record. :return: STIX formatted watchlist """ if python3: raise RuntimeError("STIX is not supported when using Python 3 due to dependency libraries.") stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "Passive DNS resolutions associated" \ " with %s during the time periods of " \ " %s - %s" % (self.queryValue, self.firstSeen, self.lastSeen) stix_package.stix_header = stix_header for record in self._records: indicator = Indicator( title="Observed from %s - %s" % ( record.firstSeen, record.lastSeen ), short_description="Resolution observed by %s." % ( ','.join(record.source) ), description="Passive DNS data collected and aggregated from" \ " PassiveTotal services." ) if is_ip(record.resolve): indicator.add_indicator_type('IP Watchlist') ioc = Address( address_value=record.resolve, category=Address.CAT_IPV4 ) else: indicator.add_indicator_type('Domain Watchlist') ioc = DomainName(value=record.resolve) ioc.condition = "Equals" indicator.add_observable(ioc) stix_package.add_indicator(indicator) output = stix_package.to_xml() return output
def main(): stix_package = STIXPackage() ttp = TTP(title="C2 Behavior") indicator = Indicator(title="IP Address for known C2 Channel") indicator.add_indicator_type("IP Watchlist") addr = Address(address_value="10.0.0.0", category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_ttp(ttp) print(stix_package.to_xml(encoding=None))
def main(): stix_package = STIXPackage() ttp = TTP(title="C2 Behavior") indicator = Indicator(title="IP Address for known C2 Channel") indicator.add_indicator_type("IP Watchlist") addr = Address(address_value="10.0.0.0", category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) stix_package.add_ttp(ttp) print(stix_package.to_xml(encoding=None))
def main(): data = json.load(open("data.json")) stix_package = STIXPackage(stix_header=STIXHeader( title=data['title'], package_intents='Incident')) ttps = {} for info in data['ips']: # Add TTP, unless it's already been added if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) # Add indicator indicator = Indicator(title=info['ip']) addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_)) stix_package.add_indicator(indicator) # Add incident incident = Incident(title=info['ip']) incident.time = Time() incident.time.first_malicious_action = info['first_seen'] addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) observable = Observable(item=addr) stix_package.add_observable(observable) related_ttp = RelatedTTP(TTP(idref=ttps[info['bot']].id_), relationship="Used Malware") incident.leveraged_ttps.append(related_ttp) related_observable = RelatedObservable( Observable(idref=observable.id_)) incident.related_observables.append(related_observable) related_indicator = RelatedIndicator(Indicator(idref=indicator.id_)) incident.related_indicators.append(related_indicator) stix_package.add_incident(incident) print(stix_package.to_xml(encoding=None))
def main(): data = json.load(open("data.json")) stix_package = STIXPackage(stix_header=STIXHeader(title=data['title'], package_intents='Incident')) ttps = {} for info in data['ips']: # Add TTP, unless it's already been added if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) # Add indicator indicator = Indicator(title=info['ip']) addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_)) stix_package.add_indicator(indicator) # Add incident incident = Incident(title=info['ip']) incident.time = Time() incident.time.first_malicious_action = info['first_seen'] addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) observable = Observable(item=addr) stix_package.add_observable(observable) related_ttp = RelatedTTP(TTP(idref=ttps[info['bot']].id_), relationship="Used Malware") incident.leveraged_ttps.append(related_ttp) related_observable = RelatedObservable(Observable(idref=observable.id_)) incident.related_observables.append(related_observable) related_indicator = RelatedIndicator(Indicator(idref=indicator.id_)) incident.related_indicators.append(related_indicator) stix_package.add_incident(incident) print stix_package.to_xml()
def main(): fileIn = open('tor_exit_node_list.txt', 'r') fileOut = open('tor_stix.xml', 'w') #print("List of Tor Exit nodes as of 5/4/2018") ip_addr_list = [] for line in fileIn: ip_addr = re.search( '(([2][5][0-5]\.)|([2][0-4][0-9]\.)|([0-1]?[0-9]?[0-9]\.)){3}(([2][5][0-5])|([2][0-4][0-9])|([0-1]?[0-9]?[0-9]))', line) if ip_addr: ip_addr_list.append(ip_addr) #print(" ", ip_addr.group(0)) stix_package = STIXPackage() ttp = TTP(title="Tor Exit Nodes") i = 0 for ip_addr in ip_addr_list: indicator = Indicator(title="IP Address for known Tor exit Node") indicator.add_indicator_type("IP Watchlist") addr = Address(address_value=ip_addr.group(0), category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttp.id_)) stix_package.add_indicator(indicator) print(i) i = i + 1 stix_package.add_ttp(ttp) #print(stix_package.to_xml(encoding=None)) fileOut.write(stix_package.to_xml(encoding=None))
def resolve_ip_type(attribute_type, attribute_value): address_object = Address() if '|' in attribute_value: attribute_value = attribute_value.split('|')[0] if '/' in attribute_value: attribute_value = attribute_value.split('/')[0] address_object.category = "cidr" condition = "Contains" else: try: socket.inet_aton(attribute_value) address_object.category = "ipv4-addr" except socket.error: address_object.category = "ipv6-addr" condition = "Equals" if attribute_type.startswith("ip-src"): address_object.is_source = True address_object.is_destination = False else: address_object.is_source = False address_object.is_destination = True address_object.address_value = attribute_value address_object.condition = condition return address_object
def main(): data = json.load(open("data.json")) stix_package = STIXPackage() ttps = {} for info in data['ips']: if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) indicator = Indicator(title=info['ip']) indicator.add_indicator_type("IP Watchlist") addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_)) stix_package.add_indicator(indicator) print stix_package.to_xml()
def main(): data = json.load(open("data.json")) stix_package = STIXPackage() ttps = {} for info in data['ips']: if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) indicator = Indicator(title=info['ip']) indicator.add_indicator_type("IP Watchlist") addr = Address(address_value=info['ip'], category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_)) stix_package.add_indicator(indicator) print stix_package.to_xml()
def json2observable(config, src, dest, endpoint, json_, crits_id): # TODO split into smaller functions '''transform crits observables into cybox''' try: set_id_method(IDGenerator.METHOD_UUID) xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name'] set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) if endpoint == 'ips': crits_types = { 'Address - cidr': 'cidr', 'Address - ipv4-addr': 'ipv4-addr', 'Address - ipv4-net': 'ipv4-net', 'Address - ipv4-net-mask': 'ipv4-netmask', 'Address - ipv6-addr': 'ipv6-addr', 'Address - ipv6-net': 'ipv6-net', 'Address - ipv6-net-mask': 'ipv6-netmask' } addr = Address(address_value=json_['ip'], category=crits_types[json_['type']]) addr.condition = 'Equals' observable_ = Observable(addr) elif endpoint == 'domains': domain = DomainName() domain.type_ = 'FQDN' domain.value = json_['domain'] domain.condition = 'Equals' observable_ = Observable(domain) elif endpoint == 'samples': crits_types = { 'md5': 'MD5', 'sha1': 'SHA1', 'sha224': 'SHA224', 'sha256': 'SHA256', 'sha384': 'SHA384', 'sha512': 'SHA512', 'ssdeep': 'SSDEEP' } file_object = File() file_object.file_name = json_['filename'] for hash in crits_types.keys(): if hash in json_: file_object.add_hash( Hash(json_[hash], type_=crits_types[hash])) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" observable_ = Observable(file_object) elif endpoint == 'emails': crits_types = { 'subject': 'subject', 'to': 'to', 'cc': 'cc', 'from_address': 'from_', 'sender': 'sender', 'date': 'date', 'message_id': 'message_id', 'reply_to': 'reply_to', 'boundary': 'boundary', 'x_mailer': 'x_mailer', 'x_originating_ip': 'x_originating_ip' } email = EmailMessage() email.header = EmailHeader() for k in crits_types.keys(): val = json_.get(k, None) if val: email.header.__setattr__(crits_types[k], val) email.header.__getattribute__(crits_types[k]).condition = \ 'Equals' observable_ = Observable(email) else: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type=endpoint, id_=crits_id)) return (None) observable_.id = xmlns_name + ':observable-' + crits_id observable_.id_ = observable_.id return (observable_) except: e = sys.exc_info()[0] config['logger'].error(log.log_messages['obj_convert_error'].format( src_type='crits', src_obj='observable', id_=crits_id, dest_type='cybox', dest_obj='observable')) config['logger'].exception(e) return (None)
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(iocs=iocs): stix_header = STIXHeader(title=iocs['title'], description=iocs['desc'], package_intents=["Indicators - Watchlist"]) stix_package = STIXPackage(stix_header=stix_header) # add indicator - file hash if iocs.get('hash'): indicator_file_hash = Indicator(title="Malicious File") indicator_file_hash.add_indicator_type("File Hash Watchlist") for file_hash in iocs['hash']: file_object = File() file_object.add_hash(Hash(file_hash)) file_object.hashes[0].simple_hash_value.condition = "Equals" file_object.hashes[0].type_.condition = "Equals" indicator_file_hash.add_observable(file_object) stix_package.add_indicator(indicator_file_hash) # add indicator - file name if iocs.get('fname'): indicator_filename = Indicator(title="Malicious File Name") for file in iocs['fname']: file_object = File() file_object.file_name = file indicator_filename.add_observable(file_object) stix_package.add_indicator(indicator_filename) # add indicator - ip address if iocs.get('ips'): indicator_ip = Indicator(title="Malicious IP Address") indicator_ip.add_indicator_type("IP Watchlist") for ip in iocs['ips']: addr = Address(address_value=ip, category=Address.CAT_IPV4) addr.condition = "Equals" indicator_ip.add_observable(addr) stix_package.add_indicator(indicator_ip) # add indicator - domains if iocs.get('domains'): indicator_domains = Indicator(title="Malicious Domains") indicator_domains.add_indicator_type("Domain Watchlist") for domain in iocs['domains']: domain_name = DomainName() domain_name.value = domain indicator_domains.add_observable(domain_name) stix_package.add_indicator(indicator_domains) # add indicator - url if iocs.get('urls'): indicator_url = Indicator(title='Malicious URL') indicator_url.add_indicator_type("URL Watchlist") for _url in iocs['urls']: url = URI() url.value = _url url.type_ = URI.TYPE_URL url.value.condition = "Equals" # url.value.condition = "Contains" indicator_url.add_observable(url) stix_package.add_indicator(indicator_url) # add indicator - email subject if iocs.get('subject'): indicator_email_subject = Indicator(title='Malicious E-mail Subject') indicator_email_subject.add_indicator_type("Malicious E-mail") for subject in iocs['subject']: email_subject_object = EmailMessage() email_subject_object.header = EmailHeader() email_subject_object.header.subject = subject email_subject_object.header.subject.condition = "StartsWith" indicator_email_subject.add_observable(email_subject_object) stix_package.add_indicator(indicator_email_subject) # add indicator - email sender if iocs.get('senders'): indicator_email_sender = Indicator(title='Malicious E-mail Sender') indicator_email_sender.add_indicator_type("Malicious E-mail") for sender in iocs['senders']: email_sender_object = EmailMessage() email_sender_object.header = EmailHeader() email_sender_object.header.sender = sender email_sender_object.header.sender.condition = "Equals" indicator_email_sender.add_observable(email_sender_object) stix_package.add_indicator(indicator_email_sender) # print(stix_package.to_xml(encoding=None)) # print(type(stix_package.to_xml(encoding=None))) return stix_package.to_xml(encoding=None)
def gen_stix_observable_sample( config, target=None, datatype=None, title="random test data", description="random test data", package_intents="Indicators - Watchlist", tlp_color="WHITE", ): """generate sample stix data comprised of indicator_count indicators of type datatype""" # setup the xmlns... xmlns_url = config["edge"]["sites"][target]["stix"]["xmlns_url"] xmlns_name = config["edge"]["sites"][target]["stix"]["xmlns_name"] set_stix_id_namespace({xmlns_url: xmlns_name}) set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) # construct a stix package... stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = title stix_header.description = description stix_header.package_intents = package_intents marking = MarkingSpecification() marking.controlled_structure = "../../../../descendant-or-self::node()" tlp_marking = TLPMarkingStructure() tlp_marking.color = tlp_color marking.marking_structures.append(tlp_marking) stix_package.stix_header = stix_header stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking) # ...and stuff it full of random sample data :-) if datatype == "ip": addr = Address(address_value=datagen_.generate_random_ip_address(), category="ipv4-addr") addr.condition = "Equals" stix_package.add_observable(Observable(addr)) elif datatype == "domain": domain = DomainName() domain.type_ = "FQDN" domain.value = datagen_.generate_random_domain(config) domain.condition = "Equals" stix_package.add_observable(Observable(domain)) elif datatype == "filehash": file_object = File() file_object.file_name = str(uuid.uuid4()) + ".exe" hashes = datagen_.generate_random_hashes() for hash in hashes.keys(): file_object.add_hash(Hash(hashes[hash], type_=hash.upper())) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" stix_package.add_observable(Observable(file_object)) elif datatype == "email": try: msg = datagen_.get_random_spam_msg(config) email = EmailMessage() email.header = EmailHeader() header_map = { "Subject": "subject", "To": "to", "Cc": "cc", "Bcc": "bcc", "From": "from_", "Sender": "sender", "Date": "date", "Message-ID": "message_id", "Reply-To": "reply_to", "In-Reply-To": "in_reply_to", "Content-Type": "content_type", "Errors-To": "errors_to", "Precedence": "precedence", "Boundary": "boundary", "MIME-Version": "mime_version", "X-Mailer": "x_mailer", "User-Agent": "user_agent", "X-Originating-IP": "x_originating_ip", "X-Priority": "x_priority", } # TODO handle received_lines for key in header_map.keys(): val = msg.get(key, None) if val: email.header.__setattr__(header_map[key], val) email.header.__getattribute__(header_map[key]).condition = "Equals" # TODO handle email bodies (it's mostly all there except for # handling weird text encoding problems that were making # libcybox stacktrace) # body = get_email_payload(random_spam_msg) # if body: # email.raw_body = body stix_package.add_observable(Observable(email)) except: return None observable_id = stix_package.observables.observables[0].id_ return (observable_id, stix_package)
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 generate_stix_file(input_file, list_type, delimiter, list_name, tc_name, tmp_dir, validate, verbose): # observable limit per generated stix file OBSERVABLES_PER_STIX_FILE = 3000 if verbose: logging.info("=====================") logging.info("== GENERATING STIX ==") logging.info("=====================") # download or open input file if validators.url(input_file): res = requests.get(input_file) items = res.text.split(delimiter) else: # exit if input file doesn't exist if not os.path.isfile(input_file): logging.error("Supplied input file '{}' doesn't exist".format(input_file)) sys.exit("Error: Supplied input file '{}' doesn't exist".format(input_file)) else: with open(input_file, 'r') as f: items = f.read().split(delimiter) logging.info("Successfully parsed input file at {}".format(input_file)) # slice input into batches for batch_num, index in enumerate(range(0, len(items), OBSERVABLES_PER_STIX_FILE), 1): # slice handles out of bounds indices gracefully batch_items = items[index:index + OBSERVABLES_PER_STIX_FILE] # create the STIX Package package = STIXPackage() # create the STIX Header and add a description header = STIXHeader() package.stix_header = header reporttime = datetime.datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z') # create indicator for each item in the batch for item in batch_items: item = item.strip() # basic filtering of empty items and comments if not item or item.startswith(('#', '//', '--')): continue if list_type == 'ip': indicator_obj = Address() # attempt to parse as an ip address try: parsed_ip = ipaddress.ip_address(item) if parsed_ip.version == 4: indicator_obj.category = Address.CAT_IPV4 elif parsed_ip.version == 6: indicator_obj.category = Address.CAT_IPV6 else: logging.warning("Unknown IP Address version type: {} - skipping".format(parsed_ip.version)) continue except ValueError: # if ip address parsing fails then attempt to parse as an ip network try: parsed_ip = ipaddress.ip_network(item, strict=False) indicator_obj.category = Address.CAT_CIDR except ValueError: logging.warning("IP Address {} is neither an IPv4, IPv6, nor CIDR - skipping".format(item)) continue indicator_obj.address_value = str(parsed_ip) indicator_obj.condition = "Equals" indicator_type = "IP Watchlist" # customizable components below indicator_title = "IP: {}" indicator_description = "IP {} reported from {}" elif list_type == 'domain': # validate domain if validate and not validators.domain(item): logging.warning("Invalid domain: {} - skipping".format(item)) continue indicator_obj = DomainName() indicator_obj.value = item indicator_type = "Domain Watchlist" # customizable components below indicator_title = "Domain: {}" indicator_description = "Domain {} reported from {}" elif list_type == 'url': # validate url if validate and not validators.url(item): logging.warning("Invalid url: {} - skipping".format(item)) continue indicator_obj = URI() indicator_obj.value = item indicator_obj.type_ = URI.TYPE_URL indicator_obj.condition = "Equals" indicator_type = "URL Watchlist" # customizable components below indicator_title = "URL: {}" indicator_description = "URL {} reported from {}" else: # invalid input type logging.error("invalid input type encountered") raise Exception('Error: invalid input type encountered') # create a basic Indicator object from the item indicator = Indicator() indicator.title = indicator_title.format(str(item)) indicator.description = indicator_description.format(str(item), list_name) indicator.add_indicator_type(indicator_type) indicator.set_producer_identity(list_name) indicator.set_produced_time(str(reporttime)) indicator.add_observable(indicator_obj) # add the indicator to the stix package package.add_indicator(indicator) # save each batch in a separate stix file with the filename ending ..._part_N.stix collection_filename = "{}_part_{}.stix".format(strip_non_alphanum(tc_name), batch_num) with open(os.path.join(tmp_dir, collection_filename), 'wb') as f: f.write(package.to_xml()) logging.info("Successfully created stix file {}".format(collection_filename)) # clear cybox cache to prevent an Out of Memory error # https://cybox.readthedocs.io/en/stable/api/cybox/core/object.html#cybox.core.object.Object cache_clear() return
def gen_stix_observable_sample(config, target=None, datatype=None, title='random test data', description='random test data', package_intents='Indicators - Watchlist', tlp_color='WHITE'): '''generate sample stix data comprised of indicator_count indicators of type datatype''' # setup the xmlns... xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name'] set_stix_id_namespace({xmlns_url: xmlns_name}) set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) # construct a stix package... stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = title stix_header.description = description stix_header.package_intents = package_intents marking = MarkingSpecification() marking.controlled_structure = '../../../../descendant-or-self::node()' tlp_marking = TLPMarkingStructure() tlp_marking.color = tlp_color marking.marking_structures.append(tlp_marking) stix_package.stix_header = stix_header stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking) # ...and stuff it full of random sample data :-) if datatype == 'ip': addr = Address(address_value=datagen.generate_random_ip_address(), category='ipv4-addr') addr.condition = 'Equals' stix_package.add_observable(Observable(addr)) elif datatype == 'domain': domain = DomainName() domain.type_ = 'FQDN' domain.value = datagen.generate_random_domain(config) domain.condition = 'Equals' stix_package.add_observable(Observable(domain)) elif datatype == 'filehash': file_object = File() file_object.file_name = str(uuid.uuid4()) + '.exe' hashes = datagen.generate_random_hashes() for hash in hashes.keys(): file_object.add_hash(Hash(hashes[hash], type_=hash.upper())) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" stix_package.add_observable(Observable(file_object)) elif datatype == 'email': try: msg = datagen.get_random_spam_msg(config) email = EmailMessage() email.header = EmailHeader() header_map = { 'Subject': 'subject', 'To': 'to', 'Cc': 'cc', 'Bcc': 'bcc', 'From': 'from_', 'Sender': 'sender', 'Date': 'date', 'Message-ID': 'message_id', 'Reply-To': 'reply_to', 'In-Reply-To': 'in_reply_to', 'Content-Type': 'content_type', 'Errors-To': 'errors_to', 'Precedence': 'precedence', 'Boundary': 'boundary', 'MIME-Version': 'mime_version', 'X-Mailer': 'x_mailer', 'User-Agent': 'user_agent', 'X-Originating-IP': 'x_originating_ip', 'X-Priority': 'x_priority' } # TODO handle received_lines for key in header_map.keys(): val = msg.get(key, None) if val: email.header.__setattr__(header_map[key], val) email.header.__getattribute__(header_map[key]).condition = \ 'Equals' # TODO handle email bodies (it's mostly all there except for # handling weird text encoding problems that were making # libcybox stacktrace) # body = get_email_payload(random_spam_msg) # if body: # email.raw_body = body stix_package.add_observable(Observable(email)) except: return (None) observable_id = stix_package.observables.observables[0].id_ return (observable_id, stix_package)
def gen_stix_observable_sample(config, target=None, datatype=None, title='random test data', description='random test data', package_intents='Indicators - Watchlist', tlp_color='WHITE'): '''generate sample stix data comprised of indicator_count indicators of type datatype''' # setup the xmlns... xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name'] set_stix_id_namespace({xmlns_url: xmlns_name}) set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) # construct a stix package... stix_package = STIXPackage() stix_header = STIXHeader() stix_header.title = title stix_header.description = description stix_header.package_intents = package_intents marking = MarkingSpecification() marking.controlled_structure = '../../../../descendant-or-self::node()' tlp_marking = TLPMarkingStructure() tlp_marking.color = tlp_color marking.marking_structures.append(tlp_marking) stix_package.stix_header = stix_header stix_package.stix_header.handling = Marking() stix_package.stix_header.handling.add_marking(marking) # ...and stuff it full of random sample data :-) if datatype == 'ip': addr = Address(address_value=datagen.generate_random_ip_address(), category='ipv4-addr') addr.condition = 'Equals' stix_package.add_observable(Observable(addr)) elif datatype == 'domain': domain = DomainName() domain.type_ = 'FQDN' domain.value = datagen.generate_random_domain(config) domain.condition = 'Equals' stix_package.add_observable(Observable(domain)) elif datatype == 'filehash': file_object = File() file_object.file_name = str(uuid.uuid4()) + '.exe' hashes = datagen.generate_random_hashes() for hash in hashes.keys(): file_object.add_hash(Hash(hashes[hash], type_=hash.upper())) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" stix_package.add_observable(Observable(file_object)) elif datatype == 'email': try: msg = datagen.get_random_spam_msg(config) email = EmailMessage() email.header = EmailHeader() header_map = {'Subject': 'subject', 'To': 'to', 'Cc': 'cc', 'Bcc': 'bcc', 'From': 'from_', 'Sender': 'sender', 'Date': 'date', 'Message-ID': 'message_id', 'Reply-To': 'reply_to', 'In-Reply-To': 'in_reply_to', 'Content-Type': 'content_type', 'Errors-To': 'errors_to', 'Precedence': 'precedence', 'Boundary': 'boundary', 'MIME-Version': 'mime_version', 'X-Mailer': 'x_mailer', 'User-Agent': 'user_agent', 'X-Originating-IP': 'x_originating_ip', 'X-Priority': 'x_priority'} # TODO handle received_lines for key in header_map.keys(): val = msg.get(key, None) if val: email.header.__setattr__(header_map[key], val) email.header.__getattribute__(header_map[key]).condition = \ 'Equals' # TODO handle email bodies (it's mostly all there except for # handling weird text encoding problems that were making # libcybox stacktrace) # body = get_email_payload(random_spam_msg) # if body: # email.raw_body = body stix_package.add_observable(Observable(email)) except: return(None) observable_id = stix_package.observables.observables[0].id_ return(observable_id, stix_package)
def cybox_object_address(obj): a = Address() a.address_value =obj.address_value a.category = obj.category a.condition = obj.condition return a
def json2observable(config, src, dest, endpoint, json_, crits_id): # TODO split into smaller functions '''transform crits observables into cybox''' try: set_id_method(IDGenerator.METHOD_UUID) xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url'] xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name'] set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name)) if endpoint == 'ips': crits_types = {'Address - cidr': 'cidr', 'Address - ipv4-addr': 'ipv4-addr', 'Address - ipv4-net': 'ipv4-net', 'Address - ipv4-net-mask': 'ipv4-netmask', 'Address - ipv6-addr': 'ipv6-addr', 'Address - ipv6-net': 'ipv6-net', 'Address - ipv6-net-mask': 'ipv6-netmask'} addr = Address(address_value=json_['ip'], category=crits_types[json_['type']]) addr.condition = 'Equals' observable_ = Observable(addr) elif endpoint == 'domains': domain = DomainName() domain.type_ = 'FQDN' domain.value = json_['domain'] domain.condition = 'Equals' observable_ = Observable(domain) elif endpoint == 'samples': crits_types = {'md5': 'MD5', 'sha1': 'SHA1', 'sha224': 'SHA224', 'sha256': 'SHA256', 'sha384': 'SHA384', 'sha512': 'SHA512', 'ssdeep': 'SSDEEP'} file_object = File() file_object.file_name = json_['filename'] for hash in crits_types.keys(): if hash in json_: file_object.add_hash(Hash(json_[hash], type_=crits_types[hash])) for i in file_object.hashes: i.simple_hash_value.condition = "Equals" observable_ = Observable(file_object) elif endpoint == 'emails': crits_types = {'subject': 'subject', 'to': 'to', 'cc': 'cc', 'from_address': 'from_', 'sender': 'sender', 'date': 'date', 'message_id': 'message_id', 'reply_to': 'reply_to', 'boundary': 'boundary', 'x_mailer': 'x_mailer', 'x_originating_ip': 'x_originating_ip'} email = EmailMessage() email.header = EmailHeader() for k in crits_types.keys(): val = json_.get(k, None) if val: email.header.__setattr__(crits_types[k], val) email.header.__getattribute__(crits_types[k]).condition = \ 'Equals' observable_ = Observable(email) else: config['logger'].error( log.log_messages['unsupported_object_error'].format( type_='crits', obj_type=endpoint, id_=crits_id)) return(None) observable_.id = xmlns_name + ':observable-' + crits_id observable_.id_ = observable_.id return(observable_) except: e = sys.exc_info()[0] config['logger'].error( log.log_messages['obj_convert_error'].format( src_type='crits', src_obj='observable', id_=crits_id, dest_type='cybox', dest_obj='observable')) config['logger'].exception(e) return(None)
res = urllib2.urlopen(req) except urllib2.HTTPError, e: print "HTTPError: " + str(e.code) except urllib2.URLError, e: print "URLError: " + str(e.reason) doc = xmltodict.parse(res.read()) # Create the STIX Package package = STIXPackage() # Create the STIX Header and add a description. header = STIXHeader() #header.title = "SANS ISC Top-100 Malicious IP Addresses" #header.description = "Source: " + url package.stix_header = header for entry in doc['topips']['ipaddress']: bytes = entry['source'].split('.') indicator = Indicator() indicator.title = "SANS ISC Malicious IP" indicator.add_indicator_type("IP Watchlist") ip = Address() ip.address_value = "%d.%d.%d.%d" % (int(bytes[0]), int( bytes[1]), int(bytes[2]), int(bytes[3])) ip.category = 'ipv4-addr' ip.condition = 'Equals' indicator.add_observable(ip) package.add_indicator(indicator) print(package.to_xml()) if __name__ == '__main__': main()
def main(): # define constants TI_REQUEST_URL = "https://api.intelgraph.idefense.com/rest/threatindicator/v0" # iDefense API Key # To avoid hard-coding creds, I'm using environment variables if os.environ.get('IDEF_TOKEN') is None: print( "error: please store your iDefense IntelGraph API key in the IDEF_TOKEN environment" ) sys.exit(1) API_KEY = os.environ.get('IDEF_TOKEN') API_SECRET = '' # TODO: use command-line parameter timestr = datetime.datetime.utcnow() - datetime.timedelta(days=1) LAST_IMPORT = timestr.strftime("%Y-%m-%dT%H:%M:%S") + ".000Z" HEADERS = { "Content-Type": "application/json", "auth-token": API_KEY, "X-Api-Key-Proof": API_SECRET } print(HEADERS) page = 1 more_data = True count = 0 # Set namespace NAMESPACE = Namespace("https://intelgraph.idefense.com", "idefense") set_id_namespace(NAMESPACE) # Create STIX Package stix_package = STIXPackage() stix_header = STIXHeader() stix_header.description = "iDefense Threat Indicators Feed" stix_package.stix_header = stix_header ttps = {} malware = {} try: while more_data: request_payload = { "start_date": LAST_IMPORT, "page_size": 200, "page": page } r = requests.post(TI_REQUEST_URL, headers=HEADERS, data=json.dumps(request_payload)) print(r) response = [] if r.status_code == requests.codes.ok: try: # Read in response as json response = r.json() except (ValueError, KeyError): print("Response couldn't be decoded :(") more_data = False continue more_data = response.get('more', 'False') print("Page %d ==> %s (%s)" % (page, response['more'], response['total_size'])) page += 1 # Iterate the response for indicatorD in response['results']: count += 1 # Indicator value such as the value of the IP/Domain/URL indicator = indicatorD.get('key') print(indicator, indicatorD.get('type')) if indicatorD.get('last_seen_as') is None: last_seen_as = 'UNKNOWN' else: last_seen_as = ''.join(indicatorD.get('last_seen_as')) # Identify TTP if last_seen_as not in ttps: ttps[last_seen_as] = TTP(title=last_seen_as) stix_package.add_ttp(ttps[last_seen_as]) # Identify malware source if 'files' in indicatorD: for hashD in indicatorD['files']: md5 = hashD.get('key') # Malware Family classification of the hash if available if hashD.get('malware_family') is None: malware_family = "Unknown" else: malware_family = ''.join( hashD.get('malware_family')) if md5 not in malware: malware[md5] = add_malware( md5, malware_family, hashD.get('uuid')) if indicatorD.get('type') == "url": # Create indicator indicator = Indicator( id_="indicator-{0}".format(indicatorD.get('uuid')), title=''.join(indicatorD.get('malware_family')), timestamp=indicatorD.get('last_seen')) indicator.add_indicator_type("URL Watchlist") # Populate URL url = URI() url.value = indicatorD.get('key') url.type_ = URI.TYPE_URL url.value.condition = "Equals" indicator.add_observable(url) elif indicatorD.get('type') == "domain": # Populate domain name indicator = Indicator( id_="indicator-{0}".format(indicatorD.get('uuid')), title=''.join(indicatorD.get('malware_family')), timestamp=indicatorD.get('last_seen')) indicator.add_indicator_type("Domain Watchlist") domain = DomainName() domain.value = indicatorD.get('key') domain.value.condition = "Equals" indicator.add_observable(domain) elif indicatorD.get('type') == "ip": # Create indicator indicator = Indicator( id_="indicator-{0}".format(indicatorD.get('uuid')), title=indicatorD.get('malware_family'), timestamp=indicatorD.get('last_seen')) indicator.add_indicator_type("IP Watchlist") # Populate IP address addr = Address(address_value=indicatorD.get('key'), category=Address.CAT_IPV4) addr.condition = "Equals" indicator.add_observable(addr) # Link TTP indicator.add_indicated_ttp( TTP(idref=ttps[last_seen_as].id_)) # Indicate confidence score indicator.confidence = Confidence( value=VocabString(indicatorD.get('confidence'))) # Add related indicator to malware indicator.add_related_indicator(malware[md5]) # Add to package stix_package.add_indicator(indicator) else: print("API request couldn't be fulfilled due status code: %d" % r.status_code) more_data = False except requests.exceptions.ConnectionError as e: print("Check your network connection\n %s" % str(e)) except requests.exceptions.HTTPError as e: print("Bad HTTP response\n %s" % str(e)) except Exception as e: print("Uncaught exception\n %s" % str(e)) # Output to XML with open('stix-1.2.1.xml', 'wb') as f: f.write(stix_package.to_xml())
doc = xmltodict.parse(res.read()) # Create the STIX Package package = STIXPackage() # Create the STIX Header and add a description. header = STIXHeader() #header.title = "SANS ISC Top-100 Malicious IP Addresses" #header.description = "Source: " + url package.stix_header = header for entry in doc['topips']['ipaddress']: bytes = entry['source'].split('.') indicator = Indicator() indicator.title = "SANS ISC Malicious IP" indicator.add_indicator_type("IP Watchlist") ip = Address() ip.address_value = "%d.%d.%d.%d" % (int(bytes[0]), int(bytes[1]), int(bytes[2]) , int(bytes[3])) ip.category = 'ipv4-addr' ip.condition = 'Equals' indicator.add_observable(ip) package.add_indicator(indicator) print(package.to_xml()) if __name__ == '__main__': main()
def cybox_object_address(obj): a = Address() a.address_value =obj.address_value a.category = obj.category a.condition = obj.condition return a