From df1f3cda780e1dd8fc598ba3e282f7d1ce5d552a Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 28 Jun 2021 13:30:53 -0400 Subject: [PATCH 1/4] agent: Add explicit fields to FileEncryptionTelem --- .../ransomware/ransomware_payload.py | 2 +- .../telemetry/file_encryption_telem.py | 6 +++--- .../ransomware/test_ransomware_payload.py | 12 ++++++------ .../telemetry/test_file_encryption_telem.py | 13 ++++++++++--- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/monkey/infection_monkey/ransomware/ransomware_payload.py b/monkey/infection_monkey/ransomware/ransomware_payload.py index f500ce67c..7753022ff 100644 --- a/monkey/infection_monkey/ransomware/ransomware_payload.py +++ b/monkey/infection_monkey/ransomware/ransomware_payload.py @@ -68,5 +68,5 @@ class RansomewarePayload: filepath.rename(new_filepath) def _send_telemetry(self, filepath: Path, error: str): - encryption_attempt = FileEncryptionTelem((str(filepath), str(error))) + encryption_attempt = FileEncryptionTelem(str(filepath), str(error)) self._telemetry_messenger.send_telemetry(encryption_attempt) diff --git a/monkey/infection_monkey/telemetry/file_encryption_telem.py b/monkey/infection_monkey/telemetry/file_encryption_telem.py index 4ea2ada0d..117140f91 100644 --- a/monkey/infection_monkey/telemetry/file_encryption_telem.py +++ b/monkey/infection_monkey/telemetry/file_encryption_telem.py @@ -1,4 +1,4 @@ -from typing import Tuple +from pathlib import Path from common.common_consts.telem_categories import TelemCategoryEnum from infection_monkey.telemetry.base_telem import BaseTelem @@ -7,7 +7,7 @@ from infection_monkey.telemetry.i_batchable_telem import IBatchableTelem class FileEncryptionTelem(BatchableTelemMixin, IBatchableTelem, BaseTelem): - def __init__(self, entry: Tuple[str, str]): + def __init__(self, filepath: Path, error: str): """ File Encryption telemetry constructor :param attempts: List of tuples with each tuple containing the path @@ -17,7 +17,7 @@ class FileEncryptionTelem(BatchableTelemMixin, IBatchableTelem, BaseTelem): """ super().__init__() - self._telemetry_entries.append(entry) + self._telemetry_entries.append({"path": filepath, "error": error}) telem_category = TelemCategoryEnum.FILE_ENCRYPTION diff --git a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py index bead17ed5..c2d13085e 100644 --- a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py +++ b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py @@ -133,10 +133,10 @@ def test_telemetry_success(ransomware_payload, telemetry_messenger_spy): telem_1 = telemetry_messenger_spy.telemetries[0] telem_2 = telemetry_messenger_spy.telemetries[1] - assert ALL_ZEROS_PDF in telem_1.get_data()["files"][0][0] - assert telem_1.get_data()["files"][0][1] == "" - assert TEST_KEYBOARD_TXT in telem_2.get_data()["files"][0][0] - assert telem_2.get_data()["files"][0][1] == "" + assert ALL_ZEROS_PDF in telem_1.get_data()["files"][0]["path"] + assert telem_1.get_data()["files"][0]["error"] == "" + assert TEST_KEYBOARD_TXT in telem_2.get_data()["files"][0]["path"] + assert telem_2.get_data()["files"][0]["error"] == "" def test_telemetry_failure(monkeypatch, ransomware_payload, telemetry_messenger_spy): @@ -149,5 +149,5 @@ def test_telemetry_failure(monkeypatch, ransomware_payload, telemetry_messenger_ ransomware_payload.run_payload() telem_1 = telemetry_messenger_spy.telemetries[0] - assert "/file/not/exist" in telem_1.get_data()["files"][0][0] - assert "No such file or directory" in telem_1.get_data()["files"][0][1] + assert "/file/not/exist" in telem_1.get_data()["files"][0]["path"] + assert "No such file or directory" in telem_1.get_data()["files"][0]["error"] diff --git a/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py b/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py index 6152942e6..07dd556dd 100644 --- a/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py +++ b/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py @@ -2,12 +2,19 @@ import json from infection_monkey.telemetry.file_encryption_telem import FileEncryptionTelem -ENCRYPTION_ATTEMPTS = [("", ""), ("", "")] +ENCRYPTION_ATTEMPTS = [ + {"path": "", "error": ""}, + {"path": "", "error": ""}, +] def test_file_encryption_telem_send(spy_send_telemetry): - file_encryption_telem_1 = FileEncryptionTelem(ENCRYPTION_ATTEMPTS[0]) - file_encryption_telem_2 = FileEncryptionTelem(ENCRYPTION_ATTEMPTS[1]) + file_encryption_telem_1 = FileEncryptionTelem( + ENCRYPTION_ATTEMPTS[0]["path"], ENCRYPTION_ATTEMPTS[0]["error"] + ) + file_encryption_telem_2 = FileEncryptionTelem( + ENCRYPTION_ATTEMPTS[1]["path"], ENCRYPTION_ATTEMPTS[1]["error"] + ) file_encryption_telem_1.add_telemetry_to_batch(file_encryption_telem_2) From c1af3f8165b24c4e8d7e8c6974687eddfaaa6679 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 28 Jun 2021 13:31:28 -0400 Subject: [PATCH 2/4] agent: Fix failing ransomware test on Windows --- .../infection_monkey/ransomware/test_ransomware_payload.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py index c2d13085e..70c43e8c6 100644 --- a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py +++ b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py @@ -1,5 +1,5 @@ import os -from pathlib import PurePath +from pathlib import PurePosixPath import pytest from tests.unit_tests.infection_monkey.ransomware.ransomware_target_files import ( @@ -143,7 +143,7 @@ def test_telemetry_failure(monkeypatch, ransomware_payload, telemetry_messenger_ monkeypatch.setattr( ransomware_payload_module, "select_production_safe_target_files", - lambda a, b: [PurePath("/file/not/exist")], + lambda a, b: [PurePosixPath("/file/not/exist")], ), ransomware_payload.run_payload() From dbd6dedb954ac659d7b0d443c21fb724e2ca591e Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 28 Jun 2021 13:37:00 -0400 Subject: [PATCH 3/4] agent: Add explicit "success" field to FileEncryptionTelem --- .../ransomware/ransomware_payload.py | 8 ++++---- .../telemetry/file_encryption_telem.py | 4 ++-- .../ransomware/test_ransomware_payload.py | 3 +++ .../telemetry/test_file_encryption_telem.py | 12 ++++++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/monkey/infection_monkey/ransomware/ransomware_payload.py b/monkey/infection_monkey/ransomware/ransomware_payload.py index 7753022ff..e0f9fe7ec 100644 --- a/monkey/infection_monkey/ransomware/ransomware_payload.py +++ b/monkey/infection_monkey/ransomware/ransomware_payload.py @@ -56,10 +56,10 @@ class RansomewarePayload: LOG.debug(f"Encrypting {filepath}") self._encryptor.encrypt_file_in_place(filepath) self._add_extension(filepath) - self._send_telemetry(filepath, "") + self._send_telemetry(filepath, True, "") except Exception as ex: LOG.warning(f"Error encrypting {filepath}: {ex}") - self._send_telemetry(filepath, str(ex)) + self._send_telemetry(filepath, False, str(ex)) return results @@ -67,6 +67,6 @@ class RansomewarePayload: new_filepath = filepath.with_suffix(f"{filepath.suffix}{self._new_file_extension}") filepath.rename(new_filepath) - def _send_telemetry(self, filepath: Path, error: str): - encryption_attempt = FileEncryptionTelem(str(filepath), str(error)) + def _send_telemetry(self, filepath: Path, success: bool, error: str): + encryption_attempt = FileEncryptionTelem(str(filepath), success, error) self._telemetry_messenger.send_telemetry(encryption_attempt) diff --git a/monkey/infection_monkey/telemetry/file_encryption_telem.py b/monkey/infection_monkey/telemetry/file_encryption_telem.py index 117140f91..ff298d3cc 100644 --- a/monkey/infection_monkey/telemetry/file_encryption_telem.py +++ b/monkey/infection_monkey/telemetry/file_encryption_telem.py @@ -7,7 +7,7 @@ from infection_monkey.telemetry.i_batchable_telem import IBatchableTelem class FileEncryptionTelem(BatchableTelemMixin, IBatchableTelem, BaseTelem): - def __init__(self, filepath: Path, error: str): + def __init__(self, filepath: Path, success: bool, error: str): """ File Encryption telemetry constructor :param attempts: List of tuples with each tuple containing the path @@ -17,7 +17,7 @@ class FileEncryptionTelem(BatchableTelemMixin, IBatchableTelem, BaseTelem): """ super().__init__() - self._telemetry_entries.append({"path": filepath, "error": error}) + self._telemetry_entries.append({"path": filepath, "success": success, "error": error}) telem_category = TelemCategoryEnum.FILE_ENCRYPTION diff --git a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py index 70c43e8c6..7557c5055 100644 --- a/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py +++ b/monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py @@ -134,8 +134,10 @@ def test_telemetry_success(ransomware_payload, telemetry_messenger_spy): telem_2 = telemetry_messenger_spy.telemetries[1] assert ALL_ZEROS_PDF in telem_1.get_data()["files"][0]["path"] + assert telem_1.get_data()["files"][0]["success"] assert telem_1.get_data()["files"][0]["error"] == "" assert TEST_KEYBOARD_TXT in telem_2.get_data()["files"][0]["path"] + assert telem_2.get_data()["files"][0]["success"] assert telem_2.get_data()["files"][0]["error"] == "" @@ -150,4 +152,5 @@ def test_telemetry_failure(monkeypatch, ransomware_payload, telemetry_messenger_ telem_1 = telemetry_messenger_spy.telemetries[0] assert "/file/not/exist" in telem_1.get_data()["files"][0]["path"] + assert not telem_1.get_data()["files"][0]["success"] assert "No such file or directory" in telem_1.get_data()["files"][0]["error"] diff --git a/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py b/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py index 07dd556dd..b6d55b9d0 100644 --- a/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py +++ b/monkey/tests/unit_tests/infection_monkey/telemetry/test_file_encryption_telem.py @@ -3,17 +3,21 @@ import json from infection_monkey.telemetry.file_encryption_telem import FileEncryptionTelem ENCRYPTION_ATTEMPTS = [ - {"path": "", "error": ""}, - {"path": "", "error": ""}, + {"path": "", "success": False, "error": ""}, + {"path": "", "success": True, "error": ""}, ] def test_file_encryption_telem_send(spy_send_telemetry): file_encryption_telem_1 = FileEncryptionTelem( - ENCRYPTION_ATTEMPTS[0]["path"], ENCRYPTION_ATTEMPTS[0]["error"] + ENCRYPTION_ATTEMPTS[0]["path"], + ENCRYPTION_ATTEMPTS[0]["success"], + ENCRYPTION_ATTEMPTS[0]["error"], ) file_encryption_telem_2 = FileEncryptionTelem( - ENCRYPTION_ATTEMPTS[1]["path"], ENCRYPTION_ATTEMPTS[1]["error"] + ENCRYPTION_ATTEMPTS[1]["path"], + ENCRYPTION_ATTEMPTS[1]["success"], + ENCRYPTION_ATTEMPTS[1]["error"], ) file_encryption_telem_1.add_telemetry_to_batch(file_encryption_telem_2) From 444a18d57ab985cec9af03d257cdbd33cc6f0827 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 29 Jun 2021 08:15:39 -0400 Subject: [PATCH 4/4] agent: Fix parameter descriptions in FileEncryptionTelem docstring --- monkey/infection_monkey/telemetry/file_encryption_telem.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/telemetry/file_encryption_telem.py b/monkey/infection_monkey/telemetry/file_encryption_telem.py index ff298d3cc..7f18867ab 100644 --- a/monkey/infection_monkey/telemetry/file_encryption_telem.py +++ b/monkey/infection_monkey/telemetry/file_encryption_telem.py @@ -10,10 +10,9 @@ class FileEncryptionTelem(BatchableTelemMixin, IBatchableTelem, BaseTelem): def __init__(self, filepath: Path, success: bool, error: str): """ File Encryption telemetry constructor - :param attempts: List of tuples with each tuple containing the path - of a file it tried encrypting and its result. - If ransomware fails completely - list of one tuple - containing the directory path and error string. + :param filepath: The path to the file that monkey attempted to encrypt + :param success: True if encryption was successful, false otherwise + :param error: An error message describing the failure. Empty unless success == False """ super().__init__()