diff --git a/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py b/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py index 7971e7256..e739901f1 100644 --- a/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py +++ b/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py @@ -1,6 +1,6 @@ import abc import logging -from typing import Union +from typing import Optional, Union import pypsrp import spnego @@ -12,7 +12,7 @@ from urllib3 import connectionpool from infection_monkey.exploit.consts import WIN_ARCH_32, WIN_ARCH_64 from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions -from infection_monkey.exploit.powershell_utils.credentials import Credentials +from infection_monkey.exploit.powershell_utils.credentials import Credentials, SecretType from infection_monkey.model import GET_ARCH_WINDOWS logger = logging.getLogger(__name__) @@ -27,6 +27,22 @@ def _set_sensitive_packages_log_level_to_error(): logging.getLogger(package.__name__).setLevel(logging.ERROR) +def format_password(credentials: Credentials) -> Optional[str]: + if credentials.secret_type == SecretType.CACHED: + return None + + if credentials.secret_type == SecretType.PASSWORD: + return credentials.secret + + if credentials.secret_type == SecretType.LM_HASH: + return f"{credentials.secret}:00000000000000000000000000000000" + + if credentials.secret_type == SecretType.NT_HASH: + return f"00000000000000000000000000000000:{credentials.secret}" + + raise ValueError(f"Unknown secret type {credentials.secret_type}") + + class IPowerShellClient(Protocol, metaclass=abc.ABCMeta): @abc.abstractmethod def execute_cmd(self, cmd: str) -> str: @@ -53,7 +69,7 @@ class PowerShellClient(IPowerShellClient): self._client = Client( ip_addr, username=credentials.username, - password=credentials.secret, + password=format_password(credentials), cert_validation=False, auth=auth_options.auth_type, encryption=auth_options.encryption, diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_powershell_client.py b/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_powershell_client.py new file mode 100644 index 000000000..73f7ea64c --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_powershell_client.py @@ -0,0 +1,52 @@ +import pytest + +from infection_monkey.exploit.powershell_utils.credentials import Credentials, SecretType +from infection_monkey.exploit.powershell_utils.powershell_client import format_password + + +def test_format_cached_credentials(): + expected = None + creds = Credentials("test_user", expected, SecretType.CACHED) + + actual = format_password(creds) + + assert expected == actual + + +def test_format_password(): + expected = "test_password" + creds = Credentials("test_user", expected, SecretType.PASSWORD) + + actual = format_password(creds) + + assert expected == actual + + +def test_format_lm_hash(): + lm_hash = "c080132b6f2a0c4e5d1029cc06f48a92" + expected = f"{lm_hash}:00000000000000000000000000000000" + + creds = Credentials("test_user", lm_hash, SecretType.LM_HASH) + + actual = format_password(creds) + + assert expected == actual + + +def test_format_nt_hash(): + nt_hash = "c080132b6f2a0c4e5d1029cc06f48a92" + expected = f"00000000000000000000000000000000:{nt_hash}" + + creds = Credentials("test_user", nt_hash, SecretType.NT_HASH) + + actual = format_password(creds) + + assert expected == actual + + +def test_invalid_secret_type(): + + creds = Credentials("test_user", "secret", "Bogus_Secret") + + with pytest.raises(ValueError): + format_password(creds)