Skip to content

Commit

Permalink
Increase plaintext and hash login speeds
Browse files Browse the repository at this point in the history
NetExec PR Pennyw0rth#411

Signed-off-by: Mercury0 <[email protected]>
  • Loading branch information
Mercury0 authored Sep 12, 2024
1 parent 0da34ea commit 09b9ae1
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions nxc/protocols/smb.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,17 +283,18 @@ def enum_host_info(self):
self.kdcHost = result["host"] if result else None
self.logger.info(f"Resolved domain: {self.domain} with dns, kdcHost: {self.kdcHost}")

# if we want to authenticate we should create another connection object, because we have already logged in
if self.args.username or self.args.cred_id or self.kerberos:
self.create_conn_obj()

def print_host_info(self):
signing = colored(f"signing:{self.signing}", host_info_colors[0], attrs=["bold"]) if self.signing else colored(f"signing:{self.signing}", host_info_colors[1], attrs=["bold"])
smbv1 = colored(f"SMBv1:{self.smbv1}", host_info_colors[2], attrs=["bold"]) if self.smbv1 else colored(f"SMBv1:{self.smbv1}", host_info_colors[3], attrs=["bold"])
self.logger.display(f"{self.server_os}{f' x{self.os_arch}' if self.os_arch else ''} (name:{self.hostname}) (domain:{self.targetDomain}) ({signing}) ({smbv1})")
return True

def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False):
logging.getLogger("impacket").disabled = True
# Re-connect since we logged off
self.logger.debug(f"KDC set to: {kdcHost}")
self.create_conn_obj()
lmhash = ""
nthash = ""

Expand Down Expand Up @@ -351,9 +352,7 @@ def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="",
if self.args.continue_on_success and self.signing:
with contextlib.suppress(Exception):
self.conn.logoff()

self.create_conn_obj()

return True
except SessionKeyDecryptionError:
# success for now, since it's a vulnerability - previously was an error
Expand Down Expand Up @@ -386,7 +385,6 @@ def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="",

def plaintext_login(self, domain, username, password):
# Re-connect since we logged off
self.create_conn_obj()
try:
self.password = password
self.username = username
Expand Down Expand Up @@ -439,14 +437,15 @@ def plaintext_login(self, domain, username, password):
return False
except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e:
self.logger.fail(f"Connection Error: {e}")
self.create_conn_obj()
return False
except BrokenPipeError:
self.logger.fail("Broken Pipe Error while attempting to login")
self.create_conn_obj()
return False

def hash_login(self, domain, username, ntlm_hash):
# Re-connect since we logged off
self.create_conn_obj()
lmhash = ""
nthash = ""
try:
Expand Down Expand Up @@ -502,12 +501,15 @@ def hash_login(self, domain, username, ntlm_hash):
return False
except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e:
self.logger.fail(f"Connection Error: {e}")
self.create_conn_obj()
return False
except BrokenPipeError:
self.logger.fail("Broken Pipe Error while attempting to login")
self.create_conn_obj()
return False

def create_smbv1_conn(self):
self.logger.debug(f"Creating SMBv1 connection to {self.host}")
try:
self.conn = SMBConnection(
self.remoteName,
Expand All @@ -525,10 +527,10 @@ def create_smbv1_conn(self):
except (Exception, NetBIOSTimeout) as e:
self.logger.info(f"Error creating SMBv1 connection to {self.host}: {e}")
return False

return True

def create_smbv3_conn(self):
self.logger.debug(f"Creating SMBv3 connection to {self.host}")
try:
self.conn = SMBConnection(
self.remoteName,
Expand All @@ -551,9 +553,25 @@ def create_smbv3_conn(self):
return False
return True

def create_conn_obj(self):
return bool(self.create_smbv1_conn() or self.create_smbv3_conn())

def create_conn_obj(self, no_smbv1=False):
"""
Tries to create a connection object to the target host.
On first try, it will try to create a SMBv1 connection.
On further tries, it will remember which SMB version is supported and create a connection object accordingly.
:param no_smbv1: If True, it will not try to create a SMBv1 connection
"""
# Initial negotiation
if not no_smbv1 and self.smbv1 is None:
self.smbv1 = self.create_smbv1_conn()
if self.smbv1:
return True
else:
return self.create_smbv3_conn()
elif not no_smbv1 and self.smbv1:
return self.create_smbv1_conn()
else:
return self.create_smbv3_conn()

def check_if_admin(self):
self.logger.debug(f"Checking if user is admin on {self.host}")
try:
Expand Down

0 comments on commit 09b9ae1

Please sign in to comment.