From df356ca087f4d99c9d27ce7f2c5644999ce28f6f Mon Sep 17 00:00:00 2001 From: zblurx Date: Tue, 20 Oct 2026 10:17:16 +0200 Subject: [PATCH 1/6] fix for #1490 --- nxc/protocols/wmi.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index 02ecb5b9..52c51027 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -194,16 +194,17 @@ class wmi(connection): self.logger.fail(error_msg) if not flag else self.logger.debug(error_msg) else: + self.logger.extra["protocol"] = "WMI" try: self.iWbemLevel1Login = IWbemLevel1Login(iInterface) - self.get_namespace("//./root/cimv2") + if self.get_namespace("//./root/cimv2") is None: + self.admin_privs = False + else: + self.admin_privs = True except Exception as e: if "access_denied" not in str(e).lower(): self.logger.fail(str(e)) return False - else: - self.logger.extra["protocol"] = "WMI" - self.admin_privs = True def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False): self.logger.debug("Starting WMI login with Kerberos") From d1464494a880873db973a433a0c12d016939965e Mon Sep 17 00:00:00 2001 From: zblurx Date: Tue, 20 Oct 2026 13:34:55 +0200 Subject: [PATCH 2/6] new fix for #1490 --- nxc/protocols/wmi.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index 02ecb5b9..87937e4d 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -194,16 +194,17 @@ class wmi(connection): self.logger.fail(error_msg) if not flag else self.logger.debug(error_msg) else: + self.logger.extra["protocol"] = "WMI" try: self.iWbemLevel1Login = IWbemLevel1Login(iInterface) - self.get_namespace("//./root/cimv2") + if self.get_namespace("//./root/cimv2") is None: + self.admin_privs = False + else: + self.admin_privs = True except Exception as e: if "access_denied" not in str(e).lower(): self.logger.fail(str(e)) return False - else: - self.logger.extra["protocol"] = "WMI" - self.admin_privs = True def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False): self.logger.debug("Starting WMI login with Kerberos") @@ -392,8 +393,10 @@ class wmi(connection): escaped_path = remote_path.replace("\\", "\\\\") # Load the Namespace - powershellv3_namespace = self.get_namespace("//./root/Microsoft/Windows/Powershellv3") - if powershellv3_namespace is None: + try: + powershellv3_namespace = self.get_namespace("//./root/Microsoft/Windows/Powershellv3") + except Exception as e: + self.logger.debug(f"Cannot load WMI Namespace //./root/Microsoft/Windows/Powershellv3: {e}") return None # Read the file @@ -791,13 +794,8 @@ class wmi(connection): if namespace in self.namespaces: return self.namespaces[namespace] self.logger.debug(f"Getting namespace {namespace}") - try: - iWbemServices = self.iWbemLevel1Login.NTLMLogin(namespace, NULL, NULL) - self.iWbemLevel1Login.RemRelease() - except Exception as e: - self.logger.debug(f"Cannot load WMI Namespace {namespace}: {e}") - return None - self.namespaces[namespace] = iWbemServices + self.namespaces[namespace] = self.iWbemLevel1Login.NTLMLogin(namespace, NULL, NULL) + self.iWbemLevel1Login.RemRelease() return self.namespaces[namespace] @property From e6a4d9f2f008f3aa334572c9cbdf8e700f436c90 Mon Sep 17 00:00:00 2001 From: zblurx Date: Tue, 20 Oct 2026 13:40:18 +0200 Subject: [PATCH 3/6] fix wmi bruteforce bug --- nxc/protocols/wmi.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index 87937e4d..74e4493f 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -177,9 +177,17 @@ class wmi(connection): self.logger.display(f"{self.server_os} (name:{self.hostname}) (domain:{self.targetDomain})") def check_if_admin(self): + # With several credentials, drop the admin flag, namespaces and DCOM connections (cached per target by impacket) of the previous one + self.admin_privs = False + self.namespaces = {} + if self.dcom_conn: + self.dcom_conn.disconnect() + self.dcom_conn = None try: - self.dcom_conn = DCOMConnection(self.remoteName, self.username, self.password, self.domain, self.lmhash, self.nthash, oxidResolver=True, doKerberos=self.doKerberos, kdcHost=self.kdcHost, aesKey=self.aesKey, remoteHost=self.host) - iInterface = self.dcom_conn.CoCreateInstanceEx(CLSID_WbemLevel1Login, IID_IWbemLevel1Login) + # Only keep the connection once activated: impacket's disconnect() can't run twice on a target + dcom_conn = DCOMConnection(self.remoteName, self.username, self.password, self.domain, self.lmhash, self.nthash, oxidResolver=True, doKerberos=self.doKerberos, kdcHost=self.kdcHost, aesKey=self.aesKey, remoteHost=self.host) + iInterface = dcom_conn.CoCreateInstanceEx(CLSID_WbemLevel1Login, IID_IWbemLevel1Login) + self.dcom_conn = dcom_conn flag, self.stringBinding = dcom_FirewallChecker(iInterface, self.host, self.args.rpc_timeout, self.logger) except Exception as e: self.logger.debug(f"Received error while checking admin: {e}") From 949ffa54390f7c268b2845658e1ec8292d4d19d2 Mon Sep 17 00:00:00 2001 From: zblurx Date: Tue, 20 Oct 2026 13:42:05 +0200 Subject: [PATCH 4/6] revert first fix --- nxc/protocols/wmi.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index 74e4493f..a30b1a86 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -205,14 +205,15 @@ class wmi(connection): self.logger.extra["protocol"] = "WMI" try: self.iWbemLevel1Login = IWbemLevel1Login(iInterface) - if self.get_namespace("//./root/cimv2") is None: - self.admin_privs = False - else: - self.admin_privs = True + self.get_namespace("//./root/cimv2") + except Exception as e: if "access_denied" not in str(e).lower(): self.logger.fail(str(e)) return False + else: + self.logger.extra["protocol"] = "WMI" + self.admin_privs = True def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False): self.logger.debug("Starting WMI login with Kerberos") From e55cc5d23d4b103931459261fc56ae80d22be1f8 Mon Sep 17 00:00:00 2001 From: zblurx Date: Tue, 20 Oct 2026 13:42:55 +0200 Subject: [PATCH 5/6] ruff --- nxc/protocols/wmi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index a30b1a86..2718fa8e 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -206,7 +206,6 @@ class wmi(connection): try: self.iWbemLevel1Login = IWbemLevel1Login(iInterface) self.get_namespace("//./root/cimv2") - except Exception as e: if "access_denied" not in str(e).lower(): self.logger.fail(str(e)) From 36e9731b2cef709ff784e8b9357ae6728641c452 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 20 Oct 2026 11:57:55 -0400 Subject: [PATCH 6/6] Remove duplicate proto log specification --- nxc/protocols/wmi.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nxc/protocols/wmi.py b/nxc/protocols/wmi.py index 2718fa8e..965aae30 100644 --- a/nxc/protocols/wmi.py +++ b/nxc/protocols/wmi.py @@ -172,8 +172,6 @@ class wmi(connection): self.logger.info(f"Resolved domain: {self.domain} with dns, kdcHost: {self.kdcHost}") def print_host_info(self): - self.logger.extra["protocol"] = "RPC" - self.logger.extra["port"] = "135" self.logger.display(f"{self.server_os} (name:{self.hostname}) (domain:{self.targetDomain})") def check_if_admin(self): @@ -202,7 +200,6 @@ class wmi(connection): self.logger.fail(error_msg) if not flag else self.logger.debug(error_msg) else: - self.logger.extra["protocol"] = "WMI" try: self.iWbemLevel1Login = IWbemLevel1Login(iInterface) self.get_namespace("//./root/cimv2") @@ -211,7 +208,6 @@ class wmi(connection): self.logger.fail(str(e)) return False else: - self.logger.extra["protocol"] = "WMI" self.admin_privs = True def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False):