Skip to content

Commit 08207ee

Browse files
authored
Merge pull request Pennyw0rth#935 from Dfte/ntlmreflection_path
[NTLM reflection] Fix false assumption over smb signing
2 parents 0278b81 + 1c77c64 commit 08207ee

1 file changed

Lines changed: 33 additions & 30 deletions

File tree

nxc/modules/ntlm_reflection.py

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class NXCModule:
99
# https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025
1010
# Modified by azoxlpf to handle BrokenPipe/transport errors gracefully
11+
# Modified by Defte following the discovery of ctjf (https://github.com/Pennyw0rth/NetExec/issues/928) and the research done along side with @NeffIsBack and I
1112
name = "ntlm_reflection"
1213
description = "Attempt to check if the OS is vulnerable to CVE-2025-33073 (NTLM Reflection attack)"
1314
supported_protocols = ["smb"]
@@ -48,34 +49,36 @@ def is_vulnerable(self, major, minor, build, ubr):
4849
def on_login(self, context, connection):
4950
self.context = context
5051
self.connection = connection
51-
if not connection.conn.isSigningRequired(): # Not vulnerable if SMB signing is enabled
52-
connection.trigger_winreg()
53-
rpc = transport.DCERPCTransportFactory(r"ncacn_np:445[\pipe\winreg]")
54-
rpc.set_smb_connection(connection.conn)
55-
if connection.kerberos:
56-
rpc.set_kerberos(connection.kerberos, kdcHost=connection.kdcHost)
57-
dce = rpc.get_dce_rpc()
58-
if connection.kerberos:
59-
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
60-
try:
61-
dce.connect()
62-
dce.bind(rrp.MSRPC_UUID_RRP)
63-
# Reading UBR from registry
64-
hRootKey = rrp.hOpenLocalMachine(dce)["phKey"]
65-
hKey = rrp.hBaseRegOpenKey(dce, hRootKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")["phkResult"]
66-
ubr = rrp.hBaseRegQueryValue(dce, hKey, "UBR")[1]
67-
version_str = f"{connection.server_os_major}.{connection.server_os_minor}.{connection.server_os_build}.{ubr}" if ubr else None
68-
dce.disconnect()
69-
if not version_str:
70-
self.context.log.info("Could not determine OS version from registry")
71-
return
72-
vuln = self.is_vulnerable(connection.server_os_major, connection.server_os_minor, connection.server_os_build, ubr)
73-
if vuln:
74-
context.log.highlight(f"VULNERABLE to {self.name}! {connection.server_os} ({version_str})")
75-
except SessionError as e:
76-
if "STATUS_OBJECT_NAME_NOT_FOUND" in str(e):
77-
self.context.log.info(f"RemoteRegistry is probably deactivated: {e}")
52+
connection.trigger_winreg()
53+
rpc = transport.DCERPCTransportFactory(r"ncacn_np:445[\pipe\winreg]")
54+
rpc.set_smb_connection(connection.conn)
55+
if connection.kerberos:
56+
rpc.set_kerberos(connection.kerberos, kdcHost=connection.kdcHost)
57+
dce = rpc.get_dce_rpc()
58+
if connection.kerberos:
59+
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
60+
try:
61+
dce.connect()
62+
dce.bind(rrp.MSRPC_UUID_RRP)
63+
# Reading UBR from registry
64+
hRootKey = rrp.hOpenLocalMachine(dce)["phKey"]
65+
hKey = rrp.hBaseRegOpenKey(dce, hRootKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")["phkResult"]
66+
ubr = rrp.hBaseRegQueryValue(dce, hKey, "UBR")[1]
67+
version_str = f"{connection.server_os_major}.{connection.server_os_minor}.{connection.server_os_build}.{ubr}" if ubr else None
68+
dce.disconnect()
69+
if not version_str:
70+
self.context.log.info("Could not determine OS version from registry")
71+
return
72+
vuln = self.is_vulnerable(connection.server_os_major, connection.server_os_minor, connection.server_os_build, ubr)
73+
if vuln:
74+
if not connection.conn.isSigningRequired(): # Not vulnerable if SMB signing is enabled
75+
context.log.highlight(f"VULNERABLE (can relay SMB to any protocol on {self.context.log.extra['host']})")
7876
else:
79-
self.context.log.debug(f"Unexpected error: {e}")
80-
except (BrokenPipeError, ConnectionResetError, NetBIOSError, OSError) as e:
81-
context.log.debug(f"ntlm_reflection: DCERPC transport error: {e.__class__.__name__}: {e}")
77+
context.log.highlight(f"VULNERABLE (can relay SMB to other protocols except SMB on {self.context.log.extra['host']})")
78+
except SessionError as e:
79+
if "STATUS_OBJECT_NAME_NOT_FOUND" in str(e):
80+
self.context.log.info(f"RemoteRegistry is probably deactivated: {e}")
81+
else:
82+
self.context.log.debug(f"Unexpected error: {e}")
83+
except (BrokenPipeError, ConnectionResetError, NetBIOSError, OSError) as e:
84+
context.log.debug(f"ntlm_reflection: DCERPC transport error: {e.__class__.__name__}: {e}")

0 commit comments

Comments
 (0)