From 1160ac6af000cb8f793c0c43ebb09949d17792c1 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 28 Sep 2021 10:52:54 +0300 Subject: [PATCH] Refactor dictionary and sensitive mongo field encryption by moving it to server_utils/encryption --- monkey/monkey_island/cc/models/__init__.py | 2 +- .../cc/models/report/__init__.py | 1 + .../cc/models/telemetries/telemetry_dal.py | 13 +++++++++---- .../cc/server_utils/encryption/__init__.py | 8 ++++++++ .../encryption/dict_encryption/__init__.py | 0 .../dict_encryption}/dict_encryptor.py | 8 +++++--- .../field_encryptors/__init__.py | 0 .../field_encryptors/i_field_encryptor.py | 0 .../mimikatz_results_encryptor.py | 4 +++- .../field_encryptors/string_list_encryptor.py | 4 +++- monkey/monkey_island/cc/utils/__init__.py | 1 - .../models/telemetries/test_telemetry_dal.py | 6 ++++-- ...est_report_model.py => test_report_dal.py} | 19 ++++++++++++------- .../test_string_list_encryptor.py | 4 +++- 14 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 monkey/monkey_island/cc/models/report/__init__.py create mode 100644 monkey/monkey_island/cc/server_utils/encryption/dict_encryption/__init__.py rename monkey/monkey_island/cc/{utils => server_utils/encryption/dict_encryption}/dict_encryptor.py (80%) rename monkey/monkey_island/cc/{utils => server_utils/encryption/dict_encryption}/field_encryptors/__init__.py (100%) rename monkey/monkey_island/cc/{utils => server_utils/encryption/dict_encryption}/field_encryptors/i_field_encryptor.py (100%) rename monkey/monkey_island/cc/{utils => server_utils/encryption/dict_encryption}/field_encryptors/mimikatz_results_encryptor.py (91%) rename monkey/monkey_island/cc/{utils => server_utils/encryption/dict_encryption}/field_encryptors/string_list_encryptor.py (78%) delete mode 100644 monkey/monkey_island/cc/utils/__init__.py rename monkey/tests/unit_tests/monkey_island/cc/models/{test_report_model.py => test_report_dal.py} (76%) diff --git a/monkey/monkey_island/cc/models/__init__.py b/monkey/monkey_island/cc/models/__init__.py index 3464154b5..cab95ae18 100644 --- a/monkey/monkey_island/cc/models/__init__.py +++ b/monkey/monkey_island/cc/models/__init__.py @@ -7,4 +7,4 @@ from .creds import Creds from .monkey import Monkey from .monkey_ttl import MonkeyTtl from .pba_results import PbaResults -from .report import Report +from monkey_island.cc.models.report.report import Report diff --git a/monkey/monkey_island/cc/models/report/__init__.py b/monkey/monkey_island/cc/models/report/__init__.py new file mode 100644 index 000000000..ba3d7d9e0 --- /dev/null +++ b/monkey/monkey_island/cc/models/report/__init__.py @@ -0,0 +1 @@ +from .report_dal import save_report, get_report diff --git a/monkey/monkey_island/cc/models/telemetries/telemetry_dal.py b/monkey/monkey_island/cc/models/telemetries/telemetry_dal.py index 88e617725..c036c5776 100644 --- a/monkey/monkey_island/cc/models/telemetries/telemetry_dal.py +++ b/monkey/monkey_island/cc/models/telemetries/telemetry_dal.py @@ -5,8 +5,13 @@ from typing import List from monkey_island.cc.database import mongo from monkey_island.cc.models import CommandControlChannel from monkey_island.cc.models.telemetries.telemetry import Telemetry -from monkey_island.cc.utils import FieldNotFoundError, SensitiveField, dict_encryptor -from monkey_island.cc.utils.field_encryptors import MimikatzResultsEncryptor +from monkey_island.cc.server_utils.encryption import ( + FieldNotFoundError, + MimikatzResultsEncryptor, + SensitiveField, + decrypt_dict, + encrypt_dict, +) sensitive_fields = [ SensitiveField("data.credentials", MimikatzResultsEncryptor), @@ -16,7 +21,7 @@ sensitive_fields = [ def save_telemetry(telemetry_dict: dict): try: - telemetry_dict = dict_encryptor.encrypt(sensitive_fields, telemetry_dict) + telemetry_dict = encrypt_dict(sensitive_fields, telemetry_dict) except FieldNotFoundError: pass # Not all telemetries require encryption @@ -40,7 +45,7 @@ def get_telemetry_by_query(query: dict, output_fields=None) -> List[dict]: decrypted_list = [] for telemetry in telemetries: try: - decrypted_list.append(dict_encryptor.decrypt(sensitive_fields, telemetry)) + decrypted_list.append(decrypt_dict(sensitive_fields, telemetry)) except FieldNotFoundError: decrypted_list.append(telemetry) return decrypted_list diff --git a/monkey/monkey_island/cc/server_utils/encryption/__init__.py b/monkey/monkey_island/cc/server_utils/encryption/__init__.py index a41240be1..7d806139c 100644 --- a/monkey/monkey_island/cc/server_utils/encryption/__init__.py +++ b/monkey/monkey_island/cc/server_utils/encryption/__init__.py @@ -11,3 +11,11 @@ from monkey_island.cc.server_utils.encryption.data_store_encryptor import ( get_datastore_encryptor, initialize_datastore_encryptor, ) +from .dict_encryption.dict_encryptor import ( + SensitiveField, + encrypt_dict, + decrypt_dict, + FieldNotFoundError, +) +from .dict_encryption.field_encryptors.mimikatz_results_encryptor import MimikatzResultsEncryptor +from .dict_encryption.field_encryptors.string_list_encryptor import StringListEncryptor diff --git a/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/__init__.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/utils/dict_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/dict_encryptor.py similarity index 80% rename from monkey/monkey_island/cc/utils/dict_encryptor.py rename to monkey/monkey_island/cc/server_utils/encryption/dict_encryption/dict_encryptor.py index 9a6d1d3d0..a95a761e0 100644 --- a/monkey/monkey_island/cc/utils/dict_encryptor.py +++ b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/dict_encryptor.py @@ -3,7 +3,9 @@ from typing import Callable, List, Type import dpath.util -from monkey_island.cc.utils.field_encryptors import IFieldEncryptor +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + IFieldEncryptor, +) class FieldNotFoundError(Exception): @@ -17,7 +19,7 @@ class SensitiveField: field_encryptor: Type[IFieldEncryptor] -def encrypt(sensitive_fields: List[SensitiveField], document_dict: dict) -> dict: +def encrypt_dict(sensitive_fields: List[SensitiveField], document_dict: dict) -> dict: for sensitive_field in sensitive_fields: _apply_operation_to_document_field( document_dict, sensitive_field, sensitive_field.field_encryptor.encrypt @@ -26,7 +28,7 @@ def encrypt(sensitive_fields: List[SensitiveField], document_dict: dict) -> dict return document_dict -def decrypt(sensitive_fields: List[SensitiveField], document_dict: dict) -> dict: +def decrypt_dict(sensitive_fields: List[SensitiveField], document_dict: dict) -> dict: for sensitive_field in sensitive_fields: _apply_operation_to_document_field( document_dict, sensitive_field, sensitive_field.field_encryptor.decrypt diff --git a/monkey/monkey_island/cc/utils/field_encryptors/__init__.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/__init__.py similarity index 100% rename from monkey/monkey_island/cc/utils/field_encryptors/__init__.py rename to monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/__init__.py diff --git a/monkey/monkey_island/cc/utils/field_encryptors/i_field_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/i_field_encryptor.py similarity index 100% rename from monkey/monkey_island/cc/utils/field_encryptors/i_field_encryptor.py rename to monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/i_field_encryptor.py diff --git a/monkey/monkey_island/cc/utils/field_encryptors/mimikatz_results_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/mimikatz_results_encryptor.py similarity index 91% rename from monkey/monkey_island/cc/utils/field_encryptors/mimikatz_results_encryptor.py rename to monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/mimikatz_results_encryptor.py index 6708ec40c..6261f5147 100644 --- a/monkey/monkey_island/cc/utils/field_encryptors/mimikatz_results_encryptor.py +++ b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/mimikatz_results_encryptor.py @@ -1,7 +1,9 @@ import logging from monkey_island.cc.server_utils.encryption import get_datastore_encryptor -from monkey_island.cc.utils.field_encryptors import IFieldEncryptor +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + IFieldEncryptor, +) logger = logging.getLogger(__name__) diff --git a/monkey/monkey_island/cc/utils/field_encryptors/string_list_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/string_list_encryptor.py similarity index 78% rename from monkey/monkey_island/cc/utils/field_encryptors/string_list_encryptor.py rename to monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/string_list_encryptor.py index f939c0e22..46eef09cb 100644 --- a/monkey/monkey_island/cc/utils/field_encryptors/string_list_encryptor.py +++ b/monkey/monkey_island/cc/server_utils/encryption/dict_encryption/field_encryptors/string_list_encryptor.py @@ -1,7 +1,9 @@ from typing import List from monkey_island.cc.server_utils.encryption import get_datastore_encryptor -from monkey_island.cc.utils.field_encryptors import IFieldEncryptor +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + IFieldEncryptor, +) class StringListEncryptor(IFieldEncryptor): diff --git a/monkey/monkey_island/cc/utils/__init__.py b/monkey/monkey_island/cc/utils/__init__.py deleted file mode 100644 index abe040645..000000000 --- a/monkey/monkey_island/cc/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .dict_encryptor import FieldNotFoundError, SensitiveField diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/test_telemetry_dal.py b/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/test_telemetry_dal.py index f25e8ffb3..d6a35760a 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/test_telemetry_dal.py +++ b/monkey/tests/unit_tests/monkey_island/cc/models/telemetries/test_telemetry_dal.py @@ -6,8 +6,10 @@ import pytest from monkey_island.cc.models.telemetries import get_telemetry_by_query, save_telemetry from monkey_island.cc.models.telemetries.telemetry import Telemetry -from monkey_island.cc.utils import SensitiveField -from monkey_island.cc.utils.field_encryptors import MimikatzResultsEncryptor +from monkey_island.cc.server_utils.encryption import SensitiveField +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + MimikatzResultsEncryptor, +) MOCK_CREDENTIALS = { "Vakaris": { diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/test_report_model.py b/monkey/tests/unit_tests/monkey_island/cc/models/test_report_dal.py similarity index 76% rename from monkey/tests/unit_tests/monkey_island/cc/models/test_report_model.py rename to monkey/tests/unit_tests/monkey_island/cc/models/test_report_dal.py index 0c8fd90de..5d3d5a49a 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/models/test_report_model.py +++ b/monkey/tests/unit_tests/monkey_island/cc/models/test_report_dal.py @@ -4,8 +4,11 @@ from typing import List import pytest from monkey_island.cc.models import Report -from monkey_island.cc.utils import SensitiveField -from monkey_island.cc.utils.field_encryptors import IFieldEncryptor +from monkey_island.cc.models.report import get_report, save_report +from monkey_island.cc.server_utils.encryption import SensitiveField +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + IFieldEncryptor, +) MOCK_SENSITIVE_FIELD_CONTENTS = ["the_string", "the_string2"] MOCK_REPORT_DICT = { @@ -42,26 +45,28 @@ def patch_sensitive_fields(monkeypatch): SensitiveField("overview.foo.the_key", MockStringListEncryptor), SensitiveField("overview.bar.the_key", MockStringListEncryptor), ] - monkeypatch.setattr("monkey_island.cc.models.report.sensitive_fields", mock_sensitive_fields) + monkeypatch.setattr( + "monkey_island.cc.models.report.report_dal.sensitive_fields", mock_sensitive_fields + ) @pytest.mark.usefixtures("uses_database") def test_report_encryption(): - Report.save_report(MOCK_REPORT_DICT) + save_report(MOCK_REPORT_DICT) assert Report.objects.first()["overview"]["foo"]["the_key"] == ["ENCRYPTED_0", "ENCRYPTED_1"] assert Report.objects.first()["overview"]["bar"]["the_key"] == [] - assert Report.get_report()["overview"]["foo"]["the_key"] == MOCK_SENSITIVE_FIELD_CONTENTS + assert get_report()["overview"]["foo"]["the_key"] == MOCK_SENSITIVE_FIELD_CONTENTS @pytest.mark.usefixtures("uses_database") def test_report_dot_encoding(): mrd = copy.deepcopy(MOCK_REPORT_DICT) mrd["meta_info"] = {"foo.bar": "baz"} - Report.save_report(mrd) + save_report(mrd) assert "foo.bar" not in Report.objects.first()["meta_info"] assert "foo,,,bar" in Report.objects.first()["meta_info"] - report = Report.get_report() + report = get_report() assert "foo.bar" in report["meta_info"] diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/utils/field_encryptors/test_string_list_encryptor.py b/monkey/tests/unit_tests/monkey_island/cc/models/utils/field_encryptors/test_string_list_encryptor.py index ac46898c0..d02ad5bbb 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/models/utils/field_encryptors/test_string_list_encryptor.py +++ b/monkey/tests/unit_tests/monkey_island/cc/models/utils/field_encryptors/test_string_list_encryptor.py @@ -1,7 +1,9 @@ import pytest from monkey_island.cc.server_utils.encryption import initialize_datastore_encryptor -from monkey_island.cc.utils.field_encryptors import StringListEncryptor +from monkey_island.cc.server_utils.encryption.dict_encryption.field_encryptors import ( + StringListEncryptor, +) MOCK_STRING_LIST = ["test_1", "test_2"] EMPTY_LIST = []