diff --git a/nxc/connection.py b/nxc/connection.py index 729ff4e682..1bb4afe367 100755 --- a/nxc/connection.py +++ b/nxc/connection.py @@ -401,7 +401,11 @@ def parse_credentials(self): username.append(username_single.strip()) owned.append(False) else: - if "\\" in user: + # Check if user looks like a file path but doesn't exist + if ("/" in user or "\\" in user) and not isfile(user): + self.logger.warning(f"File not found: {user} - treating as username") + + if "\\" in user and len(user.split("\\")) == 2: domain_single, username_single = user.split("\\") else: domain_single = self.args.domain if hasattr(self.args, "domain") and self.args.domain is not None else self.domain @@ -423,6 +427,10 @@ def parse_credentials(self): self.logger.error("You can ignore non UTF-8 characters with the option '--ignore-pw-decoding'") sys.exit(1) else: + # Check if password looks like a file path but doesn't exist + if ("/" in password or "\\" in password) and not isfile(password): + self.logger.warning(f"File not found: {password} - treating as password") + secret.append(password) cred_type.append("plaintext") @@ -571,6 +579,13 @@ def login(self): if not (username[0] or secret[0] or domain[0]): return False + # If no secrets provided, add None to allow authentication attempts (useful for user enumeration) + if len(secret) == 0 and len(username) > 0: + self.logger.debug("No secrets provided, adding None to allow authentication attempts") + secret = [None] + cred_type = ["plaintext"] + data = [None] + if not self.args.no_bruteforce: for secr_index, secr in enumerate(secret): for user_index, user in enumerate(username): diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 4d7f17bdea..7bc8b8e62e 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -1,3 +1,4 @@ +# Standard library imports import ntpath import binascii import os @@ -6,6 +7,12 @@ import ipaddress from Cryptodome.Hash import MD4 from textwrap import dedent +from time import time, ctime, sleep +from traceback import format_exc +import contextlib + +# External library imports +from termcolor import colored from impacket.smbconnection import SMBConnection, SessionError from impacket.smb import SMB_DIALECT @@ -29,6 +36,7 @@ from impacket.dcerpc.v5.samr import SID_NAME_USE from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED from impacket.krb5.ccache import CCache + from impacket.krb5.kerberosv5 import SessionKeyDecryptionError, getKerberosTGT from impacket.krb5.types import KerberosException, Principal from impacket.krb5 import constants @@ -38,13 +46,20 @@ from impacket.smb3structs import FILE_SHARE_WRITE, FILE_SHARE_DELETE, SMB2_0_IOCTL_IS_FSCTL from impacket.dcerpc.v5 import tsts as TSTS +from dploot.triage.vaults import VaultsTriage +from dploot.triage.browser import BrowserTriage, LoginData, GoogleRefreshToken, Cookie +from dploot.triage.credentials import CredentialsTriage +from dploot.lib.target import Target +from dploot.triage.sccm import SCCMTriage, SCCMCred, SCCMSecret, SCCMCollection + +# Local library imports from nxc.config import process_secret, host_info_colors, check_guest_account from nxc.connection import connection, sem, requires_admin, dcom_FirewallChecker from nxc.helpers.misc import gen_random_string, validate_ntlm from nxc.logger import NXCAdapter from nxc.protocols.smb.dpapi import collect_masterkeys_from_target, get_domain_backup_key, upgrade_to_dploot_connection from nxc.protocols.smb.firefox import FirefoxCookie, FirefoxData, FirefoxTriage -from nxc.protocols.smb.kerberos import kerberos_login_with_S4U +from nxc.protocols.smb.kerberos import kerberos_login_with_S4U, kerberos_asreq_user_enum from nxc.protocols.smb.wmiexec import WMIEXEC from nxc.protocols.smb.atexec import TSCH_EXEC from nxc.protocols.smb.smbexec import SMBEXEC @@ -60,17 +75,6 @@ from nxc.helpers.misc import detect_if_ip from nxc.protocols.ldap.resolution import LDAPResolution -from dploot.triage.vaults import VaultsTriage -from dploot.triage.browser import BrowserTriage, LoginData, GoogleRefreshToken, Cookie -from dploot.triage.credentials import CredentialsTriage -from dploot.lib.target import Target -from dploot.triage.sccm import SCCMTriage, SCCMCred, SCCMSecret, SCCMCollection - -from time import time, ctime, sleep -from traceback import format_exc -from termcolor import colored -import contextlib - smb_share_name = gen_random_string(5).upper() smb_error_status = [ @@ -330,95 +334,40 @@ def print_host_info(self): return self.host, self.hostname, self.targetDomain - def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False): - self.logger.debug(f"KDC set to: {kdcHost}") - # Re-connect since we logged off - self.create_conn_obj() - lmhash = "" - nthash = "" - - try: - self.password = password - self.username = username - # This checks to see if we didn't provide the LM Hash - if ntlm_hash.find(":") != -1: - lmhash, nthash = ntlm_hash.split(":") - self.hash = nthash - else: - nthash = ntlm_hash - self.hash = ntlm_hash - if lmhash: - self.lmhash = lmhash - if nthash: - self.nthash = nthash + # ============================================================ + # Public Authentication Methods (called by connection.py) + # ============================================================ - if not all(s == "" for s in [self.nthash, password, aesKey]): - kerb_pass = next(s for s in [self.nthash, password, aesKey] if s) - else: - kerb_pass = "" - self.logger.debug(f"Attempting to do Kerberos Login with useCache: {useCache}") - - tgs = None - if self.args.delegate: - kerb_pass = "" - self.username = self.args.delegate - serverName = Principal(f"cifs/{self.hostname}", type=constants.PrincipalNameType.NT_SRV_INST.value) - tgs = kerberos_login_with_S4U(domain, self.hostname, username, password, nthash, lmhash, aesKey, kdcHost, self.args.delegate, serverName, useCache, no_s4u2proxy=self.args.no_s4u2proxy) - self.logger.debug(f"Got TGS for {self.args.delegate} through S4U") - - self.conn.kerberosLogin(self.username, password, domain, lmhash, nthash, aesKey, kdcHost, useCache=useCache, TGS=tgs) - if "Unix" not in self.server_os: - self.check_if_admin() + def kerberos_login(self, domain: str, username: str, password: str | None = None, ntlm_hash: str = "", aesKey: str = "", kdcHost: str = "", useCache: bool = False): + """ + Authenticate using Kerberos. - if username == "": - self.username = self.conn.getCredentials()[0] - elif not self.args.delegate: - self.username = username + If --continue-on-success is set with no password and username list, + performs user enumeration via AS-REQ without incrementing badPwdCount. + Otherwise, performs normal Kerberos authentication. - used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" - if self.args.delegate: - used_ccache = f" through S4U with {username}" + Args: + domain: Target domain + username: Username to authenticate or enumerate + password: Password (None for enumeration mode) + ntlm_hash: NTLM hash for authentication + aesKey: AES key for authentication + kdcHost: KDC host address + useCache: Use Kerberos ticket cache - out = f"{self.domain}\\{self.username}{used_ccache} {self.mark_pwned()}" - self.logger.success(out) + Returns: + bool: True if authentication/enumeration succeeded + """ + # Check if this is user enumeration mode (no credentials provided) + if password is None and not ntlm_hash and not aesKey and not useCache: + # User enumeration mode: AS-REQ probing without badPwdCount increment + return self._kerberos_user_verification(domain, username, kdcHost) - if not self.args.local_auth and self.username != "" and not self.args.delegate: - add_user_bh(self.username, domain, self.logger, self.config) - if self.admin_privs: - add_user_bh(f"{self.hostname}$", domain, self.logger, self.config) + if password == "": + self.logger.warning("Using blank password will increment badPwdCount") - # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321 - if self.args.continue_on_success and self.signing: - with contextlib.suppress(Exception): - self.conn.logoff() - return True - except SessionKeyDecryptionError: - # success for now, since it's a vulnerability - previously was an error - self.logger.success( - f"{domain}\\{self.username} account vulnerable to asreproast attack", - color="yellow", - ) - return False - except (FileNotFoundError, KerberosException) as e: - self.logger.fail(f"CCache Error: {e}") - return False - except OSError as e: - used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" - if self.args.delegate: - used_ccache = f" through S4U with {username}" - self.logger.fail(f"{domain}\\{self.username}{used_ccache} {e}") - except (SessionError, Exception) as e: - error, desc = e.getErrorString() - used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" - if self.args.delegate: - used_ccache = f" through S4U with {username}" - self.logger.fail( - f"{domain}\\{self.username}{used_ccache} {error} {f'({desc})' if self.args.verbose else ''}", - color="magenta" if error in smb_error_status else "red", - ) - if error not in smb_error_status: - self.inc_failed_login(username) - return False + # Normal Kerberos authentication + return self._kerberos_authenticate(domain, username, password, ntlm_hash, aesKey, kdcHost, useCache) def plaintext_login(self, domain, username, password): # Re-connect since we logged off @@ -474,7 +423,7 @@ def plaintext_login(self, domain, username, password): self.logger.fail("Broken Pipe Error while attempting to login") return False - def hash_login(self, domain, username, ntlm_hash): + def hash_login(self, domain: str, username: str, ntlm_hash: str): # Re-connect since we logged off self.create_conn_obj() lmhash = "" @@ -538,6 +487,176 @@ def hash_login(self, domain, username, ntlm_hash): self.logger.fail("Broken Pipe Error while attempting to login") return False + def _kerberos_authenticate(self, domain: str, username: str, password: str, ntlm_hash: str, aesKey: str, kdcHost: str, useCache: bool): + """ + Perform Kerberos authentication to SMB service. + + This is the internal implementation that handles the actual Kerberos + authentication process including S4U delegation if requested. + + Args: + domain: Target domain + username: Username to authenticate + password: Password for authentication + ntlm_hash: NTLM hash for authentication + aesKey: AES key for authentication + kdcHost: KDC host address + useCache: Use Kerberos ticket cache + + Returns: + bool: True if authentication succeeded, False otherwise + """ + # Re-connect since we logged off + self.create_conn_obj() + lmhash = "" + nthash = "" + + try: + self.password = password + self.username = username + # This checks to see if we didn't provide the LM Hash + if ntlm_hash.find(":") != -1: + lmhash, nthash = ntlm_hash.split(":") + self.hash = nthash + else: + nthash = ntlm_hash + self.hash = ntlm_hash + if lmhash: + self.lmhash = lmhash + if nthash: + self.nthash = nthash + + # Determine which credential is being used for logging + if self.nthash: + kerb_pass = self.nthash + elif password: + kerb_pass = password + elif aesKey: + kerb_pass = aesKey + else: + kerb_pass = "" + self.logger.debug(f"Attempting to do Kerberos Login with useCache: {useCache}") + + tgs = None + if self.args.delegate: + kerb_pass = "" + self.username = self.args.delegate + serverName = Principal(f"cifs/{self.hostname}", type=constants.PrincipalNameType.NT_SRV_INST.value) + tgs = kerberos_login_with_S4U(domain, self.hostname, username, password, nthash, lmhash, aesKey, kdcHost, self.args.delegate, serverName, useCache, no_s4u2proxy=self.args.no_s4u2proxy) + self.logger.debug(f"Got TGS for {self.args.delegate} through S4U") + + self.conn.kerberosLogin(self.username, password, domain, lmhash, nthash, aesKey, kdcHost, useCache=useCache, TGS=tgs) + if "Unix" not in self.server_os: + self.check_if_admin() + + if username == "": + self.username = self.conn.getCredentials()[0] + elif not self.args.delegate: + self.username = username + + used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" + if self.args.delegate: + used_ccache = f" through S4U with {username}" + + out = f"{self.domain}\\{self.username}{used_ccache} {self.mark_pwned()}" + self.logger.success(out) + + if not self.args.local_auth and self.username != "" and not self.args.delegate: + add_user_bh(self.username, domain, self.logger, self.config) + if self.admin_privs: + add_user_bh(f"{self.hostname}$", domain, self.logger, self.config) + + # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321 + if self.args.continue_on_success and self.signing: + with contextlib.suppress(Exception): + self.conn.logoff() + return True + except SessionKeyDecryptionError: + # success for now, since it's a vulnerability - previously was an error + self.logger.success( + f"{domain}\\{self.username} account vulnerable to asreproast attack", + color="yellow", + ) + return False + except (FileNotFoundError, KerberosException) as e: + self.logger.fail(f"CCache Error: {e}") + return False + except OSError as e: + used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" + if self.args.delegate: + used_ccache = f" through S4U with {username}" + self.logger.fail(f"{domain}\\{self.username}{used_ccache} {e}") + except (SessionError, Exception) as e: + error, desc = e.getErrorString() + used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" + if self.args.delegate: + used_ccache = f" through S4U with {username}" + self.logger.fail( + f"{domain}\\{self.username}{used_ccache} {error} {f'({desc})' if self.args.verbose else ''}", + color="magenta" if error in smb_error_status else "red", + ) + if error not in smb_error_status: + self.inc_failed_login(username) + return False + + def _kerberos_user_verification(self, domain: str, username: str, kdcHost: str): + """ + Enumerate if username exists via Kerberos AS-REQ (no badPwdCount increment). + + This is called when --continue-on-success is set with no password. + It uses AS-REQ without preauthentication to probe user existence. + + Args: + domain: Target domain + username: Username to check + kdcHost: KDC host address + + Returns: + bool: True if user exists, False otherwise + """ + kdc_host = kdcHost if kdcHost else self.host + + # Call the pure function from kerberos.py + result = kerberos_asreq_user_enum(domain.upper(), username, kdc_host) + + if result == "invalid": + # User doesn't exist - only show in debug mode during enumeration + self.logger.debug(f"{domain}\\{username} (user does not exist)") + return False + + if result == "wrong_realm": + # Wrong domain + self.logger.fail(f"{domain}\\{username} (wrong realm/domain)") + return False + + if result.startswith("error:"): + # Error occurred + error_msg = result.split(":", 1)[1] + self.logger.warning(f"{domain}\\{username} ({error_msg})") + return False + + # Parse result and log appropriately + if result == "valid": + # User exists and is active + self.logger.success(f"{domain}\\{username}") + elif result == "disabled": + # User exists but disabled + self.logger.success(f"{domain}\\{username} (account disabled)") + else: + # Unknown result + self.logger.debug(f"{domain}\\{username} (unknown result: {result})") + return False + + # Add to database + with contextlib.suppress(Exception): + self.db.add_credential("plaintext", domain, username, "") + + return True + + # ============================================================ + # SMB Connection Management + # ============================================================ + def create_smbv1_conn(self, check=False): self.logger.info(f"Creating SMBv1 connection to {self.host}") try: diff --git a/nxc/protocols/smb/kerberos.py b/nxc/protocols/smb/kerberos.py index 87c64b0da6..7d31240a8d 100644 --- a/nxc/protocols/smb/kerberos.py +++ b/nxc/protocols/smb/kerberos.py @@ -1,24 +1,51 @@ +# Standard library imports import datetime import struct import random from six import b +# External library imports from pyasn1.codec.der import decoder, encoder from pyasn1.type.univ import noValue -from impacket.krb5.asn1 import AP_REQ, AS_REP, TGS_REQ, Authenticator, TGS_REP, \ - seq_set, seq_set_iter, PA_FOR_USER_ENC, Ticket as TicketAsn1, EncTGSRepPart, \ - PA_PAC_OPTIONS +from impacket.krb5.asn1 import ( + AP_REQ, + AS_REQ, + AS_REP, + TGS_REQ, + Authenticator, + TGS_REP, + seq_set, + seq_set_iter, + PA_FOR_USER_ENC, + Ticket as TicketAsn1, + EncTGSRepPart, + PA_PAC_OPTIONS, +) from impacket.krb5.types import Principal, KerberosTime, Ticket -from impacket.krb5.kerberosv5 import sendReceive, getKerberosTGT +from impacket.krb5.kerberosv5 import sendReceive, getKerberosTGT, KerberosError from impacket.krb5.ccache import CCache from impacket.krb5.crypto import Key, _enctype_table, _HMACMD5 from impacket.krb5 import constants +# Local library imports from nxc.logger import nxc_logger -def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash, aesKey, kdcHost, impersonate, spn, use_cache, no_s4u2proxy=False): +def kerberos_login_with_S4U( + domain: str, + hostname: str, + username: str, + password: str, + nthash: str, + lmhash: str, + aesKey: str, + kdcHost: str, + impersonate: str, + spn: str, + use_cache: bool, + no_s4u2proxy: bool = False, +): my_tgt = None if use_cache: domain, _, tgt, _ = CCache.parseFile(domain, username, f"cifs/{hostname}") @@ -28,9 +55,13 @@ def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash cipher = tgt["cipher"] session_key = tgt["sessionKey"] if my_tgt is None: - principal = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value) + principal = Principal( + username, type=constants.PrincipalNameType.NT_PRINCIPAL.value + ) nxc_logger.debug("Getting TGT for user") - tgt, cipher, _, session_key = getKerberosTGT(principal, password, domain, lmhash, nthash, aesKey, kdcHost) + tgt, cipher, _, session_key = getKerberosTGT( + principal, password, domain, lmhash, nthash, aesKey, kdcHost + ) my_tgt = decoder.decode(tgt, asn1Spec=AS_REP())[0] decoded_tgt = my_tgt # Extract the ticket from the TGT @@ -64,7 +95,9 @@ def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes # TGS authenticator subkey), encrypted with the TGS session # key (Section 5.5.1) - encrypted_encoded_authenticator = cipher.encrypt(session_key, 7, encoded_authenticator, None) + encrypted_encoded_authenticator = cipher.encrypt( + session_key, 7, encoded_authenticator, None + ) ap_req["authenticator"] = noValue ap_req["authenticator"]["etype"] = cipher.enctype @@ -79,13 +112,17 @@ def kerberos_login_with_S4U(domain, hostname, username, password, nthash, lmhash tgs_req["padata"] = noValue tgs_req["padata"][0] = noValue - tgs_req["padata"][0]["padata-type"] = int(constants.PreAuthenticationDataTypes.PA_TGS_REQ.value) + tgs_req["padata"][0]["padata-type"] = int( + constants.PreAuthenticationDataTypes.PA_TGS_REQ.value + ) tgs_req["padata"][0]["padata-value"] = encoded_ap_req # In the S4U2self KRB_TGS_REQ/KRB_TGS_REP protocol extension, a service # requests a service ticket to itself on behalf of a user. The user is # identified to the KDC by the user's name and realm. - client_name = Principal(impersonate, type=constants.PrincipalNameType.NT_PRINCIPAL.value) + client_name = Principal( + impersonate, type=constants.PrincipalNameType.NT_PRINCIPAL.value + ) s4u_byte_array = struct.pack(" str: + """ + Check if a username exists in Active Directory via Kerberos AS-REQ enumeration. + + This function sends a Kerberos AS-REQ (Authentication Service Request) with + no preauthentication data. The KDC's response reveals whether the user exists + without incrementing badPwdCount since no password is provided. + + KDC Response Codes: + - KDC_ERR_PREAUTH_REQUIRED (25): User exists (preauth required) + - KDC_ERR_C_PRINCIPAL_UNKNOWN (6): User does not exist + - KDC_ERR_CLIENT_REVOKED: User account is disabled + - Other errors: Various account/policy issues + + Args: + domain (str): The target Active Directory domain (e.g., 'CORP.LOCAL') + username (str): Username to check (without domain) + kdcHost (str): IP address or FQDN of the KDC (Domain Controller) + + Returns: + str: Status of the user check + - "valid": User exists and is active + - "disabled": User exists but account is disabled + - "invalid": User does not exist + - "wrong_realm": Wrong domain/realm + - "timeout": Connection timeout + - "error:": Other error occurred + """ + try: + # Build the principal name + client_principal = Principal( + username, type=constants.PrincipalNameType.NT_PRINCIPAL.value + ) + + # Build AS-REQ + as_req = AS_REQ() + + # Set domain + as_req["pvno"] = 5 + as_req["msg-type"] = int(constants.ApplicationTagNumbers.AS_REQ.value) + + # Request body + req_body = seq_set(as_req, "req-body") + + # KDC Options - request forwardable and renewable tickets + opts = [] + opts.append(constants.KDCOptions.forwardable.value) + opts.append(constants.KDCOptions.renewable.value) + opts.append(constants.KDCOptions.renewable_ok.value) + req_body["kdc-options"] = constants.encodeFlags(opts) + + # Set client principal + seq_set(req_body, "cname", client_principal.components_to_asn1) + req_body["realm"] = domain + + # Set server principal (krbtgt) + server_principal = Principal( + f"krbtgt/{domain}", type=constants.PrincipalNameType.NT_PRINCIPAL.value + ) + seq_set(req_body, "sname", server_principal.components_to_asn1) + + now = datetime.datetime.now(datetime.timezone.utc) + + req_body["till"] = KerberosTime.to_asn1(now.replace(year=now.year + 1)) + req_body["rtime"] = KerberosTime.to_asn1(now.replace(year=now.year + 1)) + req_body["nonce"] = random.getrandbits(31) + + # Set encryption types - prefer AES + supported_ciphers = ( + constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value, + constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value, + constants.EncryptionTypes.rc4_hmac.value, + ) + seq_set_iter(req_body, "etype", supported_ciphers) + + # No preauthentication data (this is key for enumeration) + # We deliberately don't include PA-DATA to trigger preauth required response + + # Encode and send the request + message = encoder.encode(as_req) + + try: + sendReceive(message, domain, kdcHost) + except KerberosError as e: + # Analyze the error code to determine user status + error_code = e.getErrorCode() + + if error_code == constants.ErrorCodes.KDC_ERR_PREAUTH_REQUIRED.value: + # User exists! (KDC requires preauthentication) + return "valid" + + elif error_code == constants.ErrorCodes.KDC_ERR_C_PRINCIPAL_UNKNOWN.value: + # User does not exist + return "invalid" + + elif error_code == constants.ErrorCodes.KDC_ERR_CLIENT_REVOKED.value: + # User exists but account is disabled + return "disabled" + + elif error_code == constants.ErrorCodes.KDC_ERR_WRONG_REALM.value: + return "wrong_realm" + + else: + # Other Kerberos error + error_msg = ( + constants.ErrorCodes(error_code).name + if hasattr(constants.ErrorCodes, "_value2member_map_") + else str(error_code) + ) + return f"error:krb_{error_msg}" + + # If we get an AS-REP without error, user exists (very rare without preauth) + return "valid" + + except TimeoutError: + return "error:timeout" + except OSError as e: + return f"error:socket_{e}" + except Exception as e: + return f"error:{e}" diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index 84d5eeece8..a44ed727e4 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -71,7 +71,7 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-comp netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" DELETE=True netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M bitlocker netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dpapi_hash -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dpapi_hash -o OUTPUTFILE=hashes.txt +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dpapi_hash -o OUTPUTFILE=hashes.txt netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc -o CLEANUP=True netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M empire_exec -o LISTENER=http-listener @@ -184,7 +184,7 @@ netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -x whoami ##### WMI Modules netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ioxidresolver netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spooler -netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M zerologon +netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M zerologon netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_dns netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get_netconnections #netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=enable