forked from p15670423/monkey
Agent: Format NT/LM hashes for use with pypsrp in PowerShellClient
This commit is contained in:
parent
9cc488d36a
commit
1a1a130716
|
@ -1,6 +1,6 @@
|
||||||
import abc
|
import abc
|
||||||
import logging
|
import logging
|
||||||
from typing import Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
import pypsrp
|
import pypsrp
|
||||||
import spnego
|
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.consts import WIN_ARCH_32, WIN_ARCH_64
|
||||||
from infection_monkey.exploit.powershell_utils.auth_options import AuthOptions
|
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
|
from infection_monkey.model import GET_ARCH_WINDOWS
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -27,6 +27,22 @@ def _set_sensitive_packages_log_level_to_error():
|
||||||
logging.getLogger(package.__name__).setLevel(logging.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):
|
class IPowerShellClient(Protocol, metaclass=abc.ABCMeta):
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def execute_cmd(self, cmd: str) -> str:
|
def execute_cmd(self, cmd: str) -> str:
|
||||||
|
@ -53,7 +69,7 @@ class PowerShellClient(IPowerShellClient):
|
||||||
self._client = Client(
|
self._client = Client(
|
||||||
ip_addr,
|
ip_addr,
|
||||||
username=credentials.username,
|
username=credentials.username,
|
||||||
password=credentials.secret,
|
password=format_password(credentials),
|
||||||
cert_validation=False,
|
cert_validation=False,
|
||||||
auth=auth_options.auth_type,
|
auth=auth_options.auth_type,
|
||||||
encryption=auth_options.encryption,
|
encryption=auth_options.encryption,
|
||||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue