On a recent engagement, it was noticed that Responder and Metasploit's LLMNR and NBT-NS spoofing modules weren't capturing the hashes like initially expected. Doing some investigation into some of the capabilities of Responder, some observations can be made. A name conflict may arise when poisoning LLMNR or NBT-NS requests for known names, not allowing for NTLM authentication to be initiated when requesting an SMB share. Secondly, Internet Explorer 11 has blocked proxy configuration scripts (i.e. WPAD) that require authentication, preventing these tools from initiating Basic authentication. Be sure to look out for this behavior in the field and adjust accordingly. Happy hacking!
This research is not considered to be absolute and complete, these are just observations made that I figured to be worth of a blog post. As I'm always learning and could be way off point, please correct/advise :) I'm far from an expert in the subject matter. Let us get started.
On a recent internal penetration test, I found myself in a position where capturing Windows credentials seemed to be one of the remaining options of gaining a foothold on the domain. It came down to tools like Responder and Metasploit's LLMNR and NBT-NS poisoning modules. Over the past couple of years, there has some good research on this topic. Collectively, this attack method is known to be very reliable in the security community (at least I think so). Given the amount of information on the internet regarding how these tools and LLMNR/NBT-NS poisoning works, I won't be reiterating the information in this post. Please see references for more information.
During the engagement I spin up Responder, force WPAD authentication, and sit back while the credentials roll in.
Thirty minutes go by with no credentials. A few hours go by ... no credentials.
What could be the problem? Where are the hashes?! Surely, Responder is poisoning the LLMNR and NBT-NS requests effectively. I try different command line switch configurations, all to no avail. Of course the big question is why. There has to be a explanation for Responder running for hours and never capturing a password. It's off to the lab to do some investigation on Responder.
Our primary question: Although Responder is poisoning LLMNR and NBT-NS requests, why aren't we seeing credentials? Two very commonly discussed ways Responder capture hashes is by requesting an SMB share, or when IE requests for WPAD. We will be investigating these two functions in this post.
- Attacker Machine (Kali): 10.10.10.101
- Victim (Windows 2012 Server): 10.10.10.102
FYI these two hosts are in a Active Directory lab with Victim.
Spinning up Responder and start seeing some activity.
root@kali# ./Responder.py -I eth0 -wFf
After 10 minutes, still aren't seeing any hashes. Responder is poisoning the LLMNR and NBNS requests generated by the victim, but it isn't until I requests an SMB share with a random name (as described in several tutorials) that we get a hash. Credentials are captured on a query for a name that doesn't currently exists on the network, it must be unique (i.e. \fielshare). As long as the name the victim is querying for exists on the domain, the poisoning tools do not get the opportunity to initiate a NTLM challenge.
In an engagement, it looks like capturing a hash depends on this condition being "triggered", as Windows is unlikely to request \\fielshare on its own. Analysis shows that the NetBIOS requests generated without "outside assistance" are only for known names, which Responder will not capture hashes despite poisoning responses. This may explain why I didn't much results during the assessment. Perhaps no arbitrary name queries took place on the network. Exactly what prevents Responder from sending a NTLM challenge for an existing name when requesting an SMB share?
We examine a message exchange that occurs when our victim queries a valid name, in this case the domain PWNLAB. (Side note, these requests were generated by typing "\\" in the victim's Windows Explorer.)
Here we can see the NBNS broadcast name query for PWNLAB (packet 648). Packet 650 shows Responder poising the request. Finally in packets number 651 (highlighted), we see this "Name is on conflict" message sent from the victim. Let's take a closer look at this packet.
Looking at the highlighted row, this shows that the field values are set to indicate a conflict. This name conflict causes the victim to not communicate with the attacker as expected.
RFC 1002 for NBNS gives some information regarding name conflicts. Check out the RFC itself for more information.
RFC 4795 for LLMNR states,
Queries with the 'C' bit set are considered advisory, and responders MUST verify the existence of a conflict before acting on it. A responder receiving a query with the 'C' bit set MUST NOT respond.
Protocol operations sensitive to successive response packets, such as name conflict detection, are protected from duplicated packets because they ignore successive packets with the same NetBIOS information. Since no state on the responder's node is associated with a request, the responder just sends the appropriate response whenever a request packet arrives. Consequently, duplicate or delayed request packets have no impact.
The victim ignores successive packets from nodes where conflict detection arises. One can conclude that the successful packets to set up a TCP and SMB connection do not occur between the attacker and victim as oppose to when a unique (arbitrary) name is requested. Looking back at the previous Wireshark image following message exchange being repeated.
- Victim name query request
- Attacker poisoned name query response
- Victim name conflict detection
Now let's see what happens when the victim requests an arbitrary name (i.e. ramdom), triggered by requested the share \\ramdom. (Side note: haste typing caused "random" to be "ramdom".)
In the above image 3 observations can be made.
- Packet# 914 - 922: Name query for ramdom followed by poisoned response
- Packet# 923 - 927: Creation of a TCP connection, and following SMB connection attempt
- Packet# 928 - 931: NTLM challenge transactions resulting in the attacker capturing hashes
This is why a trigger is needed, which in a real engagement you can't truly sit back and wait for the credentials to roll in. An attacker must rely on an instance where a unique name is requested, either via simple user error or perhaps forcing a victim to send a name requests for a unique name. These tools are still outstanding, but this explains the instances where no hashes are captured.
Unless the basic authentication switch (-b) is used, the same trigger applies for Responder's HTTP/HTTPS/FTP module. A successful attack happens upon an arbitrary name (i.e. http://unknowndomain123/).
Force WPAD Authentication
This leads to another reliable methods Responder uses to grab hashes ... forcing WPAD authentication. This topic has received a lot of discussion and is pretty popular. Once again, multiple articles explain this so I'll will leave it to them (they can explain it better I'm sure). Testing still proves this to be extremely reliable on IE prior to version 11, as you can truly sit back and wait for a victim to open IE. What about IE11 and beyond? On a Windows Server 2012 R2 or Windows 10 environment? During the engagement this wasn't working either, no hashes were captured. Once again we ask the question why.
We have the same lab setup mentioned above. By default, "Automatically detect settings" is enabled in IE's LAN Settings, and will send requests for WPAD quite frequently. Let's look at the traffic:
We can see that Responder is poisoning the LLMNR requests, which is soon followed up with our victim requested wpad.dat from our rogue WPAD server. Looking at the TCP stream we can see the following message exchange.
Responder is attempting to get the victim to authenticate, however no Basic Authentication prompt appears. What's stopping this? After doing a little digging we see the following.
NOTE: IE11 Deprecates Non-Silent Auth when downloading Proxy Script
When downloading a proxy configuration script, it’s possible that the server will demand credentials from the client application. A problem arises if the server requests credentials using HTTP BASIC or HTTP DIGEST authentication, as these authentication methods require that the user respond to a credential prompt dialog box. (In contrast, NTLM and Negotiate authenticate silently).
Many applications cannot handle showing prompts as a part of this workflow and will fail silently. To promote interoperability, IE11 also blocks the use of Proxy Configuration scripts that require authentication.
Responder is attempting to force NTLM or Basic Authentication, but IE11 in its default state now blocks proxy configurations that require authentication.
In conclusion, if you aren't seeing any hashes after running Responder for awhile time you may want to give it a trigger. Perhaps by supplying a link, or using a man-in-the-middle proxy. This post isn't to diminish Responder or LLMNT/NBNT-NS poisoning tools in any way. These are still very reliable, amazing tools, and the effort in developing them is truly appreciated. Instead, it is to simply highlight some of the reasons why one may not seeing your hashes when testing an environment with more up-to-date hosts. All to make one more aware during engagements.