def test_observable_iterable(self): a = Address("*****@*****.**", Address.CAT_EMAIL) a2 = Address("*****@*****.**", Address.CAT_EMAIL) o = Observables([a, a2]) for obs in o: self.assertTrue(obs.object_.properties in [a, a2])
def test_sender_TypedField(self): h = EmailHeader() a = "*****@*****.**" # Set using actual object h.sender = Address(a, Address.CAT_EMAIL) # In this case, the type is Address, not EmailAddress, but we don't # care since EmailAddress.istypeof(h.sender) is True self.assertNotEqual(EmailAddress, type(h.sender)) self.assertEqual(Address, type(h.sender)) self.assertTrue(EmailAddress.istypeof(h.sender)) # Set using "aliased" object h.sender = EmailAddress(a) # In this case it is actually an EmailAddress, not just an Address # (but isinstance returns True) self.assertEqual(EmailAddress, type(h.sender)) self.assertNotEqual(Address, type(h.sender)) self.assertTrue(isinstance(h.sender, Address)) self.assertTrue(EmailAddress.istypeof(h.sender)) h.sender = a self.assertTrue(EmailAddress.istypeof(h.sender)) bad_object = 42 self.assertRaises(ValueError, setattr, h, 'sender', bad_object) # Just because it's an Address isn't good enough. It needs to have # the right category. ipv4_object = Address(a, Address.CAT_IPV4) self.assertRaises(ValueError, setattr, h, 'sender', ipv4_object)
def _address(keypair): address = keypair.get('indicator') 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')
def _address(self, 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')
def to_cybox(self, exclude=None): """ Convert an email to a CybOX Observables. Pass parameter exclude to specify fields that should not be included in the returned object. Returns a tuple of (CybOX object, releasability list). To get the cybox object as xml or json, call to_xml() or to_json(), respectively, on the resulting CybOX object. """ if exclude == None: exclude = [] observables = [] obj = EmailMessage() # Assume there is going to be at least one header obj.header = EmailHeader() if 'message_id' not in exclude: obj.header.message_id = String(self.message_id) if 'subject' not in exclude: obj.header.subject = String(self.subject) if 'sender' not in exclude: obj.header.sender = Address(self.reply_to, Address.CAT_EMAIL) if 'reply_to' not in exclude: obj.header.reply_to = Address(self.reply_to, Address.CAT_EMAIL) if 'x_originating_ip' not in exclude: obj.header.x_originating_ip = Address(self.x_originating_ip, Address.CAT_IPV4) if 'raw_body' not in exclude: obj.raw_body = self.raw_body if 'raw_header' not in exclude: obj.raw_header = self.raw_header #copy fields where the names differ between objects if 'helo' not in exclude and 'email_server' not in exclude: obj.email_server = String(self.helo) if ('from_' not in exclude and 'from' not in exclude and 'from_address' not in exclude): obj.header.from_ = EmailAddress(self.from_address) if 'date' not in exclude and 'isodate' not in exclude: obj.header.date = DateTime(self.isodate) observables.append(Observable(obj)) return (observables, self.releasability)
def test_round_trip(self): a = Address("*****@*****.**", Address.CAT_EMAIL) a2 = Address("*****@*****.**", Address.CAT_EMAIL) ms = MeasureSource() ms.class_ = "System" ms.source_type = "Analysis" ms.description = StructuredText("A Description") o = Observables([a, a2]) o.observable_package_source = ms o2 = round_trip(o, output=True) self.assertEqual(o.to_dict(), o2.to_dict())
def url(ip, provider, reporttime): vuln = Vulnerability() vuln.cve_id = "IPV4-" + str(ip) vuln.description = "maliciousURL" et = ExploitTarget(title=provider + " observable") et.add_vulnerability(vuln) addr = Address(address_value=str(ip), category=Address.CAT_IPV4) addr.condition = "Equals" # Create an Indicator with the File Hash Object created above. indicator = Indicator() indicator.title = "URL-" + str(ip) indicator.description = ("Malicious URL " + str(ip) + " reported from " + provider) indicator.set_producer_identity(provider) indicator.set_produced_time(reporttime) indicator.add_observable(addr) # Create a STIX Package stix_package = STIXPackage() stix_package.add(et) stix_package.add(indicator) # Print the XML! #print(stix_package.to_xml()) f = open('/opt/TARDIS/Observables/URL/' + str(ip) + '.xml', 'w') f.write(stix_package.to_xml()) f.close()
def test_observble_init(self): obj = Object() dobj = ObjectProperties() a = Address() oc = ObservableComposition() e = Event() obs1 = Observable(obj) self.assertTrue(obs1.object_ is obj) self.assertFalse(obs1.observable_composition) self.assertFalse(obs1.event) obs2 = Observable(dobj) self.assertTrue(obs2.object_) self.assertTrue(obs2.object_.properties is dobj) self.assertFalse(obs2.observable_composition) self.assertFalse(obs2.event) obs3 = Observable(a) self.assertTrue(obs3.object_) self.assertTrue(obs3.object_.properties is a) self.assertFalse(obs3.event) self.assertFalse(obs3.observable_composition) obs4 = Observable(oc) self.assertFalse(obs4.object_) self.assertFalse(obs4.event) self.assertTrue(obs4.observable_composition is oc) obs5 = Observable(e) self.assertFalse(obs5.object_) self.assertTrue(obs5.event is e) self.assertFalse(obs5.observable_composition)
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 main(): from stix.coa import CourseOfAction, Objective from stix.common import Confidence from stix.core import STIXPackage from cybox.core import Observables from cybox.objects.address_object import Address pkg = STIXPackage() coa = CourseOfAction() coa.title = "Block traffic to PIVY C2 Server (10.10.10.10)" coa.stage = "Response" coa.type_ = "Perimeter Blocking" obj = Objective() obj.description = "Block communication between the PIVY agents and the C2 Server" obj.applicability_confidence = Confidence("High") coa.objective = obj coa.impact = "Low" coa.impact.description = "This IP address is not used for legitimate hosting so there should be no operational impact." coa.cost = "Low" coa.efficacy = "High" addr = Address(address_value="10.10.10.10", category=Address.CAT_IPV4) coa.parameter_observables = Observables(addr) pkg.add_course_of_action(coa) print pkg.to_xml()
def generateIPObservable(attribute): address_object = Address() cidr = False 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" elif (ipv4 == True): address_object.category = "ipv4-addr" else: address_object.category = "ipv6-addr" if (attribute["type"] == "ip-src"): address_object.is_source = True else: address_object.is_source = False address_object.address_value = attribute["value"] return address_object
def resolveIPType(attribute_value, attribute_type): address_object = Address() cidr = False 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" elif (ipv4 == True): address_object.category = "ipv4-addr" else: address_object.category = "ipv6-addr" if (attribute_type == "ip-src") or (attribute_type == "domain|ip"): address_object.is_source = True else: address_object.is_source = False address_object.address_value = attribute_value return address_object
def to_cybox_observable(self): """ Convert an IP to a CybOX Observables. Returns a tuple of (CybOX object, releasability list). To get the cybox object as xml or json, call to_xml() or to_json(), respectively, on the resulting CybOX object. """ obj = Address() obj.address_value = self.ip temp_type = self.ip_type.replace("-", "") if temp_type.find(Address.CAT_ASN.replace("-", "")) >= 0: obj.category = Address.CAT_ASN elif temp_type.find(Address.CAT_ATM.replace("-", "")) >= 0: obj.category = Address.CAT_ATM elif temp_type.find(Address.CAT_CIDR.replace("-", "")) >= 0: obj.category = Address.CAT_CIDR elif temp_type.find(Address.CAT_MAC.replace("-", "")) >= 0: obj.category = Address.CAT_MAC elif temp_type.find(Address.CAT_IPV4_NETMASK.replace("-", "")) >= 0: obj.category = Address.CAT_IPV4_NETMASK elif temp_type.find(Address.CAT_IPV4_NET.replace("-", "")) >= 0: obj.category = Address.CAT_IPV4_NET elif temp_type.find(Address.CAT_IPV4.replace("-", "")) >= 0: obj.category = Address.CAT_IPV4 elif temp_type.find(Address.CAT_IPV6_NETMASK.replace("-", "")) >= 0: obj.category = Address.CAT_IPV6_NETMASK elif temp_type.find(Address.CAT_IPV6_NET.replace("-", "")) >= 0: obj.category = Address.CAT_IPV6_NET elif temp_type.find(Address.CAT_IPV6.replace("-", "")) >= 0: obj.category = Address.CAT_IPV6 return ([Observable(obj)], self.releasability)
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']: if info['bot'] not in ttps: ttps[info['bot']] = TTP(title=info['bot']) stix_package.add_ttp(ttps[info['bot']]) 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) stix_package.add_incident(incident) print(stix_package.to_xml(encoding=None))
def main(): NAMESPACE = {"https://www.ncsc.gov.uk/": "ncscuk"} idgen.set_id_namespace(NAMESPACE) pkg = STIXPackage() coa = CourseOfAction() obj = file_to_obj('out.json') if obj.type == 'bundle': for _dict in obj.objects: object = dict_to_obj(_dict) if object.type == 'indicator': ind = Indicator() id_str = object.id.replace('--', '-') print id_str #ind.id_ = object.id pattern_type = object.pattern.split(':')[0] _value = re.sub("'", '', object.pattern.split(' = ')[1]) if pattern_type == 'ipv4-addr': obs = Observable( Address(address_value=_value, category=Address.CAT_IPV4)) elif pattern_type == 'url': obs = Observable(URI(value=_value, type_=URI.TYPE_URL)) pkg.add_observable(obs) obs_ref = Observable() obs_ref.id_ = None obs_ref.idref = obs.id_ ind.add_observable(obs_ref) pkg.add_indicator(ind) print pkg.to_xml()
def test_round_trip(self): o = Object() o.idref = "example:a1" o.properties = Address("1.2.3.4", Address.CAT_IPV4) o2 = round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
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 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 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 main(): m = EmailMessage() m.to = ["*****@*****.**", "*****@*****.**"] m.from_ = "*****@*****.**" m.subject = "New modifications to the specification" a = Address("192.168.1.1", Address.CAT_IPV4) m.add_related(a, "Received_From", inline=False) print(Observables([m, a]).to_xml(encoding=None))
def main(): stix_package = STIXPackage() addr1 = Observable( Address(address_value="198.51.100.2", category=Address.CAT_IPV4)) addr2 = Observable( Address(address_value="198.51.100.17", category=Address.CAT_IPV4)) addr3 = Observable( Address(address_value="203.0.113.19", category=Address.CAT_IPV4)) stix_package.add_observable(addr1) stix_package.add_observable(addr2) stix_package.add_observable(addr3) obs_addr1 = Observable() obs_addr2 = Observable() obs_addr3 = Observable() obs_addr1.id_ = None obs_addr2.id_ = None obs_addr3.id_ = None obs_addr1.idref = addr1.id_ obs_addr2.idref = addr2.id_ obs_addr3.idref = addr3.id_ vocab_string = VocabString(value='Malware C2') infrastructure = Infrastructure() infrastructure.observable_characterization = Observables( [obs_addr1, obs_addr2, obs_addr3]) infrastructure.add_type(vocab_string) resource = Resource() resource.infrastructure = infrastructure ttp = TTP(title="Malware C2 Channel") ttp.resources = resource stix_package.add_ttp(ttp) print(stix_package.to_xml())
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 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 __create_cybox_headers(self, msg): """ Returns a CybOX EmailHeaderType object """ if self.__verbose_output: sys.stderr.write("** parsing headers\n") headers = EmailHeader() if 'received' in self.headers: headers.received_lines = self._parse_received_headers(msg) if 'to' in self.headers: headers.to = _get_email_recipients(msg['to']) if 'cc' in self.headers: headers.cc = _get_email_recipients(msg['cc']) if 'bcc' in self.headers: headers.bcc = _get_email_recipients(msg['bcc']) if 'from' in self.headers: headers.from_ = _get_single_email_address(msg['from']) if 'sender' in self.headers: headers.sender = _get_single_email_address(msg['sender']) if 'reply-to' in self.headers: headers.reply_to = _get_single_email_address(msg['reply-to']) if 'subject' in self.headers: headers.subject = String(msg['subject']) if 'in-reply-to' in self.headers: headers.in_reply_to = String(msg['in-reply-to']) if 'errors-to' in self.headers: headers.errors_to = String(msg['errors-to']) if 'date' in self.headers: headers.date = DateTime(msg['date']) if 'message-id' in self.headers: headers.message_id = String(msg['message-id']) if 'boundary' in self.headers: headers.boundary = String(msg['boundary']) if 'content-type' in self.headers: headers.content_type = String(msg['content-type']) if 'mime-version' in self.headers: headers.mime_version = String(msg['mime-version']) if 'precedence' in self.headers: headers.precedence = String(msg['precedence']) if 'user-agent' in self.headers: headers.user_agent = String(msg['user-agent']) if 'x-mailer' in self.headers: headers.x_mailer = String(msg['x-mailer']) if 'x-originating-ip' in self.headers: headers.x_originating_ip = Address(msg['x-originating-ip'], Address.CAT_IPV4) if 'x-priority' in self.headers: headers.x_priority = String(msg['x-priority']) return headers
def main(): NS = cybox.utils.Namespace("http://example.com/", "example") cybox.utils.set_id_namespace(NS) m = EmailMessage() m.to = ["*****@*****.**", "*****@*****.**"] m.from_ = "*****@*****.**" m.subject = "New modifications to the specification" a = Address("192.168.1.1", Address.CAT_IPV4) m.add_related(a, "Received_From", inline=False) print Observables([m, a]).to_xml()
def __create_ip_address_object(self, ip_addr): """ Returns a CybOX AddressType Object for use with IPv4 or IPv6 addresses """ if not ip_addr: return None if self.__verbose_output: sys.stderr.write("** creating ip address object for: %s\n" % ip_addr) if ':' in str(ip_addr): category = Address.CAT_IPV6 else: category = Address.CAT_IPV4 return Address(ip_addr, category)
def print_match(self, fpath, page, name, match): # Resolve all hashes to single HASH reference to avoid repetition if name == 'MD5' or name == 'SHA1' or name == 'SHA256': name = 'HASH' if name in ind_dict: indicator = ind_dict[name] add_ind_list.append(name) indicator.title = fpath #=========== # Add new object handlers here: if name == 'IP': new_obj = Address(address_value=match, category=Address.CAT_IPV4) elif name == 'HASH': new_obj = File() new_obj.add_hash(Hash(match)) elif name == 'URL': new_obj = URI(type_=URI.TYPE_URL, value=match) elif name == 'Host': new_obj = URI(type_=URI.TYPE_DOMAIN, value=match) elif name == 'Email': new_obj = Address( address_value=match, category=Address.CAT_EMAIL ) ## Not sure if this is right - should this be using the email_message_object? elif name == 'Registry': new_obj = WinRegistryKey(values=match) #=========== new_obs = Observable(new_obj) new_obs.title = "Page Ref: " + str(page) indicator.add_observable(new_obs)
def get_observable(self): if self.type_ == 'md5': o_ = File() o_.md5 = self.value elif self.type_ == 'sha1': o_ = File() o_.sha1 = self.value elif self.type_ == 'sha256': o_ = File() o_.sha256 = self.value elif self.type_ == 'sha512': o_ = File() o_.sha256 = self.value elif self.type_ == 'url': o_ = URI(value=self.value, type_=URI.TYPE_URL) elif self.type_ == 'hostname': o_ = DomainName() o_.value = self.value o_.type_ = 'FQDN' elif self.type_ == 'domain': o_ = DomainName() o_.value = self.value o_.type_ = 'domain' elif self.type_ == 'ip-dst': o_ = Address(address_value=self.value, category=Address.CAT_IPV4) o_.is_destination = True o_.is_Source = False elif self.type_ == 'email-src': o_ = Address(address_value=self.value, category=Address.CAT_EMAIL) elif self.type_ == 'email-subject': o_ = EmailMessage() o_.subject = self.value else: # print 'skip>>>>: type_: ' + str(self.type_) o_ = None return o_
def test_round_trip(self): email = "*****@*****.**" category = Address.CAT_EMAIL addr = Address() addr.address_value = email addr.category = category addr2 = cybox.test.round_trip(addr) self.assertEqual(addr.to_dict(), addr2.to_dict()) # Explicitly check these fields self.assertEqual(category, addr2.category) self.assertEqual(email, str(addr2))