|
8 | 8 | class NXCModule: |
9 | 9 | # https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025 |
10 | 10 | # 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 |
11 | 12 | name = "ntlm_reflection" |
12 | 13 | description = "Attempt to check if the OS is vulnerable to CVE-2025-33073 (NTLM Reflection attack)" |
13 | 14 | supported_protocols = ["smb"] |
@@ -48,34 +49,36 @@ def is_vulnerable(self, major, minor, build, ubr): |
48 | 49 | def on_login(self, context, connection): |
49 | 50 | self.context = context |
50 | 51 | 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']})") |
78 | 76 | 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