forked from p15670423/monkey
Agent: Add LM and NT hashes to PowerShell Credentials
Adds two list parameters to get_credentials() that contain LM and NT hashes respectively. Adds a "secret_type" field to Credentials so that the user of the Credentials object can distinguish between using cached credentials (on windows), passwords, and NT or LM hashes.
This commit is contained in:
parent
3a6f725cc4
commit
a2e6b0bfbd
|
@ -13,7 +13,11 @@ from infection_monkey.exploit.powershell_utils.auth_options import (
|
|||
AuthOptions,
|
||||
get_auth_options,
|
||||
)
|
||||
from infection_monkey.exploit.powershell_utils.credentials import Credentials, get_credentials
|
||||
from infection_monkey.exploit.powershell_utils.credentials import (
|
||||
Credentials,
|
||||
SecretType,
|
||||
get_credentials,
|
||||
)
|
||||
from infection_monkey.exploit.powershell_utils.powershell_client import (
|
||||
AuthenticationError,
|
||||
IPowerShellClient,
|
||||
|
@ -49,7 +53,11 @@ class PowerShellExploiter(HostExploiter):
|
|||
return False
|
||||
|
||||
credentials = get_credentials(
|
||||
self._config.exploit_user_list, self._config.exploit_password_list, is_windows_os()
|
||||
self._config.exploit_user_list,
|
||||
self._config.exploit_password_list,
|
||||
[],
|
||||
[],
|
||||
is_windows_os(),
|
||||
)
|
||||
auth_options = get_auth_options(credentials, is_https)
|
||||
|
||||
|
@ -89,6 +97,7 @@ class PowerShellExploiter(HostExploiter):
|
|||
credentials = Credentials(
|
||||
username="dummy_username",
|
||||
secret="dummy_password",
|
||||
secret_type=SecretType.PASSWORD,
|
||||
)
|
||||
|
||||
auth_options = AuthOptions(
|
||||
|
|
|
@ -1,21 +1,36 @@
|
|||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from itertools import product
|
||||
from typing import List, Union
|
||||
|
||||
|
||||
class SecretType(Enum):
|
||||
CACHED = 1
|
||||
PASSWORD = 2
|
||||
LM_HASH = 3
|
||||
NT_HASH = 4
|
||||
|
||||
|
||||
@dataclass
|
||||
class Credentials:
|
||||
username: Union[str, None]
|
||||
secret: Union[str, None]
|
||||
secret_type: SecretType
|
||||
|
||||
|
||||
def get_credentials(
|
||||
usernames: List[str], passwords: List[str], is_windows: bool
|
||||
usernames: List[str],
|
||||
passwords: List[str],
|
||||
lm_hashes: List[str],
|
||||
nt_hashes: List[str],
|
||||
is_windows: bool,
|
||||
) -> List[Credentials]:
|
||||
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))
|
||||
credentials.extend(_get_username_lm_hash_credentials(usernames, lm_hashes))
|
||||
credentials.extend(_get_username_nt_hash_credentials(usernames, nt_hashes))
|
||||
|
||||
return credentials
|
||||
|
||||
|
@ -24,7 +39,7 @@ def get_credentials(
|
|||
# will be used to attempt to log into the victim.
|
||||
def _get_empty_credentials(is_windows: bool) -> List[Credentials]:
|
||||
if is_windows:
|
||||
return [Credentials(username=None, secret=None)]
|
||||
return [Credentials(username=None, secret=None, secret_type=SecretType.CACHED)]
|
||||
|
||||
return []
|
||||
|
||||
|
@ -32,10 +47,18 @@ 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
|
||||
# log into the victim.
|
||||
def _get_username_only_credentials(usernames: List[str], is_windows: bool) -> List[Credentials]:
|
||||
credentials = [Credentials(username=username, secret="") for username in usernames]
|
||||
credentials = [
|
||||
Credentials(username=username, secret="", secret_type=SecretType.PASSWORD)
|
||||
for username in usernames
|
||||
]
|
||||
|
||||
if is_windows:
|
||||
credentials.extend([Credentials(username=username, secret=None) for username in usernames])
|
||||
credentials.extend(
|
||||
[
|
||||
Credentials(username=username, secret=None, secret_type=SecretType.CACHED)
|
||||
for username in usernames
|
||||
]
|
||||
)
|
||||
|
||||
return credentials
|
||||
|
||||
|
@ -43,6 +66,27 @@ def _get_username_only_credentials(usernames: List[str], is_windows: bool) -> Li
|
|||
def _get_username_password_credentials(
|
||||
usernames: List[str], passwords: List[str]
|
||||
) -> List[Credentials]:
|
||||
username_password_pairs = product(usernames, passwords)
|
||||
return _get_username_secret_credentials(usernames, passwords, SecretType.PASSWORD)
|
||||
|
||||
return [Credentials(credentials[0], credentials[1]) for credentials in username_password_pairs]
|
||||
|
||||
def _get_username_lm_hash_credentials(
|
||||
usernames: List[str], lm_hashes: List[str]
|
||||
) -> List[Credentials]:
|
||||
return _get_username_secret_credentials(usernames, lm_hashes, SecretType.LM_HASH)
|
||||
|
||||
|
||||
def _get_username_nt_hash_credentials(
|
||||
usernames: List[str], nt_hashes: List[str]
|
||||
) -> List[Credentials]:
|
||||
return _get_username_secret_credentials(usernames, nt_hashes, SecretType.NT_HASH)
|
||||
|
||||
|
||||
def _get_username_secret_credentials(
|
||||
usernames: List[str], secrets: List[str], secret_type: SecretType
|
||||
) -> List[Credentials]:
|
||||
username_secret_pairs = product(usernames, secrets)
|
||||
|
||||
return [
|
||||
Credentials(credentials[0], credentials[1], secret_type)
|
||||
for credentials in username_secret_pairs
|
||||
]
|
||||
|
|
|
@ -6,12 +6,12 @@ from infection_monkey.exploit.powershell_utils.auth_options import (
|
|||
ENCRYPTION_NEVER,
|
||||
get_auth_options,
|
||||
)
|
||||
from infection_monkey.exploit.powershell_utils.credentials import Credentials
|
||||
from infection_monkey.exploit.powershell_utils.credentials import Credentials, SecretType
|
||||
|
||||
CREDENTIALS = [
|
||||
Credentials("user1", "password1"),
|
||||
Credentials("user2", ""),
|
||||
Credentials("user3", None),
|
||||
Credentials("user1", "password1", SecretType.PASSWORD),
|
||||
Credentials("user2", "", SecretType.PASSWORD),
|
||||
Credentials("user3", None, SecretType.CACHED),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,44 +1,97 @@
|
|||
from infection_monkey.exploit.powershell_utils.credentials import Credentials, get_credentials
|
||||
from infection_monkey.exploit.powershell_utils.credentials import (
|
||||
Credentials,
|
||||
SecretType,
|
||||
get_credentials,
|
||||
)
|
||||
|
||||
TEST_USERNAMES = ["user1", "user2"]
|
||||
TEST_PASSWORDS = ["p1", "p2"]
|
||||
TEST_LM_HASHES = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"]
|
||||
TEST_NT_HASHES = ["cccccccccccccccccccccccccccccccc", "dddddddddddddddddddddddddddddddd"]
|
||||
|
||||
|
||||
def test_get_credentials__empty_windows_true():
|
||||
credentials = get_credentials([], [], True)
|
||||
credentials = get_credentials([], [], [], [], True)
|
||||
|
||||
assert len(credentials) == 1
|
||||
assert credentials[0] == Credentials(username=None, secret=None)
|
||||
assert credentials[0] == Credentials(username=None, secret=None, secret_type=SecretType.CACHED)
|
||||
|
||||
|
||||
def test_get_credentials__empty_windows_false():
|
||||
credentials = get_credentials([], [], False)
|
||||
credentials = get_credentials([], [], [], [], False)
|
||||
|
||||
assert len(credentials) == 0
|
||||
|
||||
|
||||
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 Credentials(username=TEST_USERNAMES[0], secret="") in credentials
|
||||
assert Credentials(username=TEST_USERNAMES[1], secret="") in credentials
|
||||
assert Credentials(username=TEST_USERNAMES[0], secret=None) in credentials
|
||||
assert Credentials(username=TEST_USERNAMES[1], secret=None) in credentials
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[0], secret="", secret_type=SecretType.PASSWORD)
|
||||
in credentials
|
||||
)
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[1], secret="", secret_type=SecretType.PASSWORD)
|
||||
in credentials
|
||||
)
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[0], secret=None, secret_type=SecretType.CACHED)
|
||||
in credentials
|
||||
)
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[1], secret=None, secret_type=SecretType.CACHED)
|
||||
in credentials
|
||||
)
|
||||
|
||||
|
||||
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 Credentials(username=TEST_USERNAMES[0], secret="") in credentials
|
||||
assert Credentials(username=TEST_USERNAMES[1], secret="") in credentials
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[0], secret="", secret_type=SecretType.PASSWORD)
|
||||
in credentials
|
||||
)
|
||||
assert (
|
||||
Credentials(username=TEST_USERNAMES[1], secret="", secret_type=SecretType.PASSWORD)
|
||||
in credentials
|
||||
)
|
||||
|
||||
|
||||
def test_get_credentials__username_password_windows_true():
|
||||
credentials = get_credentials(TEST_USERNAMES, TEST_PASSWORDS, True)
|
||||
credentials = get_credentials(TEST_USERNAMES, TEST_PASSWORDS, [], [], True)
|
||||
|
||||
assert len(credentials) == 9
|
||||
for user in TEST_USERNAMES:
|
||||
for password in TEST_PASSWORDS:
|
||||
assert Credentials(username=user, secret=password) in credentials
|
||||
assert (
|
||||
Credentials(username=user, secret=password, secret_type=SecretType.PASSWORD)
|
||||
in credentials
|
||||
)
|
||||
|
||||
|
||||
def test_get_credentials__username_lm_hash_windows_false():
|
||||
credentials = get_credentials(TEST_USERNAMES, TEST_PASSWORDS, TEST_LM_HASHES, [], False)
|
||||
|
||||
assert len(credentials) == 10
|
||||
for user in TEST_USERNAMES:
|
||||
for lm_hash in TEST_LM_HASHES:
|
||||
assert (
|
||||
Credentials(username=user, secret=lm_hash, secret_type=SecretType.LM_HASH)
|
||||
in credentials
|
||||
)
|
||||
|
||||
|
||||
def test_get_credentials__username_nt_hash_windows_false():
|
||||
credentials = get_credentials(
|
||||
TEST_USERNAMES, TEST_PASSWORDS, TEST_LM_HASHES, TEST_NT_HASHES, False
|
||||
)
|
||||
|
||||
assert len(credentials) == 14
|
||||
for user in TEST_USERNAMES:
|
||||
for nt_hash in TEST_NT_HASHES:
|
||||
assert (
|
||||
Credentials(username=user, secret=nt_hash, secret_type=SecretType.NT_HASH)
|
||||
in credentials
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue