diff --git a/monkey/infection_monkey/ransomware/ransomware_payload.py b/monkey/infection_monkey/ransomware/ransomware_payload.py index d6a36ab5b..d2c8f578d 100644 --- a/monkey/infection_monkey/ransomware/ransomware_payload.py +++ b/monkey/infection_monkey/ransomware/ransomware_payload.py @@ -6,6 +6,8 @@ from infection_monkey.utils.dir_utils import ( file_extension_filter, filter_files, get_all_regular_files_in_directory, + is_not_shortcut_filter, + is_not_symlink_filter, ) from infection_monkey.utils.environment import is_windows_os @@ -24,7 +26,11 @@ class RansomewarePayload: self._encrypt_files(file_list) def _find_files(self): - file_filters = [file_extension_filter(VALID_FILE_EXTENSIONS_FOR_ENCRYPTION)] + file_filters = [ + file_extension_filter(VALID_FILE_EXTENSIONS_FOR_ENCRYPTION), + is_not_shortcut_filter, + is_not_symlink_filter, + ] all_files = get_all_regular_files_in_directory(self.target_dir) return filter_files(all_files, file_filters) diff --git a/monkey/infection_monkey/utils/dir_utils.py b/monkey/infection_monkey/utils/dir_utils.py index 3cc839d0e..704556335 100644 --- a/monkey/infection_monkey/utils/dir_utils.py +++ b/monkey/infection_monkey/utils/dir_utils.py @@ -19,3 +19,11 @@ def file_extension_filter(file_extensions: Set): return f.suffix in file_extensions return inner_filter + + +def is_not_symlink_filter(f: Path): + return not f.is_symlink() + + +def is_not_shortcut_filter(f: Path): + return f.suffix != ".lnk" diff --git a/monkey/tests/unit_tests/infection_monkey/utils/test_dir_utils.py b/monkey/tests/unit_tests/infection_monkey/utils/test_dir_utils.py index b8ff47a65..8ebddf280 100644 --- a/monkey/tests/unit_tests/infection_monkey/utils/test_dir_utils.py +++ b/monkey/tests/unit_tests/infection_monkey/utils/test_dir_utils.py @@ -1,10 +1,18 @@ +import os + +import pytest +from tests.utils import is_user_admin + from infection_monkey.utils.dir_utils import ( file_extension_filter, filter_files, get_all_regular_files_in_directory, + is_not_shortcut_filter, + is_not_symlink_filter, ) -FILES = ["file.jpg.zip", "file.xyz", "1.tar", "2.tgz", "2.png", "2.mpg"] +SHORTCUT = "shortcut.lnk" +FILES = ["file.jpg.zip", "file.xyz", "1.tar", "2.tgz", "2.png", "2.mpg", SHORTCUT] SUBDIRS = ["subdir1", "subdir2"] @@ -91,3 +99,29 @@ def test_file_extension_filter(tmp_path): filtered_files = filter_files(files_in_dir, [file_extension_filter(valid_extensions)]) assert sorted(files[0:2]) == sorted(filtered_files) + + +@pytest.mark.skipif( + os.name == "nt" and not is_user_admin(), reason="Test requires admin rights on Windows" +) +def test_is_not_symlink_filter(tmp_path): + files = add_files_to_dir(tmp_path) + link_path = tmp_path / "symlink.test" + link_path.symlink_to(files[0], target_is_directory=False) + + files_in_dir = get_all_regular_files_in_directory(tmp_path) + filtered_files = filter_files(files_in_dir, [is_not_symlink_filter]) + + assert link_path in files_in_dir + assert len(filtered_files) == len(FILES) + assert link_path not in filtered_files + + +def test_is_not_shortcut_filter(tmp_path): + add_files_to_dir(tmp_path) + + files_in_dir = get_all_regular_files_in_directory(tmp_path) + filtered_files = filter_files(files_in_dir, [is_not_shortcut_filter]) + + assert len(filtered_files) == len(FILES) - 1 + assert SHORTCUT not in [f.name for f in filtered_files] diff --git a/monkey/tests/utils.py b/monkey/tests/utils.py new file mode 100644 index 000000000..1e55e9bc3 --- /dev/null +++ b/monkey/tests/utils.py @@ -0,0 +1,9 @@ +import ctypes +import os + + +def is_user_admin(): + if os.name == "posix": + return os.getuid() == 0 + + return ctypes.windll.shell32.IsUserAnAdmin()