Merge pull request #1280 from guardicore/ransomware-encryption-bool

Add encryption checkbox to ransomware config page
This commit is contained in:
Mike Salvatore 2021-06-30 07:46:22 -04:00 committed by GitHub
commit 3fb8c06102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import logging import logging
import shutil import shutil
from pathlib import Path from pathlib import Path
from pprint import pformat
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
from infection_monkey.ransomware.bitflip_encryptor import BitflipEncryptor from infection_monkey.ransomware.bitflip_encryptor import BitflipEncryptor
@ -21,20 +22,17 @@ README_DEST = "README.txt"
class RansomwarePayload: class RansomwarePayload:
def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger): def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
target_directories = config["directories"] LOG.debug(f"Ransomware payload configuration:\n{pformat(config)}")
LOG.info(
f"Windows dir configured for encryption is \"{target_directories['windows_dir']}\""
)
LOG.info(f"Linux dir configured for encryption is \"{target_directories['linux_dir']}\"")
self._target_dir = (
target_directories["windows_dir"]
if is_windows_os()
else target_directories["linux_dir"]
)
self._encryption_enabled = config["encryption"]["enabled"]
self._readme_enabled = config["other_behaviors"]["readme"] self._readme_enabled = config["other_behaviors"]["readme"]
LOG.info(f"README enabled: {self._readme_enabled}")
target_directories = config["encryption"]["directories"]
self._target_dir = (
target_directories["windows_target_dir"]
if is_windows_os()
else target_directories["linux_target_dir"]
)
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()
@ -44,12 +42,15 @@ class RansomwarePayload:
self._telemetry_messenger = telemetry_messenger self._telemetry_messenger = telemetry_messenger
def run_payload(self): def run_payload(self):
LOG.info("Running ransomware payload") if self._encryption_enabled:
file_list = self._find_files() LOG.info("Running ransomware payload")
self._encrypt_files(file_list) file_list = self._find_files()
self._encrypt_files(file_list)
self._leave_readme() self._leave_readme()
def _find_files(self) -> List[Path]: def _find_files(self) -> List[Path]:
LOG.info(f"Collecting files in {self._target_dir}")
if not self._target_dir: if not self._target_dir:
return [] return []
@ -58,6 +59,8 @@ class RansomwarePayload:
) )
def _encrypt_files(self, file_list: List[Path]) -> List[Tuple[Path, Optional[Exception]]]: def _encrypt_files(self, file_list: List[Path]) -> List[Tuple[Path, Optional[Exception]]]:
LOG.info(f"Encrypting files in {self._target_dir}")
results = [] results = []
for filepath in file_list: for filepath in file_list:
try: try:

View File

@ -2,28 +2,43 @@ RANSOMWARE = {
"title": "Ransomware", "title": "Ransomware",
"type": "object", "type": "object",
"properties": { "properties": {
"directories": { "encryption": {
"title": "Directories to encrypt", "title": "Encryption",
"type": "object", "type": "object",
"properties": { "properties": {
"linux_dir": { "enabled": {
"title": "Linux encryptable directory", "title": "Encrypt files",
"type": "string", "type": "boolean",
"default": "", "default": True,
"description": "Files in the specified directory will be encrypted " "description": "Ransomware encryption will be simulated by flipping every bit "
"using bitflip to simulate ransomware.", "in the files contained within the target directories.",
}, },
"windows_dir": { "directories": {
"title": "Windows encryptable directory", "title": "Directories to encrypt",
"type": "string", "type": "object",
"default": "", "properties": {
"description": "Files in the specified directory will be encrypted " "linux_target_dir": {
"using bitflip to simulate ransomware.", "title": "Linux target directory",
"type": "string",
"default": "",
"description": "A path to a directory on Linux systems that can be "
"used to safely simulate the encryption behavior of ransomware. If no "
"directory is specified, no files will be encrypted.",
},
"windows_target_dir": {
"title": "Windows target directory",
"type": "string",
"default": "",
"description": "A path to a directory on Windows systems that can be "
"used to safely simulate the encryption behavior of ransomware. If no "
"directory is specified, no files will be encrypted.",
},
},
}, },
}, },
}, },
"other_behaviors": { "other_behaviors": {
"title": "Other Behaviors", "title": "Other behavior",
"type": "object", "type": "object",
"properties": { "properties": {
"readme": { "readme": {

View File

@ -32,7 +32,13 @@ 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)}, "encryption": {
"enabled": True,
"directories": {
"linux_target_dir": str(ransomware_target),
"windows_target_dir": str(ransomware_target),
},
},
"other_behaviors": {"readme": False}, "other_behaviors": {"readme": False},
} }
@ -127,6 +133,18 @@ def test_skip_already_encrypted_file(ransomware_target, ransomware_payload):
) )
def test_encryption_skipped_if_configured_false(
ransomware_payload_config, ransomware_target, telemetry_messenger_spy
):
ransomware_payload_config["encryption"]["enabled"] = False
ransomware_payload = RansomwarePayload(ransomware_payload_config, telemetry_messenger_spy)
ransomware_payload.run_payload()
assert hash_file(ransomware_target / ALL_ZEROS_PDF) == ALL_ZEROS_PDF_CLEARTEXT_SHA256
assert hash_file(ransomware_target / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
def test_telemetry_success(ransomware_payload, telemetry_messenger_spy): def test_telemetry_success(ransomware_payload, telemetry_messenger_spy):
ransomware_payload.run_payload() ransomware_payload.run_payload()