forked from p34709852/monkey
Agent: Attempt login with LM and NT hashes in PowerShellExploiter
This commit is contained in:
parent
a2e6b0bfbd
commit
501fc162b4
|
@ -55,8 +55,8 @@ class PowerShellExploiter(HostExploiter):
|
||||||
credentials = get_credentials(
|
credentials = get_credentials(
|
||||||
self._config.exploit_user_list,
|
self._config.exploit_user_list,
|
||||||
self._config.exploit_password_list,
|
self._config.exploit_password_list,
|
||||||
[],
|
self._config.exploit_lm_hash_list,
|
||||||
[],
|
self._config.exploit_ntlm_hash_list,
|
||||||
is_windows_os(),
|
is_windows_os(),
|
||||||
)
|
)
|
||||||
auth_options = get_auth_options(credentials, is_https)
|
auth_options = get_auth_options(credentials, is_https)
|
||||||
|
@ -117,20 +117,30 @@ class PowerShellExploiter(HostExploiter):
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
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}, Secret Type: {creds.secret_type.name}"
|
||||||
)
|
)
|
||||||
self.report_login_attempt(True, creds.username, creds.secret)
|
self._report_login_attempt(True, creds)
|
||||||
|
|
||||||
return client
|
return client
|
||||||
except Exception as ex: # noqa: F841
|
except Exception as ex: # noqa: F841
|
||||||
logger.debug(
|
logger.debug(
|
||||||
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}, SecretType: {creds.secret_type.name} -- Error: {ex}"
|
||||||
)
|
)
|
||||||
self.report_login_attempt(False, creds.username, creds.secret)
|
self._report_login_attempt(False, creds)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _report_login_attempt(self, result: bool, credentials: Credentials):
|
||||||
|
if credentials.secret_type in [SecretType.PASSWORD, SecretType.CACHED]:
|
||||||
|
self.report_login_attempt(result, credentials.username, password=credentials.secret)
|
||||||
|
elif credentials.secret_type == SecretType.LM_HASH:
|
||||||
|
self.report_login_attempt(result, credentials.username, lm_hash=credentials.secret)
|
||||||
|
elif credentials.secret_type == SecretType.NT_HASH:
|
||||||
|
self.report_login_attempt(result, credentials.username, ntlm_hash=credentials.secret)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown secret type {credentials.secret_type}")
|
||||||
|
|
||||||
def _execute_monkey_agent_on_victim(self) -> bool:
|
def _execute_monkey_agent_on_victim(self) -> bool:
|
||||||
arch = self._client.get_host_architecture()
|
arch = self._client.get_host_architecture()
|
||||||
self.is_32bit = arch == WIN_ARCH_32
|
self.is_32bit = arch == WIN_ARCH_32
|
||||||
|
|
|
@ -11,6 +11,8 @@ from infection_monkey.model.host import VictimHost
|
||||||
|
|
||||||
USER_LIST = ["user1", "user2"]
|
USER_LIST = ["user1", "user2"]
|
||||||
PASSWORD_LIST = ["pass1", "pass2"]
|
PASSWORD_LIST = ["pass1", "pass2"]
|
||||||
|
LM_HASH_LIST = ["bogo_lm_1"]
|
||||||
|
NT_HASH_LIST = ["bogo_nt_1", "bogo_nt_2"]
|
||||||
DROPPER_TARGET_PATH_32 = "C:\\agent32"
|
DROPPER_TARGET_PATH_32 = "C:\\agent32"
|
||||||
DROPPER_TARGET_PATH_64 = "C:\\agent64"
|
DROPPER_TARGET_PATH_64 = "C:\\agent64"
|
||||||
|
|
||||||
|
@ -19,6 +21,8 @@ Config = namedtuple(
|
||||||
[
|
[
|
||||||
"exploit_user_list",
|
"exploit_user_list",
|
||||||
"exploit_password_list",
|
"exploit_password_list",
|
||||||
|
"exploit_lm_hash_list",
|
||||||
|
"exploit_ntlm_hash_list",
|
||||||
"dropper_target_path_win_32",
|
"dropper_target_path_win_32",
|
||||||
"dropper_target_path_win_64",
|
"dropper_target_path_win_64",
|
||||||
],
|
],
|
||||||
|
@ -33,9 +37,17 @@ class TestAuthenticationError(Exception):
|
||||||
def powershell_exploiter(monkeypatch):
|
def powershell_exploiter(monkeypatch):
|
||||||
host = VictimHost("127.0.0.1")
|
host = VictimHost("127.0.0.1")
|
||||||
pe = powershell.PowerShellExploiter(host)
|
pe = powershell.PowerShellExploiter(host)
|
||||||
pe._config = Config(USER_LIST, PASSWORD_LIST, DROPPER_TARGET_PATH_32, DROPPER_TARGET_PATH_64)
|
pe._config = Config(
|
||||||
|
USER_LIST,
|
||||||
|
PASSWORD_LIST,
|
||||||
|
LM_HASH_LIST,
|
||||||
|
NT_HASH_LIST,
|
||||||
|
DROPPER_TARGET_PATH_32,
|
||||||
|
DROPPER_TARGET_PATH_64,
|
||||||
|
)
|
||||||
|
|
||||||
monkeypatch.setattr(powershell, "AuthenticationError", TestAuthenticationError)
|
monkeypatch.setattr(powershell, "AuthenticationError", TestAuthenticationError)
|
||||||
|
monkeypatch.setattr(powershell, "is_windows_os", lambda: True)
|
||||||
# It's regrettable to mock out a private method on the PowerShellExploiter instance object, but
|
# It's regrettable to mock out a private method on the PowerShellExploiter instance object, but
|
||||||
# it's necessary to avoid having to deal with the monkeyfs
|
# it's necessary to avoid having to deal with the monkeyfs
|
||||||
monkeypatch.setattr(pe, "_write_virtual_file_to_local_path", lambda: None)
|
monkeypatch.setattr(pe, "_write_virtual_file_to_local_path", lambda: None)
|
||||||
|
@ -141,3 +153,66 @@ def test_failed_monkey_execution(monkeypatch, powershell_exploiter):
|
||||||
|
|
||||||
success = powershell_exploiter.exploit_host()
|
success = powershell_exploiter.exploit_host()
|
||||||
assert not success
|
assert not success
|
||||||
|
|
||||||
|
|
||||||
|
def test_login_attemps_correctly_reported(monkeypatch, powershell_exploiter):
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client.get_host_architecture = lambda: WIN_ARCH_32
|
||||||
|
mock_client.copy_file = MagicMock(return_value=True)
|
||||||
|
mock_client.execute_cmd_as_detached_process = MagicMock(side_effect=Exception)
|
||||||
|
|
||||||
|
def allow_ntlm(_, credentials: Credentials, auth_options: AuthOptions):
|
||||||
|
if credentials.username == USER_LIST[1] and credentials.secret == NT_HASH_LIST[1]:
|
||||||
|
return mock_client
|
||||||
|
|
||||||
|
raise TestAuthenticationError
|
||||||
|
|
||||||
|
mock_powershell_client = MagicMock(side_effect=allow_ntlm)
|
||||||
|
monkeypatch.setattr(powershell, "PowerShellClient", mock_powershell_client)
|
||||||
|
|
||||||
|
powershell_exploiter.exploit_host()
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"result": False,
|
||||||
|
"user": USER_LIST[1],
|
||||||
|
"password": None,
|
||||||
|
"lm_hash": "",
|
||||||
|
"ntlm_hash": "",
|
||||||
|
"ssh_key": "",
|
||||||
|
} in powershell_exploiter.exploit_attempts
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"result": False,
|
||||||
|
"user": USER_LIST[1],
|
||||||
|
"password": PASSWORD_LIST[0],
|
||||||
|
"lm_hash": "",
|
||||||
|
"ntlm_hash": "",
|
||||||
|
"ssh_key": "",
|
||||||
|
} in powershell_exploiter.exploit_attempts
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"result": False,
|
||||||
|
"user": USER_LIST[0],
|
||||||
|
"password": "",
|
||||||
|
"lm_hash": LM_HASH_LIST[0],
|
||||||
|
"ntlm_hash": "",
|
||||||
|
"ssh_key": "",
|
||||||
|
} in powershell_exploiter.exploit_attempts
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"result": False,
|
||||||
|
"user": USER_LIST[1],
|
||||||
|
"password": "",
|
||||||
|
"lm_hash": "",
|
||||||
|
"ntlm_hash": NT_HASH_LIST[0],
|
||||||
|
"ssh_key": "",
|
||||||
|
} in powershell_exploiter.exploit_attempts
|
||||||
|
|
||||||
|
assert {
|
||||||
|
"result": True,
|
||||||
|
"user": USER_LIST[1],
|
||||||
|
"password": "",
|
||||||
|
"lm_hash": "",
|
||||||
|
"ntlm_hash": NT_HASH_LIST[1],
|
||||||
|
"ssh_key": "",
|
||||||
|
} in powershell_exploiter.exploit_attempts
|
||||||
|
|
Loading…
Reference in New Issue