forked from p15670423/monkey
Agent: Add InPlaceEncryptor
InPlaceEncryptor encrypts a file in place. It accepts a callable that performs the actual bit manipulation. This allows the in-place encryption functionality to be easily reused, while the actual encryption algorithm can be changed.
This commit is contained in:
parent
ce2ad81321
commit
55ba5f530d
|
@ -0,0 +1,21 @@
|
|||
from pathlib import Path
|
||||
from typing import Callable
|
||||
|
||||
|
||||
class InPlaceEncryptor:
|
||||
def __init__(self, encrypt_bytes: Callable[[bytes], bytes], chunk_size: int = 64):
|
||||
self._encrypt_bytes = encrypt_bytes
|
||||
self._chunk_size = chunk_size
|
||||
|
||||
def __call__(self, filepath: Path):
|
||||
with open(filepath, "rb+") as f:
|
||||
data = f.read(self._chunk_size)
|
||||
while data:
|
||||
num_bytes_read = len(data)
|
||||
|
||||
encrypted_data = self._encrypt_bytes(data)
|
||||
|
||||
f.seek(-num_bytes_read, 1)
|
||||
f.write(encrypted_data)
|
||||
|
||||
data = f.read(self._chunk_size)
|
|
@ -0,0 +1,49 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
from tests.unit_tests.infection_monkey.ransomware.ransomware_target_files import (
|
||||
ALL_ZEROS_PDF,
|
||||
ALL_ZEROS_PDF_CLEARTEXT_SHA256,
|
||||
ALL_ZEROS_PDF_ENCRYPTED_SHA256,
|
||||
TEST_KEYBOARD_TXT,
|
||||
TEST_KEYBOARD_TXT_CLEARTEXT_SHA256,
|
||||
TEST_KEYBOARD_TXT_ENCRYPTED_SHA256,
|
||||
)
|
||||
from tests.utils import hash_file
|
||||
|
||||
from infection_monkey.ransomware.in_place_encryptor import InPlaceEncryptor
|
||||
from infection_monkey.utils.bit_manipulators import flip_bits
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def in_place_bitflip_encryptor():
|
||||
return InPlaceEncryptor(flip_bits, 64)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"file_name,cleartext_hash,encrypted_hash",
|
||||
[
|
||||
(TEST_KEYBOARD_TXT, TEST_KEYBOARD_TXT_CLEARTEXT_SHA256, TEST_KEYBOARD_TXT_ENCRYPTED_SHA256),
|
||||
(ALL_ZEROS_PDF, ALL_ZEROS_PDF_CLEARTEXT_SHA256, ALL_ZEROS_PDF_ENCRYPTED_SHA256),
|
||||
],
|
||||
)
|
||||
def test_file_encrypted(
|
||||
in_place_bitflip_encryptor, ransomware_target, file_name, cleartext_hash, encrypted_hash
|
||||
):
|
||||
test_keyboard = ransomware_target / file_name
|
||||
|
||||
assert hash_file(test_keyboard) == cleartext_hash
|
||||
|
||||
in_place_bitflip_encryptor(test_keyboard)
|
||||
|
||||
assert hash_file(test_keyboard) == encrypted_hash
|
||||
|
||||
|
||||
def test_file_encrypted_in_place(in_place_bitflip_encryptor, ransomware_target):
|
||||
test_keyboard = ransomware_target / TEST_KEYBOARD_TXT
|
||||
|
||||
expected_inode = os.stat(test_keyboard).st_ino
|
||||
in_place_bitflip_encryptor(test_keyboard)
|
||||
actual_inode = os.stat(test_keyboard).st_ino
|
||||
|
||||
assert expected_inode == actual_inode
|
Loading…
Reference in New Issue