Skip to content

Commit

Permalink
Merge pull request #1280 from guardicore/ransomware-encryption-bool
Browse files Browse the repository at this point in the history
Add encryption checkbox to ransomware config page
  • Loading branch information
mssalvatore authored Jun 30, 2021
2 parents 0f6a712 + 169bb34 commit 3fb8c06
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 29 deletions.
29 changes: 16 additions & 13 deletions monkey/infection_monkey/ransomware/ransomware_payload.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import shutil
from pathlib import Path
from pprint import pformat
from typing import List, Optional, Tuple

from infection_monkey.ransomware.bitflip_encryptor import BitflipEncryptor
Expand All @@ -21,21 +22,18 @@

class RansomwarePayload:
def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
target_directories = config["directories"]
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']}\"")
LOG.debug(f"Ransomware payload configuration:\n{pformat(config)}")

self._encryption_enabled = config["encryption"]["enabled"]
self._readme_enabled = config["other_behaviors"]["readme"]

target_directories = config["encryption"]["directories"]
self._target_dir = (
target_directories["windows_dir"]
target_directories["windows_target_dir"]
if is_windows_os()
else target_directories["linux_dir"]
else target_directories["linux_target_dir"]
)

self._readme_enabled = config["other_behaviors"]["readme"]
LOG.info(f"README enabled: {self._readme_enabled}")

self._new_file_extension = EXTENSION
self._valid_file_extensions_for_encryption = VALID_FILE_EXTENSIONS_FOR_ENCRYPTION.copy()
self._valid_file_extensions_for_encryption.discard(self._new_file_extension)
Expand All @@ -44,12 +42,15 @@ def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
self._telemetry_messenger = telemetry_messenger

def run_payload(self):
LOG.info("Running ransomware payload")
file_list = self._find_files()
self._encrypt_files(file_list)
if self._encryption_enabled:
LOG.info("Running ransomware payload")
file_list = self._find_files()
self._encrypt_files(file_list)

self._leave_readme()

def _find_files(self) -> List[Path]:
LOG.info(f"Collecting files in {self._target_dir}")
if not self._target_dir:
return []

Expand All @@ -58,6 +59,8 @@ def _find_files(self) -> List[Path]:
)

def _encrypt_files(self, file_list: List[Path]) -> List[Tuple[Path, Optional[Exception]]]:
LOG.info(f"Encrypting files in {self._target_dir}")

results = []
for filepath in file_list:
try:
Expand Down
45 changes: 30 additions & 15 deletions monkey/monkey_island/cc/services/config_schema/ransomware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,43 @@
"title": "Ransomware",
"type": "object",
"properties": {
"directories": {
"title": "Directories to encrypt",
"encryption": {
"title": "Encryption",
"type": "object",
"properties": {
"linux_dir": {
"title": "Linux encryptable directory",
"type": "string",
"default": "",
"description": "Files in the specified directory will be encrypted "
"using bitflip to simulate ransomware.",
"enabled": {
"title": "Encrypt files",
"type": "boolean",
"default": True,
"description": "Ransomware encryption will be simulated by flipping every bit "
"in the files contained within the target directories.",
},
"windows_dir": {
"title": "Windows encryptable directory",
"type": "string",
"default": "",
"description": "Files in the specified directory will be encrypted "
"using bitflip to simulate ransomware.",
"directories": {
"title": "Directories to encrypt",
"type": "object",
"properties": {
"linux_target_dir": {
"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": {
"title": "Other Behaviors",
"title": "Other behavior",
"type": "object",
"properties": {
"readme": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ def with_extension(filename):
@pytest.fixture
def ransomware_payload_config(ransomware_target):
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},
}

Expand Down Expand Up @@ -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):
ransomware_payload.run_payload()

Expand Down

0 comments on commit 3fb8c06

Please sign in to comment.