From e7443054275123135c0f0a3ac6fe3b786774e442 Mon Sep 17 00:00:00 2001 From: mpgn <5891788+mpgn@users.noreply.github.com> Date: Sun, 5 Jan 2025 02:28:00 +0100 Subject: [PATCH 1/4] switch default conn from smbv1 to smbv3 --- nxc/protocols/smb.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index bb3cba178..5a4942fe1 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -157,6 +157,7 @@ def __init__(self, args, db, host): self.bootkey = None self.output_filename = None self.smbv1 = None + self.smbv3 = None self.is_timeouted = False self.signing = False self.smb_share_name = smb_share_name @@ -295,6 +296,10 @@ def enum_host_info(self): except Exception as e: self.logger.debug(f"Error logging off system: {e}") + # Check smbv1 + if not self.args.no_smbv1: + self.smbv1 = self.create_smbv1_conn(check=True) + # DCOM connection with kerberos needed self.remoteName = self.host if not self.kerberos else f"{self.hostname}.{self.targetDomain}" @@ -538,10 +543,10 @@ def hash_login(self, domain, username, ntlm_hash): self.create_conn_obj() return False - def create_smbv1_conn(self): - self.logger.debug(f"Creating SMBv1 connection to {self.host}") + def create_smbv1_conn(self, check=False): + self.logger.info(f"Creating SMBv1 connection to {self.host}") try: - self.conn = SMBConnection( + conn = SMBConnection( self.remoteName, self.host, None, @@ -549,6 +554,8 @@ def create_smbv1_conn(self): preferredDialect=SMB_DIALECT, timeout=self.args.smb_timeout, ) + if check: + self.conn = conn except OSError as e: if "Connection reset by peer" in str(e): self.logger.info(f"SMBv1 might be disabled on {self.host}") @@ -567,7 +574,7 @@ def create_smbv1_conn(self): return True def create_smbv3_conn(self): - self.logger.debug(f"Creating SMBv3 connection to {self.host}") + self.logger.info(f"Creating SMBv3 connection to {self.host}") try: self.conn = SMBConnection( self.remoteName, @@ -581,27 +588,26 @@ def create_smbv3_conn(self): return False return True - def create_conn_obj(self, no_smbv1=False): + def create_conn_obj(self): """ Tries to create a connection object to the target host. - On first try, it will try to create a SMBv1 connection. + On first try, it will try to create a SMBv3 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 """ - no_smbv1 = self.args.no_smbv1 if self.args.no_smbv1 else no_smbv1 # Initial negotiation - if not no_smbv1 and self.smbv1 is None: - self.smbv1 = self.create_smbv1_conn() - if self.smbv1: + if self.smbv3 is None: + self.smbv3 = self.create_smbv3_conn() + if self.smbv3: return True elif not self.is_timeouted: - return self.create_smbv3_conn() - elif not no_smbv1 and self.smbv1: - return self.create_smbv1_conn() - else: + return self.create_smbv1_conn() + elif self.smbv3: return self.create_smbv3_conn() + else: + return self.create_smbv1_conn() def check_if_admin(self): self.logger.debug(f"Checking if user is admin on {self.host}") From c8160b6fe52a8d603c131654f97924a3e5b4a642 Mon Sep 17 00:00:00 2001 From: mpgn <5891788+mpgn@users.noreply.github.com> Date: Sun, 5 Jan 2025 02:32:37 +0100 Subject: [PATCH 2/4] fix ruff --- nxc/protocols/smb.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 5a4942fe1..4b29341ee 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -596,7 +596,6 @@ def create_conn_obj(self): :param no_smbv1: If True, it will not try to create a SMBv1 connection """ - # Initial negotiation if self.smbv3 is None: self.smbv3 = self.create_smbv3_conn() From 33ecfb19655e6eb1a5350d57a8fea0bdc7d43c3f Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Mon, 6 Jan 2025 08:43:22 -0500 Subject: [PATCH 3/4] Remove old smbv1 check --- nxc/modules/enum_av.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nxc/modules/enum_av.py b/nxc/modules/enum_av.py index 5946bd15e..8a7425569 100644 --- a/nxc/modules/enum_av.py +++ b/nxc/modules/enum_av.py @@ -84,10 +84,7 @@ def detect_running_processes(self, context, connection, results): prod_results = results.setdefault(product["name"], {}) prod_results.setdefault("pipes", []).append(pipe) except Exception as e: - if "STATUS_ACCESS_DENIED" in str(e): - context.log.fail("Error STATUS_ACCESS_DENIED while enumerating pipes, probably due to using SMBv1") - else: - context.log.fail(str(e)) + context.log.fail(str(e)) def dump_results(self, results, context): if not results: From 0236ef78776e110cab2f1ce04fb1882b040ee6c4 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Mon, 6 Jan 2025 08:43:49 -0500 Subject: [PATCH 4/4] Fix logic bug when creating smbv1 connection and add timeout check for smbv3 --- nxc/protocols/smb.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 4b29341ee..924d72db1 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -156,8 +156,8 @@ def __init__(self, args, db, host): self.remote_ops = None self.bootkey = None self.output_filename = None - self.smbv1 = None - self.smbv3 = None + self.smbv1 = None # Check if SMBv1 is supported + self.smbv3 = None # Check if SMBv3 is supported self.is_timeouted = False self.signing = False self.smb_share_name = smb_share_name @@ -554,7 +554,8 @@ def create_smbv1_conn(self, check=False): preferredDialect=SMB_DIALECT, timeout=self.args.smb_timeout, ) - if check: + self.smbv1 = True + if not check: self.conn = conn except OSError as e: if "Connection reset by peer" in str(e): @@ -583,8 +584,13 @@ def create_smbv3_conn(self): self.port, timeout=self.args.smb_timeout, ) + self.smbv3 = True except (Exception, NetBIOSTimeout, OSError) as e: - self.logger.info(f"Error creating SMBv3 connection to {self.host}: {e}") + if "timed out" in str(e): + self.is_timeouted = True + self.logger.debug(f"Timeout creating SMBv3 connection to {self.host}") + else: + self.logger.info(f"Error creating SMBv3 connection to {self.host}: {e}") return False return True