Agent: Rename Credentials.password to Credentials.secret

The PowerShell Credentials dataclass will hold more than just passwords.
It will also hold NT and LM hashes. "secret" is, therefore, a more
accurate name than "password".
This commit is contained in:
Mike Salvatore 2021-09-02 12:02:30 -04:00
parent 0ecbfdea38
commit 3a6f725cc4
6 changed files with 21 additions and 23 deletions

View File

@ -88,7 +88,7 @@ class PowerShellExploiter(HostExploiter):
def _try_ssl_login(self, use_ssl: bool): def _try_ssl_login(self, use_ssl: bool):
credentials = Credentials( credentials = Credentials(
username="dummy_username", username="dummy_username",
password="dummy_password", secret="dummy_password",
) )
auth_options = AuthOptions( auth_options = AuthOptions(
@ -110,7 +110,7 @@ class PowerShellExploiter(HostExploiter):
f"Successfully logged into {self.host.ip_addr} using Powershell. User: " f"Successfully logged into {self.host.ip_addr} using Powershell. User: "
f"{creds.username}" f"{creds.username}"
) )
self.report_login_attempt(True, creds.username, creds.password) self.report_login_attempt(True, creds.username, creds.secret)
return client return client
except Exception as ex: # noqa: F841 except Exception as ex: # noqa: F841
@ -118,7 +118,7 @@ class PowerShellExploiter(HostExploiter):
f"Error logging into {self.host.ip_addr} using Powershell. User: " f"Error logging into {self.host.ip_addr} using Powershell. User: "
f"{creds.username}, Error: {ex}" f"{creds.username}, Error: {ex}"
) )
self.report_login_attempt(False, creds.username, creds.password) self.report_login_attempt(False, creds.username, creds.secret)
return None return None

View File

@ -21,9 +21,9 @@ def get_auth_options(credentials: List[Credentials], use_ssl: bool) -> List[Auth
for creds in credentials: for creds in credentials:
# Passwordless login only works with SSL false, AUTH_BASIC and ENCRYPTION_NEVER # Passwordless login only works with SSL false, AUTH_BASIC and ENCRYPTION_NEVER
ssl = False if creds.password == "" else use_ssl ssl = False if creds.secret == "" else use_ssl
auth_type = AUTH_BASIC if creds.password == "" else AUTH_NEGOTIATE auth_type = AUTH_BASIC if creds.secret == "" else AUTH_NEGOTIATE
encryption = ENCRYPTION_NEVER if creds.password == "" else ENCRYPTION_AUTO encryption = ENCRYPTION_NEVER if creds.secret == "" else ENCRYPTION_AUTO
auth_options.append(AuthOptions(auth_type, encryption, ssl)) auth_options.append(AuthOptions(auth_type, encryption, ssl))

View File

@ -6,7 +6,7 @@ from typing import List, Union
@dataclass @dataclass
class Credentials: class Credentials:
username: Union[str, None] username: Union[str, None]
password: Union[str, None] secret: Union[str, None]
def get_credentials( def get_credentials(
@ -24,7 +24,7 @@ def get_credentials(
# will be used to attempt to log into the victim. # will be used to attempt to log into the victim.
def _get_empty_credentials(is_windows: bool) -> List[Credentials]: def _get_empty_credentials(is_windows: bool) -> List[Credentials]:
if is_windows: if is_windows:
return [Credentials(username=None, password=None)] return [Credentials(username=None, secret=None)]
return [] return []
@ -32,12 +32,10 @@ def _get_empty_credentials(is_windows: bool) -> List[Credentials]:
# On Windows systems, when password == None, the current user's password will bu used to attempt to # On Windows systems, when password == None, the current user's password will bu used to attempt to
# log into the victim. # log into the victim.
def _get_username_only_credentials(usernames: List[str], is_windows: bool) -> List[Credentials]: def _get_username_only_credentials(usernames: List[str], is_windows: bool) -> List[Credentials]:
credentials = [Credentials(username=username, password="") for username in usernames] credentials = [Credentials(username=username, secret="") for username in usernames]
if is_windows: if is_windows:
credentials.extend( credentials.extend([Credentials(username=username, secret=None) for username in usernames])
[Credentials(username=username, password=None) for username in usernames]
)
return credentials return credentials

View File

@ -53,7 +53,7 @@ class PowerShellClient(IPowerShellClient):
self._client = Client( self._client = Client(
ip_addr, ip_addr,
username=credentials.username, username=credentials.username,
password=credentials.password, password=credentials.secret,
cert_validation=False, cert_validation=False,
auth=auth_options.auth_type, auth=auth_options.auth_type,
encryption=auth_options.encryption, encryption=auth_options.encryption,

View File

@ -8,7 +8,7 @@ def test_get_credentials__empty_windows_true():
credentials = get_credentials([], [], True) credentials = get_credentials([], [], True)
assert len(credentials) == 1 assert len(credentials) == 1
assert credentials[0] == Credentials(username=None, password=None) assert credentials[0] == Credentials(username=None, secret=None)
def test_get_credentials__empty_windows_false(): def test_get_credentials__empty_windows_false():
@ -21,18 +21,18 @@ def test_get_credentials__username_only_windows_true():
credentials = get_credentials(TEST_USERNAMES, [], True) credentials = get_credentials(TEST_USERNAMES, [], True)
assert len(credentials) == 5 assert len(credentials) == 5
assert Credentials(username=TEST_USERNAMES[0], password="") in credentials assert Credentials(username=TEST_USERNAMES[0], secret="") in credentials
assert Credentials(username=TEST_USERNAMES[1], password="") in credentials assert Credentials(username=TEST_USERNAMES[1], secret="") in credentials
assert Credentials(username=TEST_USERNAMES[0], password=None) in credentials assert Credentials(username=TEST_USERNAMES[0], secret=None) in credentials
assert Credentials(username=TEST_USERNAMES[1], password=None) in credentials assert Credentials(username=TEST_USERNAMES[1], secret=None) in credentials
def test_get_credentials__username_only_windows_false(): def test_get_credentials__username_only_windows_false():
credentials = get_credentials(TEST_USERNAMES, [], False) credentials = get_credentials(TEST_USERNAMES, [], False)
assert len(credentials) == 2 assert len(credentials) == 2
assert Credentials(username=TEST_USERNAMES[0], password="") in credentials assert Credentials(username=TEST_USERNAMES[0], secret="") in credentials
assert Credentials(username=TEST_USERNAMES[1], password="") in credentials assert Credentials(username=TEST_USERNAMES[1], secret="") in credentials
def test_get_credentials__username_password_windows_true(): def test_get_credentials__username_password_windows_true():
@ -41,4 +41,4 @@ def test_get_credentials__username_password_windows_true():
assert len(credentials) == 9 assert len(credentials) == 9
for user in TEST_USERNAMES: for user in TEST_USERNAMES:
for password in TEST_PASSWORDS: for password in TEST_PASSWORDS:
assert Credentials(username=user, password=password) in credentials assert Credentials(username=user, secret=password) in credentials

View File

@ -78,7 +78,7 @@ def test_powershell_https(monkeypatch, powershell_exploiter):
powershell_exploiter.exploit_host() powershell_exploiter.exploit_host()
for call_args in mock_powershell_client.call_args_list: for call_args in mock_powershell_client.call_args_list:
if call_args[0][1].password != "" and call_args[0][1].password != "dummy_password": if call_args[0][1].secret != "" and call_args[0][1].secret != "dummy_password":
assert call_args[0][2].ssl assert call_args[0][2].ssl
@ -92,7 +92,7 @@ def test_no_valid_credentials(monkeypatch, powershell_exploiter):
def authenticate(mock_client): def authenticate(mock_client):
def inner(_, credentials: Credentials, auth_options: AuthOptions): def inner(_, credentials: Credentials, auth_options: AuthOptions):
if credentials.username == "user1" and credentials.password == "pass2": if credentials.username == "user1" and credentials.secret == "pass2":
return mock_client return mock_client
else: else:
raise TestAuthenticationError("Invalid credentials") raise TestAuthenticationError("Invalid credentials")