def create_observable_domain_name(properties: ObservableProperties) -> DomainName: """Create an observable representing a domain name.""" return DomainName( value=properties.value, object_marking_refs=properties.object_markings, custom_properties=_get_custom_properties(properties), )
def normalize(self): value = refang(self.value.lower()) if value.endswith('.'): value = value[:-1] value = idna.decode(value) serialized = json.loads(self._stix_object.serialize()) serialized['value'] = value self._stix_object = DomainName(**serialized)
def test_update_observed_data(): """Tests that a ObservedData object is succesfully updated.""" observed_data = ObservedData( labels=['cyber'], number_observed=1, first_observed='2015-12-21T19:00:00Z', last_observed='2015-12-21T19:00:00Z', objects={'0': DomainName(value='yeti.org')} ) observed_data.save() stix_id = observed_data.id updated = observed_data.update({'number_observed': 2}) assert updated.number_observed == 2 assert updated.id == stix_id assert updated.labels == ['cyber'] assert str(updated.first_observed) == '2015-12-21 19:00:00+00:00' assert str(updated.last_observed) == '2015-12-21 19:00:00+00:00' assert updated.objects == {'0': DomainName(value='yeti.org')}
def test_observed_data_creation(): """Tests the creation of a single ObservedData object.""" observed_data = ObservedData( labels=['cyber'], number_observed=1, first_observed='2015-12-21T19:00:00Z', last_observed='2015-12-21T19:00:00Z', objects={'0': DomainName(value='yeti.org')} ) # pylint: disable=protected-access assert observed_data._stix_object is not None assert isinstance(observed_data._stix_object, StixObservedData) assert isinstance(observed_data.objects['0'], DomainName)
def produce(self, tc_data: Union[list, dict], **kwargs) -> Iterable[DomainName]: """Produce STIX 2.0 JSON object from TC API response.""" if isinstance(tc_data, list) and len(tc_data) > 0 and 'summary' in tc_data[0]: indicator_field = 'summary' else: indicator_field = 'hostName' parse_map = { 'type': 'domain-name', 'spec_version': '2.1', 'id': '@.id', 'value': f'@."{indicator_field}"', } yield from (DomainName(**stix_data) for stix_data in self._map(tc_data, parse_map))
def parse_line_to_stix_object(self, classifier, line, regex): if self.is_on_whitelist(classifier["prepare"](re.search( regex, line).group(1))): return "" if classifier["name"] == "processes_created": process = Process( type="process", id="process--" + str(uuid1()), command_line=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, "executable_path": Stix2.get_executable_path(line), }, allow_custom=True, ) self.processes.append(process) self.all_stix_objects.append(process) if classifier["name"].startswith("files_"): name = classifier["prepare"](re.search( regex, line).group(1)).split("/")[-1] dir_str = "/".join(classifier["prepare"](re.search( regex, line).group(1)).split("/")[:-1]) or "/" if not name: name = classifier["prepare"](re.search( regex, line).group(1)).split("/")[-2] dir_str = "/".join(classifier["prepare"](re.search( regex, line).group(1)).split("/")[:-2]) or "/" file = File( type="file", id="file--" + str(uuid1()), name=name, custom_properties={ "parent_directory_str": dir_str, "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.all_stix_objects.append(file) if classifier["name"] == "files_removed": self.files_removed.append(file) if classifier["name"] == "files_written": self.files_written.append(file) if classifier["name"] == "files_read": self.files_read.append(file) if classifier["name"] == "hosts_connected": ipv4_regex = r"([0-9]{1,3}\.){3}[0-9]{1,3}" if re.search(ipv4_regex, line): ipv4 = IPv4Address( type="ipv4-addr", id="ipv4-addr--" + str(uuid1()), value=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.ipv4.append(ipv4) self.all_stix_objects.append(ipv4) else: ipv6 = IPv6Address( type="ipv6-addr", id="ipv6-addr--" + str(uuid1()), value=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.ipv6.append(ipv6) self.all_stix_objects.append(ipv6) if classifier["name"] == "domains": ip = re.search(regex, line).group(1) domain_name = classifier["prepare"](ip) if domain_name != ip: domain = DomainName( type="domain-name", id="domain-name--" + str(uuid1()), value=domain_name, resolves_to_refs=[ self.get_ip_stix_object_for_domain(line, ip) ], custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, "resolves_to_str": ip, }, allow_custom=True, ) self.domains.append(domain) self.all_stix_objects.append(domain) else: # reverse dns failed, only save ipv4 / ipv6 object self.get_ip_stix_object_for_domain(line, ip)
def _process_indicator(self, indicator: Indicator) -> list[_Observable]: """ Process the indicator depending on its type. Parameters ---------- indicator : Indicator One indicator from an article. Returns ------- List of Observable A list of Observable depending on the indicator type. """ indicator_type = indicator["type"] values = indicator["values"] tlp_marking = TLP_WHITE if indicator[ "source"] == "public" else TLP_AMBER if indicator_type == "hash_md5": return [ File( type="file", hashes={"MD5": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in ["hash_sha1", "sha1"]: return [ File( type="file", hashes={"SHA-1": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in ["sha256", "hash_sha256"]: return [ File( type="file", hashes={"SHA-256": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type == "domain": return [ DomainName(type="domain-name", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["email", "emails"]: return [ EmailAddress(type="email-addr", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["filename", "filepath"]: return [ File(type="file", name=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type == "ip": return [ IPv4Address(type="ipv4-addr", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["proces_mutex", "process_mutex", "mutex"]: return [ Mutex(type="mutex", name=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type == "url": return [ URL(type="url", value=v, object_marking_refs=tlp_marking, defanged=False) for v in values ] if indicator_type == "certificate_sha1": return [ X509Certificate( type="x509-certificate", hashes={"SHA-1": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in [ "certificate_issuerorganizationname", "certificate_issuercommonname", ]: return [ X509Certificate(type="x509-certificate", issuer=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in [ "certificate_subjectorganizationname", "certificate_subjectcountry", "certificate_subjectcommonname", ]: return [ X509Certificate(type="x509-certificate", subject=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in [ "certificate_serialnumber", "code_certificate_serial" ]: return [ X509Certificate( type="x509-certificate", serial_number=v, object_marking_refs=tlp_marking, ) for v in values ] self.helper.log_warning( f"[RiskIQ] indicator with key {indicator_type} not supported. (Values: {values})" ) return []