Skip to content

Commit 3fb8c06

Browse files
authored
Merge pull request #1280 from guardicore/ransomware-encryption-bool
Add encryption checkbox to ransomware config page
2 parents 0f6a712 + 169bb34 commit 3fb8c06

File tree

3 files changed

+65
-29
lines changed

3 files changed

+65
-29
lines changed

monkey/infection_monkey/ransomware/ransomware_payload.py

+16-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import shutil
33
from pathlib import Path
4+
from pprint import pformat
45
from typing import List, Optional, Tuple
56

67
from infection_monkey.ransomware.bitflip_encryptor import BitflipEncryptor
@@ -21,21 +22,18 @@
2122

2223
class RansomwarePayload:
2324
def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
24-
target_directories = config["directories"]
25-
LOG.info(
26-
f"Windows dir configured for encryption is \"{target_directories['windows_dir']}\""
27-
)
28-
LOG.info(f"Linux dir configured for encryption is \"{target_directories['linux_dir']}\"")
25+
LOG.debug(f"Ransomware payload configuration:\n{pformat(config)}")
26+
27+
self._encryption_enabled = config["encryption"]["enabled"]
28+
self._readme_enabled = config["other_behaviors"]["readme"]
2929

30+
target_directories = config["encryption"]["directories"]
3031
self._target_dir = (
31-
target_directories["windows_dir"]
32+
target_directories["windows_target_dir"]
3233
if is_windows_os()
33-
else target_directories["linux_dir"]
34+
else target_directories["linux_target_dir"]
3435
)
3536

36-
self._readme_enabled = config["other_behaviors"]["readme"]
37-
LOG.info(f"README enabled: {self._readme_enabled}")
38-
3937
self._new_file_extension = EXTENSION
4038
self._valid_file_extensions_for_encryption = VALID_FILE_EXTENSIONS_FOR_ENCRYPTION.copy()
4139
self._valid_file_extensions_for_encryption.discard(self._new_file_extension)
@@ -44,12 +42,15 @@ def __init__(self, config: dict, telemetry_messenger: ITelemetryMessenger):
4442
self._telemetry_messenger = telemetry_messenger
4543

4644
def run_payload(self):
47-
LOG.info("Running ransomware payload")
48-
file_list = self._find_files()
49-
self._encrypt_files(file_list)
45+
if self._encryption_enabled:
46+
LOG.info("Running ransomware payload")
47+
file_list = self._find_files()
48+
self._encrypt_files(file_list)
49+
5050
self._leave_readme()
5151

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

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

6061
def _encrypt_files(self, file_list: List[Path]) -> List[Tuple[Path, Optional[Exception]]]:
62+
LOG.info(f"Encrypting files in {self._target_dir}")
63+
6164
results = []
6265
for filepath in file_list:
6366
try:

monkey/monkey_island/cc/services/config_schema/ransomware.py

+30-15
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,43 @@
22
"title": "Ransomware",
33
"type": "object",
44
"properties": {
5-
"directories": {
6-
"title": "Directories to encrypt",
5+
"encryption": {
6+
"title": "Encryption",
77
"type": "object",
88
"properties": {
9-
"linux_dir": {
10-
"title": "Linux encryptable directory",
11-
"type": "string",
12-
"default": "",
13-
"description": "Files in the specified directory will be encrypted "
14-
"using bitflip to simulate ransomware.",
9+
"enabled": {
10+
"title": "Encrypt files",
11+
"type": "boolean",
12+
"default": True,
13+
"description": "Ransomware encryption will be simulated by flipping every bit "
14+
"in the files contained within the target directories.",
1515
},
16-
"windows_dir": {
17-
"title": "Windows encryptable directory",
18-
"type": "string",
19-
"default": "",
20-
"description": "Files in the specified directory will be encrypted "
21-
"using bitflip to simulate ransomware.",
16+
"directories": {
17+
"title": "Directories to encrypt",
18+
"type": "object",
19+
"properties": {
20+
"linux_target_dir": {
21+
"title": "Linux target directory",
22+
"type": "string",
23+
"default": "",
24+
"description": "A path to a directory on Linux systems that can be "
25+
"used to safely simulate the encryption behavior of ransomware. If no "
26+
"directory is specified, no files will be encrypted.",
27+
},
28+
"windows_target_dir": {
29+
"title": "Windows target directory",
30+
"type": "string",
31+
"default": "",
32+
"description": "A path to a directory on Windows systems that can be "
33+
"used to safely simulate the encryption behavior of ransomware. If no "
34+
"directory is specified, no files will be encrypted.",
35+
},
36+
},
2237
},
2338
},
2439
},
2540
"other_behaviors": {
26-
"title": "Other Behaviors",
41+
"title": "Other behavior",
2742
"type": "object",
2843
"properties": {
2944
"readme": {

monkey/tests/unit_tests/infection_monkey/ransomware/test_ransomware_payload.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ def with_extension(filename):
3232
@pytest.fixture
3333
def ransomware_payload_config(ransomware_target):
3434
return {
35-
"directories": {"linux_dir": str(ransomware_target), "windows_dir": str(ransomware_target)},
35+
"encryption": {
36+
"enabled": True,
37+
"directories": {
38+
"linux_target_dir": str(ransomware_target),
39+
"windows_target_dir": str(ransomware_target),
40+
},
41+
},
3642
"other_behaviors": {"readme": False},
3743
}
3844

@@ -127,6 +133,18 @@ def test_skip_already_encrypted_file(ransomware_target, ransomware_payload):
127133
)
128134

129135

136+
def test_encryption_skipped_if_configured_false(
137+
ransomware_payload_config, ransomware_target, telemetry_messenger_spy
138+
):
139+
ransomware_payload_config["encryption"]["enabled"] = False
140+
141+
ransomware_payload = RansomwarePayload(ransomware_payload_config, telemetry_messenger_spy)
142+
ransomware_payload.run_payload()
143+
144+
assert hash_file(ransomware_target / ALL_ZEROS_PDF) == ALL_ZEROS_PDF_CLEARTEXT_SHA256
145+
assert hash_file(ransomware_target / TEST_KEYBOARD_TXT) == TEST_KEYBOARD_TXT_CLEARTEXT_SHA256
146+
147+
130148
def test_telemetry_success(ransomware_payload, telemetry_messenger_spy):
131149
ransomware_payload.run_payload()
132150

0 commit comments

Comments
 (0)