diff --git a/stix_shifter_modules/tanium/stix_translation/json/to_stix_map.json b/stix_shifter_modules/tanium/stix_translation/json/to_stix_map.json index ed8a4805b..a4c84c559 100644 --- a/stix_shifter_modules/tanium/stix_translation/json/to_stix_map.json +++ b/stix_shifter_modules/tanium/stix_translation/json/to_stix_map.json @@ -34,108 +34,238 @@ "key": "x-oca-event.severity", "object": "x-oca-event" }, - "details": [ + "details": { - "key": "process", - "object": "process_all", - "transformer":"ProcessTransformer" - }, - { - "key": "process.pid", - "object": "process_some", - "transformer":"ProcessPidTransformer" - }, - { - "key": "process.created", - "object": "process_some", - "transformer":"ProcessCreatedTransformer" - }, - { - "key": "process.args", - "object": "process_some", - "transformer":"ProcessArgsTransformer" - }, - { - "key": "process.name", - "object": "process_some", - "transformer":"ProcessNameTransformer" - }, - { - "key": "process.cwd", - "object": "process_some", - "transformer":"ProcessCWDPathTransformer" - }, - { - "key": "user-account.user_id", - "object": "user", - "transformer":"ProcessUserIdTransformer" - }, - { - "key": "user-account.display_name", - "object": "user", - "transformer":"ProcessUserDisplayNameTransformer" - }, - { - "key": "user-account.is_service_account", - "object": "user", - "transformer":"ProcessUserDaemonTransformer" - }, - { - "key": "process.creator_user_ref", - "object": "process_some", - "references":"user" - }, - { - "key": "binary_ref.hashes", - "object": "processFile", - "transformer":"ProcessFileHashesTransformer" - }, - { - "key": "binary_ref.name", - "object": "processFile", - "transformer": "ProcessNameTransformer" - }, - { - "key": "parent_directory_ref.path", - "object": "processFileDirectory", - "transformer": "ProcessCWDPathTransformer" - }, - { - "key": "content_refs.issuer", - "object": "certificate", - "transformer": "ProcessFileCertificateIssuerTransformer" - }, - { - "key": "content_refs.subject", - "object": "certificate", - "transformer": "ProcessFileCertificateSubjectTransformer" - }, - { - "key": "binary_ref.parent_directory_ref", - "object": "processFile", - "references": "processFileDirectory" - }, - { - "key": "binary_ref.content_refs", - "object": "processFile", - "references": "certificate" - }, - { - "key": "process.binary_ref", - "object": "process_some", - "references": "processFile" - }, - { - "key": "x-oca-asset.process_ref", - "object": "x-oca-event", - "references": "process_some" + "match": + { + "properties": + { + "pid": + { + "key": "process.pid", + "object": "process" + }, + "start_time": + { + "key": "process.created", + "object": "process" + }, + "args": + { + "key": "process.args", + "object": "process", + "transformer":"ProcessArgsTransformer" + }, + "name": + [{ + "key": "process.name", + "object": "process", + "transformer":"ProcessNameTransformer" + }, + { + "key": "process.cwd", + "object": "process", + "transformer":"ProcessCWDPathTransformer" + }] + } + }, + "finding": + { + "whats": + { + "artifact_activity": + { + "acting_artifact": + { + "process": + { + "user": + { + "user": + { + "user_id": + { + "key": "user-account.user_id", + "object": "user" + }, + "name": + { + "key": "user-account.display_name", + "object": "user" + }, + "domain": + [{ + "key": "user-account.is_service_account", + "object": "user", + "transformer":"ProcessUserDaemonTransformer" + }, + { + "key": "process.creator_user_ref", + "object": "process", + "references":"user" + }] + } + }, + "file": + { + "file": + { + "hash": + { + "key": "binary_ref.hashes", + "object": "processFile" + }, + "path": + [{ + "key": "binary_ref.name", + "object": "processFile", + "transformer": "ProcessNameTransformer" + }, + { + "key": "parent_directory_ref.path", + "object": "processFileDirectory", + "transformer": "ProcessCWDPathTransformer" + }, + { + "key": "binary_ref.parent_directory_ref", + "object": "processFile", + "references": "processFileDirectory" + }, + { + "key": "process.binary_ref", + "object": "process", + "references": "processFile" + }], + "signature_data": + { + "issuer": + { + "key": "content_refs.issuer", + "object": "certificate" + }, + "subject": + [{ + "key": "content_refs.subject", + "object": "certificate" + }, + { + "key": "binary_ref.content_refs", + "object": "processFile", + "references": "certificate" + }] + } + } + }, + "parent": + { + "process": + { + "pid": + [{ + "key": "process.pid", + "object": "parent-process" + }, + { + "key": "process.parent_ref" , + "object": "process", + "references": "parent-process" + }], + "arguments": + { + "key": "process.args", + "object": "parent-process", + "transformer":"ProcessArgsTransformer" + }, + "start_time": + { + "key": "process.created", + "object": "parent-process" + }, + "user": + { + "user": + { + "user_id": + { + "key": "user-account.user_id", + "object": "parent-user" + }, + "name": + { + "key": "user-account.display_name", + "object": "parent-user" + }, + "domain": + [{ + "key": "user-account.is_service_account", + "object": "parent-user", + "transformer":"ProcessUserDaemonTransformer" + }, + { + "key": "process.creator_user_ref", + "object": "parent-process", + "references":"parent-user" + }] + } + }, + "file": + { + "file": + { + "hash": + { + "key": "binary_ref.hashes", + "object": "parent-processFile" + }, + "path": + [{ + "key": "binary_ref.name", + "object": "parent-processFile", + "transformer": "ProcessNameTransformer" + }, + { + "key": "parent_directory_ref.path", + "object": "parent-processFile", + "transformer": "ProcessCWDPathTransformer" + }, + { + "key": "binary_ref.parent_directory_ref", + "object": "parent-processFile", + "references": "processFileDirectory" + }, + { + "key": "process.binary_ref", + "object": "parent-process", + "references": "parent-processFile" + }], + "signature_data": + { + "issuer": + { + "key": "content_refs.issuer", + "object": "parent-processFile-certificate" + }, + "subject": + [{ + "key": "content_refs.subject", + "object": "parent-processFile-certificate" + }, + { + "key": "binary_ref.content_refs", + "object": "parent-processFile", + "references": "parent-processFile-certificate" + }] + } + } + } + } + } + } + } + } + } + } }, - { - "key": "x-oca-asset.file_ref", - "object": "x-oca-event", - "references": "processFile" - } -], "matchType": { "key": "x-oca-event.category", @@ -156,7 +286,7 @@ "key":"x-oca-event.start", "object":"x-oca-event" }, - "intelDocs": + "intelDoc": { "id": { @@ -198,7 +328,25 @@ { "techniques": { - + "name": + [{ + "key": "x-ibm-ttp-tagging.name", + "object": "mitre-tag" + }, + { + "key": "x-ibm-ttp-tagging.extensions.technique_name", + "object": "mitre-tag" + }, + { + "key": "x-oca-event.ttp_tagging_refs", + "object": "x-oca-event", + "references": "mitre-tag" + }], + "id": + { + "key": "x-ibm-ttp-tagging.extensions.technique_id", + "object": "mitre-tag" + } } }, "status": diff --git a/stix_shifter_modules/tanium/stix_translation/transformers.py b/stix_shifter_modules/tanium/stix_translation/transformers.py index 103e2b93c..a7f19d093 100644 --- a/stix_shifter_modules/tanium/stix_translation/transformers.py +++ b/stix_shifter_modules/tanium/stix_translation/transformers.py @@ -68,44 +68,13 @@ def transform(data): # Leave method name as is. LOGGER.error("Cannot convert data value {} to ".format(data)) except Exception as err: LOGGER.error(err) - - -class ProcessPidTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - - if(dataAsAJson["match"]['type'] == "process"): - return dataAsAJson["match"]["properties"]["pid"] - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - -class ProcessCreatedTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - - if(dataAsAJson["match"]['type'] == "process"): - return dataAsAJson["match"]["properties"]["start_time"] - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) class ProcessArgsTransformer(ValueTransformer): @staticmethod def transform(data): # Leave method name as is. try: - dataAsAJson = json.loads(data) - - arguments_list = shlex.split(dataAsAJson["match"]["properties"]["args"]) + arguments_list = shlex.split(data) return arguments_list except ValueError: LOGGER.error("Cannot convert data value {} to ".format(data)) @@ -117,10 +86,9 @@ class ProcessNameTransformer(ValueTransformer): @staticmethod def transform(data): # Leave method name as is. try: - dataAsAJson = json.loads(data) - converted_file = dataAsAJson["match"]["properties"]["name"].replace('\\', '/') + converted_file = data.replace('\\', '/') pathObject = pathlib.Path(converted_file) - return pathObject.name + pathObject.suffix + return pathObject.name except ValueError: LOGGER.error("Cannot convert data value {} to ".format(data)) @@ -131,10 +99,8 @@ class ProcessCWDPathTransformer(ValueTransformer): @staticmethod def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - - converted_file = dataAsAJson["match"]["properties"]["name"].replace('\\', '/') + try: + converted_file = data.replace('\\', '/') pathObject = pathlib.Path(converted_file) return pathObject.parent.as_posix() except ValueError: @@ -142,81 +108,11 @@ def transform(data): # Leave method name as is. except Exception as err: LOGGER.error(err) -class ProcessUserIdTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - return dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["user"]["user"]["user_id"] - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - -class ProcessUserDisplayNameTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - - return dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["user"]["user"]["name"] - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - class ProcessUserDaemonTransformer(ValueTransformer): @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - - if (dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["user"]["user"]["domain"] is not None): - return True - else: - return False - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - -class ProcessFileCertificateIssuerTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - return dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["file"]["file"]["signature_data"]["issuer"] - - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - -class ProcessFileCertificateSubjectTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - return dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["file"]["file"]["signature_data"]["subject"] - - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) - -class ProcessFileHashesTransformer(ValueTransformer): - - @staticmethod - def transform(data): # Leave method name as is. - try: - dataAsAJson = json.loads(data) - return dataAsAJson["finding"]["whats"][0]["artifact_activity"]["acting_artifact"]["process"]["file"]["file"]["hash"] - except ValueError: - LOGGER.error("Cannot convert data value {} to ".format(data)) - except Exception as err: - LOGGER.error(err) \ No newline at end of file + def transform(data): # Leave method name as is. + if (data is not None and data is not ""): + return True + else: + return False \ No newline at end of file diff --git a/stix_shifter_modules/tanium/stix_transmission/connector.py b/stix_shifter_modules/tanium/stix_transmission/connector.py index 1a8825d25..1e4e03e51 100644 --- a/stix_shifter_modules/tanium/stix_transmission/connector.py +++ b/stix_shifter_modules/tanium/stix_transmission/connector.py @@ -77,6 +77,7 @@ async def get_results(self, per_query_limit, query, current_offset): def _add_results_to_final_dataset(self, current_query_results): for batch_of_results in current_query_results: + batch_of_results["details"] = json.loads(batch_of_results["details"]) self.final_results.append(batch_of_results) self.current_offset = self.current_offset + len(current_query_results) diff --git a/stix_shifter_modules/tanium/tests/stix_translation/test_from_json_to_stix.py b/stix_shifter_modules/tanium/tests/stix_translation/test_from_json_to_stix.py new file mode 100644 index 000000000..e8c986825 --- /dev/null +++ b/stix_shifter_modules/tanium/tests/stix_translation/test_from_json_to_stix.py @@ -0,0 +1,236 @@ +from stix_shifter_modules.tanium.entry_point import EntryPoint +from stix_shifter_utils.stix_translation.src.utils.transformer_utils import get_module_transformers +from stix_shifter_utils.stix_translation.src.json_to_stix import json_to_stix_translator +import unittest + +MODULE = "tanium" +entry_point = EntryPoint() +map_data = entry_point.get_results_translator().map_data +data_source = { + "type": "identity", + "id": "identity--3532c56d-ea72-48be-a2ad-1a53f4c9c6d3", + "name": "Tanium", + "identity_class": "events" +} +options = {} + +SAMPLE_DATA_DICT = { + "details": + { + "finding": + { + "whats": + [{ + "intel_intra_ids": + [{ + "id": 1204114022 + }, + { + "id": 1670888670 + }, + { + "id": 2753281896 + }, + { + "id": 3854795733 + }], + "source_name": "recorder", + "artifact_activity": + { + "relevant_actions": [{ + }, + { + "verb": 6, + "target": + { + "file": + { + "path": "C:\\Users\\Bob\\AppData\\Local\\Temp\\gfw-install-CZejgRlL.exe", + "hash": + { + "md5": "d41d8cd98f00b204e9800998ecf8427e", + "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "size_bytes": + { + }, + "modification_time": "2022-06-10T23:19:37.000Z", + "instance_hash_salt": "132993767777627641" + }, + "instance_hash": "8639093369865776459", + "artifact_hash": "15425104092171844481" + }, + "timestamp": "2022-06-10T23:19:37.000Z", + "tanium_recorder_event_table_id": "4611686018468280136" + }, + { + "verb": 6, + "target": + { + "file": + { + "path": "C:\\Users\\Bob\\AppData\\Local\\Temp\\gfw-install-CZejgRlL.exe", + "hash": + { + "md5": "d41d8cd98f00b204e9800998ecf8427e", + "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "size_bytes": + { + }, + "modification_time": "2022-06-10T23:19:37.000Z", + "instance_hash_salt": "132993767777627641" + }, + "instance_hash": "8639093369865776459", + "artifact_hash": "15425104092171844481" + }, + "timestamp": "2022-06-10T23:19:37.000Z", + "tanium_recorder_event_table_id": "4611686018468280136" + }], + "acting_artifact": + { + "process": + { + "handles": + [ + ], + "pid": 8372, + "arguments": "\"C:\\Program Files\\Git\\usr\\bin\\mktemp.exe\" -t gfw-install-XXXXXXXX.exe", + "file": + { + "file": + { + "path": "C:\\Program Files\\Git\\usr\\bin\\mktemp.exe", + "hash": + { + "md5": "2204459dcbf34aed8906daac26db6f56" + } + }, + "instance_hash": "7306911300040087486", + "artifact_hash": "7306911300040087486" + }, + "user": + { + "user": + { + "name": "Bob", + "domain": "MEDIATOO" + } + }, + "parent": + { + "process": + { + "handles": + [], + "pid": 7528, + "arguments": "sh \"C:\\\\Program Files\\\\Git\\\\mingw64\\\\bin\\\\git-update-git-for-windows\" --quiet --gui", + "file": + { + "file": + { + "path": "C:\\Program Files\\Git\\usr\\bin\\sh.exe", + "hash": + { + "md5": "0d46559e826c8a7b5d432d0a91954ba2" + } + }, + "instance_hash": "4573824187960625975", + "artifact_hash": "4573824187960625975" + }, + "user": + { + "user": + { + "name": "Bob", + "domain": "MEDIATOO" + } + }, + "start_time": "2022-06-10T23:19:37.000Z", + "tanium_unique_id": "8426546338933681227" + }, + "instance_hash": "2725601412602158353", + "artifact_hash": "6063500060437154276" + }, + "start_time": "2022-06-10T23:19:37.000Z", + "tanium_unique_id": "3601155573093657773" + }, + "instance_hash": "17370642301569032073", + "artifact_hash": "16343609532904785305", + "is_intel_target": "true" + } + } + }], + "domain": "threatresponse", + "intel_id": "365:2:761d796b-b362-455f-98ae-6d0472ecf640", + "hunt_id": "1", + "threat_id": "1204114022,1670888670,2753281896,3854795733", + "source_name": "recorder", + "system_info": + { + "os": "Microsoft Windows 11 Pro", + "bits": 64, + "platform": "Windows", + "build_number": "22000", + "patch_level": "10.0.22000.0.0" + }, + "first_seen": "2022-06-10T23:19:38.000Z", + "last_seen": "2022-06-10T23:19:38.000Z", + "finding_id": "2433404061633741123", + "reporting_id": "reporting-id-placeholder" + }, + "match": + { + "version": 1, + "type": "process", + "source": "recorder", + "hash": "16343609532904785305", + "properties": + { + "pid": 8372, + "args": "\"C:\\Program Files\\Git\\usr\\bin\\mktemp.exe\" -t gfw-install-XXXXXXXX.exe", + "recorder_unique_id": "3601155573093657773", + "start_time": "2022-06-10T23:19:37.000Z", + "ppid": 7528, + "user": "MEDIATOO\\Bob", + "file": + { + "md5": "2204459dcbf34aed8906daac26db6f56", + "fullpath": "C:\\Program Files\\Git\\usr\\bin\\mktemp.exe" + }, + "parent": + { + "pid": 7528, + "args": "sh \"C:\\\\Program Files\\\\Git\\\\mingw64\\\\bin\\\\git-update-git-for-windows\" --quiet --gui", + "recorder_unique_id": "8426546338933681227", + "start_time": "2022-06-10T23:19:37.000Z", + "ppid": 10396, + "user": "MEDIATOO\\Bob", + "file": + { + "md5": "0d46559e826c8a7b5d432d0a91954ba2", + "fullpath": "C:\\Program Files\\Git\\usr\\bin\\sh.exe" + } + } + } + } + }, + "MITRE Techniques": "[\"T1036\",\"T1036.001\"]", + "Impact Score": "" +} + +class TestTaniumResultsToStix(unittest.TestCase, object): + def test_get_observed_data_objects(self): + result_bundle = json_to_stix_translator.convert_to_stix( + data_source, map_data, [SAMPLE_DATA_DICT], get_module_transformers(MODULE), options) + result_bundle_objects = result_bundle['objects'] + + print(result_bundle_objects) + + result_bundle_identity = result_bundle_objects[0] + assert result_bundle_identity['type'] == data_source['type'] + observed_data = result_bundle_objects[1] + + assert 'objects' in observed_data \ No newline at end of file