From 56e535a6372f78b6ef9ccdd5aa59b22d30f93412 Mon Sep 17 00:00:00 2001 From: Lyderic Lefebvre Date: Thu, 22 Oct 2026 14:29:05 +0200 Subject: [PATCH 01/10] Add reauth_swap module: check cross-user SMB re-auth swap (enforced signing bypass viability) --- nxc/modules/reauth_swap.py | 136 +++++++++++++++++++++++++++++++++++++ tests/e2e_commands.txt | 1 + 2 files changed, 137 insertions(+) create mode 100644 nxc/modules/reauth_swap.py diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py new file mode 100644 index 00000000..24b3024e --- /dev/null +++ b/nxc/modules/reauth_swap.py @@ -0,0 +1,136 @@ +# Module by Lyderic Lefebvre (@aas_s3curity) - https://blackfield.ch +# Check if an SMB server still allows a cross-user re-authentication swap on an existing session: +# log in as one account, then re-authenticate as a different one on the same connection. That swap +# is the primitive an auth relay uses to keep a privileged session under a signing key it controls, +# defeating enforced SMB signing. Recent Windows builds allow same-user re-auth only and refuse the +# swap with ACCESS_DENIED. Not derivable from the build number, so it is probed live. +# https://blackfield.ch/blog/defeating-enforced-smb-signing/ +import binascii +import contextlib +from sys import exit + +from impacket import ntlm +from impacket.smbconnection import SMBConnection +from impacket.smb3 import SMB2SessionSetup, SMB2SessionSetup_Response +from impacket.smb3structs import SMB2_SESSION_SETUP +from impacket.spnego import SPNEGO_NegTokenInit, SPNEGO_NegTokenResp, TypesMech +from nxc.helpers.misc import CATEGORY + + +class NXCModule: + name = "reauth_swap" + description = "Check if the server allows a cross-user re-auth swap on an SMB session (used to defeat enforced signing); needs a 2nd account" + supported_protocols = ["smb"] + opsec_safe = False # performs an extra authentication with a second account + multiple_hosts = True + category = CATEGORY.ENUMERATION + + STATUS_SUCCESS = 0x00000000 + STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016 + STATUS_ACCESS_DENIED = 0xC0000022 + + def __init__(self, context=None, module_options=None): + self.context = context + self.module_options = module_options + self.probe_user = None + self.probe_pass = "" + self.probe_nthash = "" + + def options(self, context, module_options): + """ + PROBE_USER second account, must differ from the login account (required) + PROBE_PASS second account password + PROBE_NTHASH second account NT hash (instead of PROBE_PASS) + + The second account is probed over NTLM; its privileges do not matter. + """ + self.probe_user = module_options.get("PROBE_USER") + self.probe_pass = module_options.get("PROBE_PASS", "") + self.probe_nthash = module_options.get("PROBE_NTHASH", "") + if not self.probe_user: + context.log.fail("reauth_swap requires a second account: -o PROBE_USER= PROBE_PASS= (must differ from the account nxc logged in with)") + exit(1) + if not self.probe_pass and not self.probe_nthash: + context.log.fail("reauth_swap requires PROBE_PASS or PROBE_NTHASH for the second account") + exit(1) + + def reauth_as(self, smb, user, password, domain, nthash): + """Replay an NTLM (Type1/Type3) session setup as `user` on an EXISTING session; return the NTSTATUS.""" + type1 = ntlm.getNTLMSSPType1("", domain) + blob = SPNEGO_NegTokenInit() + blob["MechTypes"] = [TypesMech["NTLMSSP - Microsoft NTLM Security Support Provider"]] + blob["MechToken"] = type1.getData() + setup = SMB2SessionSetup() + setup["Flags"] = 0 + setup["SecurityMode"] = 1 + setup["SecurityBufferLength"] = len(blob.getData()) + setup["Buffer"] = blob.getData() + pkt = smb.SMB_PACKET() + pkt["Command"] = SMB2_SESSION_SETUP + pkt["Data"] = setup + ans = smb.recvSMB(smb.sendSMB(pkt)) + if ans["Status"] != self.STATUS_MORE_PROCESSING_REQUIRED: + return ans["Status"] + + resp = SMB2SessionSetup_Response(ans["Data"]) + try: + type2 = SPNEGO_NegTokenResp(resp["Buffer"])["ResponseToken"] + except Exception: + raw = resp["Buffer"] + type2 = raw[raw.index(b"NTLMSSP"):] + lm = nt = "" + if nthash: + lm = binascii.unhexlify("aad3b435b51404eeaad3b435b51404ee") + nt = binascii.unhexlify(nthash) + type3, _ = ntlm.getNTLMSSPType3(type1, type2, user, password, domain, lmhash=lm, nthash=nt) + blob2 = SPNEGO_NegTokenResp() + blob2["ResponseToken"] = type3.getData() + setup2 = SMB2SessionSetup() + setup2["Flags"] = 0 + setup2["SecurityMode"] = 1 + setup2["SecurityBufferLength"] = len(blob2.getData()) + setup2["Buffer"] = blob2.getData() + pkt2 = smb.SMB_PACKET() + pkt2["Command"] = SMB2_SESSION_SETUP + pkt2["Data"] = setup2 + ans2 = smb.recvSMB(smb.sendSMB(pkt2)) + return ans2["Status"] + + def on_login(self, context, connection): + if self.probe_user.lower() == (connection.username or "").lower(): + context.log.fail("PROBE_USER must differ from the account nxc logged in with: only a cross-user swap is refused, so the same account always succeeds and tests nothing") + return + + # without enforced signing there is nothing to bypass: a relayed auth is accepted directly + if not connection.signing: + context.log.info("SMB signing not enforced, nothing to bypass - skipping") + return + + domain = connection.domain + prim_user = connection.username + prim_pass = connection.password or "" + prim_nthash = connection.nthash or "" + + try: + # fresh session so nxc's own connection is left untouched + conn = SMBConnection(connection.remoteName, connection.host, preferredDialect=0x0311) + if connection.kerberos: + conn.kerberosLogin(prim_user, prim_pass, domain, connection.lmhash, prim_nthash, connection.aesKey or "", kdcHost=connection.kdcHost, useCache=bool(connection.use_kcache)) + else: + conn.login(prim_user, prim_pass, domain, lmhash=connection.lmhash, nthash=prim_nthash) + try: + status = self.reauth_as(conn.getSMBServer(), self.probe_user, self.probe_pass, domain, self.probe_nthash) + finally: + with contextlib.suppress(Exception): + conn.close() + except Exception as e: + context.log.info(f"could not probe this host: {e.__class__.__name__}: {e}") + return + + if status == self.STATUS_SUCCESS: + context.log.highlight("VULNERABLE - enforced SMB signing bypassable") + context.log.highlight("Next step: https://blackfield.ch/blog/defeating-enforced-smb-signing/") + elif status == self.STATUS_ACCESS_DENIED: + context.log.display("not vulnerable - cross-user re-auth swap refused (ACCESS_DENIED), same-user re-auth only") + else: + context.log.display(f"inconclusive - second session setup returned 0x{status:08X}") diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index cc57741c..b5008856 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -153,6 +153,7 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M putty netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdcman #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=enable #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=disable +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M reauth_swap -o PROBE_USER=SECOND_USERNAME PROBE_PASS=SECOND_PASSWORD netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M reg-query -o PATH=HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion KEY=DevicePath netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M runasppl netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M scuffy -o SERVER=127.0.0.1 NAME=test From 6fbea2ae1d6ee36450cfdaddceeba593327dbda4 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 19:27:21 +0100 Subject: [PATCH 02/10] Move module doc --- nxc/modules/reauth_swap.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index 24b3024e..e0c4ad7d 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -1,10 +1,3 @@ -# Module by Lyderic Lefebvre (@aas_s3curity) - https://blackfield.ch -# Check if an SMB server still allows a cross-user re-authentication swap on an existing session: -# log in as one account, then re-authenticate as a different one on the same connection. That swap -# is the primitive an auth relay uses to keep a privileged session under a signing key it controls, -# defeating enforced SMB signing. Recent Windows builds allow same-user re-auth only and refuse the -# swap with ACCESS_DENIED. Not derivable from the build number, so it is probed live. -# https://blackfield.ch/blog/defeating-enforced-smb-signing/ import binascii import contextlib from sys import exit @@ -18,6 +11,16 @@ from nxc.helpers.misc import CATEGORY class NXCModule: + """ + Module made by: Lyderic Lefebvre (@aas_s3curity) - https://blackfield.ch + + Check if an SMB server still allows a cross-user re-authentication swap on an existing session: + log in as one account, then re-authenticate as a different one on the same connection. That swap + is the primitive an auth relay uses to keep a privileged session under a signing key it controls, + defeating enforced SMB signing. Recent Windows builds allow same-user re-auth only and refuse the + swap with ACCESS_DENIED. Not derivable from the build number, so it is probed live. + https://blackfield.ch/blog/defeating-enforced-smb-signing/ + """ name = "reauth_swap" description = "Check if the server allows a cross-user re-auth swap on an SMB session (used to defeat enforced signing); needs a 2nd account" supported_protocols = ["smb"] From 0e4959c10d3843f6259a3ebb78704d6d7faa8ff0 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 19:27:43 +0100 Subject: [PATCH 03/10] Formatting --- nxc/modules/reauth_swap.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index e0c4ad7d..4fcfdde2 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -24,8 +24,6 @@ class NXCModule: name = "reauth_swap" description = "Check if the server allows a cross-user re-auth swap on an SMB session (used to defeat enforced signing); needs a 2nd account" supported_protocols = ["smb"] - opsec_safe = False # performs an extra authentication with a second account - multiple_hosts = True category = CATEGORY.ENUMERATION STATUS_SUCCESS = 0x00000000 From 468c4f93b9fb0bef03f8f8d3404bf0a55685202e Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 19:28:12 +0100 Subject: [PATCH 04/10] Formatting --- nxc/modules/reauth_swap.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index 4fcfdde2..810c1a36 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -30,13 +30,6 @@ class NXCModule: STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016 STATUS_ACCESS_DENIED = 0xC0000022 - def __init__(self, context=None, module_options=None): - self.context = context - self.module_options = module_options - self.probe_user = None - self.probe_pass = "" - self.probe_nthash = "" - def options(self, context, module_options): """ PROBE_USER second account, must differ from the login account (required) From add06debbc8563b2820d346a3bac3fcf98c77fa0 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 20:07:08 +0100 Subject: [PATCH 05/10] Formatting --- nxc/modules/reauth_swap.py | 78 +++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index 810c1a36..6c356c97 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -48,6 +48,45 @@ class NXCModule: context.log.fail("reauth_swap requires PROBE_PASS or PROBE_NTHASH for the second account") exit(1) + def on_login(self, context, connection): + if self.probe_user.lower() == (connection.username or "").lower(): + context.log.fail("PROBE_USER must differ from the account nxc logged in with: only a cross-user swap is refused, so the same account always succeeds and tests nothing") + return + + # without enforced signing there is nothing to bypass: a relayed auth is accepted directly + if not connection.signing: + context.log.info("SMB signing not enforced, nothing to bypass - skipping") + return + + domain = connection.domain + prim_user = connection.username + prim_pass = connection.password or "" + prim_nthash = connection.nthash or "" + + try: + # fresh session so nxc's own connection is left untouched + conn = SMBConnection(connection.remoteName, connection.host, preferredDialect=0x0311) + if connection.kerberos: + conn.kerberosLogin(prim_user, prim_pass, domain, connection.lmhash, prim_nthash, connection.aesKey or "", kdcHost=connection.kdcHost, useCache=bool(connection.use_kcache)) + else: + conn.login(prim_user, prim_pass, domain, lmhash=connection.lmhash, nthash=prim_nthash) + try: + status = self.reauth_as(conn.getSMBServer(), self.probe_user, self.probe_pass, domain, self.probe_nthash) + finally: + with contextlib.suppress(Exception): + conn.close() + except Exception as e: + context.log.info(f"could not probe this host: {e.__class__.__name__}: {e}") + return + + if status == self.STATUS_SUCCESS: + context.log.highlight("VULNERABLE - enforced SMB signing bypassable") + context.log.highlight("Next step: https://blackfield.ch/blog/defeating-enforced-smb-signing/") + elif status == self.STATUS_ACCESS_DENIED: + context.log.display("not vulnerable - cross-user re-auth swap refused (ACCESS_DENIED), same-user re-auth only") + else: + context.log.display(f"inconclusive - second session setup returned 0x{status:08X}") + def reauth_as(self, smb, user, password, domain, nthash): """Replay an NTLM (Type1/Type3) session setup as `user` on an EXISTING session; return the NTSTATUS.""" type1 = ntlm.getNTLMSSPType1("", domain) @@ -89,42 +128,3 @@ class NXCModule: pkt2["Data"] = setup2 ans2 = smb.recvSMB(smb.sendSMB(pkt2)) return ans2["Status"] - - def on_login(self, context, connection): - if self.probe_user.lower() == (connection.username or "").lower(): - context.log.fail("PROBE_USER must differ from the account nxc logged in with: only a cross-user swap is refused, so the same account always succeeds and tests nothing") - return - - # without enforced signing there is nothing to bypass: a relayed auth is accepted directly - if not connection.signing: - context.log.info("SMB signing not enforced, nothing to bypass - skipping") - return - - domain = connection.domain - prim_user = connection.username - prim_pass = connection.password or "" - prim_nthash = connection.nthash or "" - - try: - # fresh session so nxc's own connection is left untouched - conn = SMBConnection(connection.remoteName, connection.host, preferredDialect=0x0311) - if connection.kerberos: - conn.kerberosLogin(prim_user, prim_pass, domain, connection.lmhash, prim_nthash, connection.aesKey or "", kdcHost=connection.kdcHost, useCache=bool(connection.use_kcache)) - else: - conn.login(prim_user, prim_pass, domain, lmhash=connection.lmhash, nthash=prim_nthash) - try: - status = self.reauth_as(conn.getSMBServer(), self.probe_user, self.probe_pass, domain, self.probe_nthash) - finally: - with contextlib.suppress(Exception): - conn.close() - except Exception as e: - context.log.info(f"could not probe this host: {e.__class__.__name__}: {e}") - return - - if status == self.STATUS_SUCCESS: - context.log.highlight("VULNERABLE - enforced SMB signing bypassable") - context.log.highlight("Next step: https://blackfield.ch/blog/defeating-enforced-smb-signing/") - elif status == self.STATUS_ACCESS_DENIED: - context.log.display("not vulnerable - cross-user re-auth swap refused (ACCESS_DENIED), same-user re-auth only") - else: - context.log.display(f"inconclusive - second session setup returned 0x{status:08X}") From 8a8d4ec93e86978c1734b1afcf9a172d0e05b365 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 20:07:37 +0100 Subject: [PATCH 06/10] Formatting --- nxc/modules/reauth_swap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index 6c356c97..d47e90ca 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -43,10 +43,10 @@ class NXCModule: self.probe_nthash = module_options.get("PROBE_NTHASH", "") if not self.probe_user: context.log.fail("reauth_swap requires a second account: -o PROBE_USER= PROBE_PASS= (must differ from the account nxc logged in with)") - exit(1) + return False if not self.probe_pass and not self.probe_nthash: context.log.fail("reauth_swap requires PROBE_PASS or PROBE_NTHASH for the second account") - exit(1) + return False def on_login(self, context, connection): if self.probe_user.lower() == (connection.username or "").lower(): From 3ff527b6986b3d2532743621c7e334cfd3f9c169 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 20:16:21 +0100 Subject: [PATCH 07/10] Use built-in smb conn reestablisher --- nxc/modules/reauth_swap.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index d47e90ca..bda56aa1 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -8,6 +8,7 @@ from impacket.smb3 import SMB2SessionSetup, SMB2SessionSetup_Response from impacket.smb3structs import SMB2_SESSION_SETUP from impacket.spnego import SPNEGO_NegTokenInit, SPNEGO_NegTokenResp, TypesMech from nxc.helpers.misc import CATEGORY +from nxc.helpers.smb import get_smb_connection class NXCModule: @@ -58,23 +59,14 @@ class NXCModule: context.log.info("SMB signing not enforced, nothing to bypass - skipping") return - domain = connection.domain - prim_user = connection.username - prim_pass = connection.password or "" - prim_nthash = connection.nthash or "" - try: # fresh session so nxc's own connection is left untouched - conn = SMBConnection(connection.remoteName, connection.host, preferredDialect=0x0311) - if connection.kerberos: - conn.kerberosLogin(prim_user, prim_pass, domain, connection.lmhash, prim_nthash, connection.aesKey or "", kdcHost=connection.kdcHost, useCache=bool(connection.use_kcache)) - else: - conn.login(prim_user, prim_pass, domain, lmhash=connection.lmhash, nthash=prim_nthash) + new_conn = get_smb_connection(context, connection, timeout=connection.args.smb_timeout) try: - status = self.reauth_as(conn.getSMBServer(), self.probe_user, self.probe_pass, domain, self.probe_nthash) + status = self.reauth_as(new_conn.getSMBServer(), self.probe_user, self.probe_pass, connection.domain, self.probe_nthash) finally: with contextlib.suppress(Exception): - conn.close() + new_conn.close() except Exception as e: context.log.info(f"could not probe this host: {e.__class__.__name__}: {e}") return From e48413e44867c95caff00510ce2db41e78e012cb Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 20:16:38 +0100 Subject: [PATCH 08/10] Alert the user if something goes wrong --- nxc/modules/reauth_swap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index bda56aa1..b0a7163a 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -68,7 +68,7 @@ class NXCModule: with contextlib.suppress(Exception): new_conn.close() except Exception as e: - context.log.info(f"could not probe this host: {e.__class__.__name__}: {e}") + context.log.fail(f"could not probe this host: {e.__class__.__name__}: {e}") return if status == self.STATUS_SUCCESS: From 6a07de72a278318ec44f6976e04d62042132b552 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Tue, 27 Oct 2026 20:21:41 +0100 Subject: [PATCH 09/10] Formatting and some comments --- nxc/modules/reauth_swap.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index b0a7163a..7bfe189e 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -81,10 +81,12 @@ class NXCModule: def reauth_as(self, smb, user, password, domain, nthash): """Replay an NTLM (Type1/Type3) session setup as `user` on an EXISTING session; return the NTSTATUS.""" + # Create NTLM Type1 message (challenge) type1 = ntlm.getNTLMSSPType1("", domain) blob = SPNEGO_NegTokenInit() blob["MechTypes"] = [TypesMech["NTLMSSP - Microsoft NTLM Security Support Provider"]] blob["MechToken"] = type1.getData() + setup = SMB2SessionSetup() setup["Flags"] = 0 setup["SecurityMode"] = 1 @@ -93,6 +95,7 @@ class NXCModule: pkt = smb.SMB_PACKET() pkt["Command"] = SMB2_SESSION_SETUP pkt["Data"] = setup + ans = smb.recvSMB(smb.sendSMB(pkt)) if ans["Status"] != self.STATUS_MORE_PROCESSING_REQUIRED: return ans["Status"] @@ -103,20 +106,26 @@ class NXCModule: except Exception: raw = resp["Buffer"] type2 = raw[raw.index(b"NTLMSSP"):] + lm = nt = "" if nthash: lm = binascii.unhexlify("aad3b435b51404eeaad3b435b51404ee") nt = binascii.unhexlify(nthash) + + # Create NTLM Type3 message (authentication) type3, _ = ntlm.getNTLMSSPType3(type1, type2, user, password, domain, lmhash=lm, nthash=nt) blob2 = SPNEGO_NegTokenResp() blob2["ResponseToken"] = type3.getData() + setup2 = SMB2SessionSetup() setup2["Flags"] = 0 setup2["SecurityMode"] = 1 setup2["SecurityBufferLength"] = len(blob2.getData()) setup2["Buffer"] = blob2.getData() + pkt2 = smb.SMB_PACKET() pkt2["Command"] = SMB2_SESSION_SETUP pkt2["Data"] = setup2 + ans2 = smb.recvSMB(smb.sendSMB(pkt2)) return ans2["Status"] From f16d0f8cf809d0528b7a46197b7bb148a161d318 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Wed, 28 Oct 2026 00:26:49 +0100 Subject: [PATCH 10/10] Remove unused imports --- nxc/modules/reauth_swap.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nxc/modules/reauth_swap.py b/nxc/modules/reauth_swap.py index 7bfe189e..d6788dbe 100644 --- a/nxc/modules/reauth_swap.py +++ b/nxc/modules/reauth_swap.py @@ -1,9 +1,7 @@ import binascii import contextlib -from sys import exit from impacket import ntlm -from impacket.smbconnection import SMBConnection from impacket.smb3 import SMB2SessionSetup, SMB2SessionSetup_Response from impacket.smb3structs import SMB2_SESSION_SETUP from impacket.spnego import SPNEGO_NegTokenInit, SPNEGO_NegTokenResp, TypesMech