From dc1a2ab1c1db7f542469ba30029f563f75299366 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 9 Mar 2022 12:12:01 +0200 Subject: [PATCH] Agent: move brute-force input generation from wmiexec to brute_force --- monkey/infection_monkey/exploit/smbexec.py | 2 +- monkey/infection_monkey/exploit/wmiexec.py | 43 +++----------------- monkey/infection_monkey/utils/brute_force.py | 15 ++++++- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index e3e2f0d52..35c45c773 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -52,7 +52,7 @@ class SmbExploiter(HostExploiter): logger.info("Can't find suitable monkey executable for host %r", self.host) return False - # TODO extract the method in wmiexec.py + # TODO use infectionmonkey.utils.brute_force creds = self._config.get_exploit_user_password_or_hash_product() exploited = False diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index ee92d29ed..43d3058b6 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -2,8 +2,6 @@ import logging import ntpath import socket import traceback -from itertools import product -from typing import List, Mapping from impacket.dcerpc.v5.rpcrt import DCERPCException @@ -14,6 +12,10 @@ from infection_monkey.exploit.tools.smb_tools import SmbTools from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException, WmiTools from infection_monkey.i_puppet import ExploiterResultData from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS +from infection_monkey.utils.brute_force import ( + generate_username_password_or_ntlm_hash_combinations, + get_credential_string, +) from infection_monkey.utils.commands import build_monkey_commandline logger = logging.getLogger(__name__) @@ -27,10 +29,10 @@ class WmiExploiter(HostExploiter): @WmiTools.dcom_wrap def _exploit_host(self) -> ExploiterResultData: - creds = _get_exploit_user_password_or_hash_product(self.options["credentials"]) + creds = generate_username_password_or_ntlm_hash_combinations(self.options["credentials"]) for user, password, lm_hash, ntlm_hash in creds: - creds_for_log = _get_credential_string([user, password, lm_hash, ntlm_hash]) + creds_for_log = get_credential_string([user, password, lm_hash, ntlm_hash]) logger.debug(f"Attempting to connect to {self.host} using WMI with {creds_for_log}") wmi_connection = WmiTools.WmiConnection() @@ -136,36 +138,3 @@ class WmiExploiter(HostExploiter): return self.exploit_result return self.exploit_result - - -def _get_exploit_user_password_or_hash_product(credentials: Mapping) -> List: - """ - Returns all combinations of the configurations users and passwords or lm/ntlm hashes - :return: - """ - cred_list = [] - for cred in product( - credentials["exploit_user_list"], credentials["exploit_password_list"], [""], [""] - ): - cred_list.append(cred) - for cred in product( - credentials["exploit_user_list"], [""], [""], credentials["exploit_ntlm_hash_list"] - ): - cred_list.append(cred) - for cred in product( - credentials["exploit_user_list"], [""], credentials["exploit_lm_hash_list"], [""] - ): - cred_list.append(cred) - return cred_list - - -def _get_credential_string(creds: List) -> str: - cred_strs = [ - (creds[0], "username"), - (creds[1], "password"), - (creds[2], "lm hash"), - (creds[3], "nt hash"), - ] - - present_creds = [cred[1] for cred in cred_strs if cred[0]] - return ", ".join(present_creds) diff --git a/monkey/infection_monkey/utils/brute_force.py b/monkey/infection_monkey/utils/brute_force.py index 192905aa8..ce5a895c1 100644 --- a/monkey/infection_monkey/utils/brute_force.py +++ b/monkey/infection_monkey/utils/brute_force.py @@ -1,5 +1,5 @@ from itertools import chain, product -from typing import Any, Iterable, Tuple +from typing import Any, Iterable, List, Tuple def generate_identity_secret_pairs( @@ -38,3 +38,16 @@ def generate_username_password_or_ntlm_hash_combinations( product(usernames, [""], lm_hashes, [""]), product(usernames, [""], [""], nt_hashes), ) + + +# Expects a list of username, password, lm hash and nt hash in that order +def get_credential_string(creds: List) -> str: + cred_strs = [ + (creds[0], "username"), + (creds[1], "password"), + (creds[2], "lm hash"), + (creds[3], "nt hash"), + ] + + present_creds = [cred[1] for cred in cred_strs if cred[0]] + return ", ".join(present_creds)