Refactor dictionary and sensitive mongo field encryption by moving it to server_utils/encryption

This commit is contained in:
VakarisZ 2021-09-28 10:52:54 +03:00
parent 8b9973238e
commit 1160ac6af0
14 changed files with 49 additions and 21 deletions

View File

@ -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

View File

@ -0,0 +1 @@
from .report_dal import save_report, get_report

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__)

View File

@ -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):

View File

@ -1 +0,0 @@
from .dict_encryptor import FieldNotFoundError, SensitiveField

View File

@ -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": {

View File

@ -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"]

View File

@ -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 = []