From 1ab0fe7b138947400a29408ffed2bbb96ef39199 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 22 Sep 2021 16:12:50 +0300 Subject: [PATCH] Add Telemetry model --- .../cc/models/telemetries/telemetry.py | 50 +++++++++++++++++++ .../mimikatz_results_encryptor.py | 21 ++++++++ .../cc/models/telemetries/__init__.py | 0 3 files changed, 71 insertions(+) create mode 100644 monkey/monkey_island/cc/models/telemetries/telemetry.py create mode 100644 monkey/monkey_island/cc/models/utils/field_encryptors/mimikatz_results_encryptor.py create mode 100644 monkey/tests/unit_tests/monkey_island/cc/models/telemetries/__init__.py diff --git a/monkey/monkey_island/cc/models/telemetries/telemetry.py b/monkey/monkey_island/cc/models/telemetries/telemetry.py new file mode 100644 index 000000000..bbefeb92f --- /dev/null +++ b/monkey/monkey_island/cc/models/telemetries/telemetry.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from mongoengine import DateTimeField, DictField, Document, EmbeddedDocumentField, StringField + +from monkey_island.cc.models import CommandControlChannel +from monkey_island.cc.models.utils import document_encryptor +from monkey_island.cc.models.utils.document_encryptor import FieldNotFoundError, SensitiveField +from monkey_island.cc.models.utils.field_encryptors.mimikatz_results_encryptor import ( + MimikatzResultsEncryptor, +) + +sensitive_fields = [ + SensitiveField("data.credentials", MimikatzResultsEncryptor), + SensitiveField("data.mimikatz", MimikatzResultsEncryptor), +] + + +class Telemetry(Document): + + data = DictField(required=True) + timestamp = DateTimeField(required=True) + monkey_guid = StringField(required=True) + telem_category = StringField(required=True) + command_control_channel = EmbeddedDocumentField(CommandControlChannel) + + meta = {"strict": False} + + @staticmethod + def save_telemetry(telemetry_dict: dict): + try: + telemetry_dict = document_encryptor.encrypt(sensitive_fields, telemetry_dict) + except FieldNotFoundError: + pass # Not all telemetries require encryption + + cc_channel = CommandControlChannel( + src=telemetry_dict["command_control_channel"]["src"], + dst=telemetry_dict["command_control_channel"]["dst"], + ) + Telemetry( + data=telemetry_dict["data"], + timestamp=telemetry_dict["timestamp"], + monkey_guid=telemetry_dict["monkey_guid"], + telem_category=telemetry_dict["telem_category"], + command_control_channel=cc_channel, + ).save() + + @staticmethod + def get_telemetry() -> dict: + telemetry_dict = Telemetry.objects.first().to_mongo() + return document_encryptor.decrypt(sensitive_fields, telemetry_dict) diff --git a/monkey/monkey_island/cc/models/utils/field_encryptors/mimikatz_results_encryptor.py b/monkey/monkey_island/cc/models/utils/field_encryptors/mimikatz_results_encryptor.py new file mode 100644 index 000000000..c924a64e9 --- /dev/null +++ b/monkey/monkey_island/cc/models/utils/field_encryptors/mimikatz_results_encryptor.py @@ -0,0 +1,21 @@ +from monkey_island.cc.models.utils.field_encryptors.i_field_encryptor import IFieldEncryptor +from monkey_island.cc.server_utils.encryptor import get_encryptor + + +class MimikatzResultsEncryptor(IFieldEncryptor): + + secret_types = ["password", "ntlm_hash", "lm_hash"] + + @staticmethod + def encrypt(results: dict) -> dict: + for _, credentials in results.items(): + for secret_type in MimikatzResultsEncryptor.secret_types: + credentials[secret_type] = get_encryptor().enc(credentials[secret_type]) + return results + + @staticmethod + def decrypt(results: dict) -> dict: + for _, credentials in results.items(): + for secret_type in MimikatzResultsEncryptor.secret_types: + credentials[secret_type] = get_encryptor().dec(credentials[secret_type]) + return results diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/__init__.py b/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/__init__.py new file mode 100644 index 000000000..e69de29bb