This blog is meant to serve as a guide for practical exploitation of systems that allow for the NTLMv1 authentication protocol. While NTLMv1 is hardly ever needed anymore, a surprising number of organizations still use it, perhaps unknowingly. There are however some VPN products that still currently instruct their users to downgrade NLTM authentication to the lowest security level. Reasons given are that NLTMv2 does not work with RADIUS or MS-CHAPv2, however other VPN solutions seem to have a solution to the issue while still using NTLMv2.
Two different attack methods will be covered:
- Authentication Downgrade -> Cracking
- LDAP Relay -> Resource Based Constrained Delegation (RBCD)
These types of attacks are possible when the LmCompatibilityLevel registry key is set to either 0, 1, or 2. This can be configured via the registry on the system itself or enforced via Group Policy.
Attack 1: Authentication Downgrade
The first technique I discovered to exploit this was documented in Tim McGuffin‘s NetNTLMtoSilverTicket Github repository. In the readme, it documents the several steps to perform this attack:
- Configure Responder to set a static challenge downgrade the authentication
- Coerce an authentication from a system
- Crack the incoming hash
- Sliver Ticket and/or DCSync
The readme documents using SpoolSample and Dementor to coerce the authentication by abusing the Print Spooler service. This coercion technique is still very relevant despite some organizations now choosing to disable the print spooling service. Many other ways to coerce authentication have been discovered and implemented in such tools as Petit Potam, DFSCoerce, and Coercer.
Below is a demonstration of the full attack:
First, you want to configure responder to use a static challenge. By default, this is set to random. In order to be able to crack the subsequent hashes using rainbow tables, the challenge should be set to 1122334455667788.
When running Responder, you will want to use a command similar to:
Responder.py -I [INTERFACE] --lm
The –lm flag will allow you to crack the hashes almost instantly with crack.sh‘s rainbow tables. If this doesn’t work, you can always try the –disable-ess flag. If you are not able to remove SSP, it will no longer be possible to crack with crack.sh’s rainbow tables, though it can still be enumerated with Hashcat after reformatting with ntlmv1-multi or by using assless-chaps, which relies on a pre-computed database of NT hashes.
To further understand how each of the various NTLM hash types are formatted, I recommend watching the talk given by EvilMog – Anatomy of NTLMv1/NTLMv1-SSP.
The next step is to coerce the authentication in any manner you see fit. Most of these techniques require at least some level of authentication, however Petit Potam will work unauthenticated if a security update has not yet been applied. Each tool has its own syntax, which will typically require a set of valid domain credentials as well as the IP for the listener and the target.
Once cracked, you will recover the NT hash for the computer account that was coerced. The hash can then be used to craft a Silver Ticket, which can then be used to gain administrative access over the system. If the host is a domain controller, it can then be used to DCSync directly via PtH without needing to impersonate any other account.
If you would like to go the Silver Ticket route, it is documented in the NetNTLMtoSilverTicket Github repository. I also recommend this blog post, which dives into a bit more detail as to how to configure the Silver Ticket.
ticketer.py -nthash [DC HASH] -domain-sid [DOMAIN SID] -domain [DOMAIN] -spn cifs/[DC HOST NAME] -user-id [USER ID] -groups [DOMAIN GROUP ID] [USERNAME]
You will, of course, need the SID of the domain as well as the user and group IDs. You will likely want to craft the ticket that impersonates an existing domain administrator. I typically get these values from ldapdomaindump or BloodHound data. You can use Pass-the-Hash authentication by using the cracked NT hash in LM:NT format.
Sometimes crack.sh is down, so cracking the hash isn’t the best option or it just simply takes too long. While this technique is the most well-known, there exists an equally effective technique that does not require any cracking at all.
Attack 2: LDAP relay
I learned about this type of attack from a coworker but hadn’t found it documented anywhere, until I came across an excellent blog by Adam Crosser, which did a full deep dive into NTLM downgrade attacks. This attack had also been alluded to in another blog post I found. It has been well established that relaying SMB to LDAP is not possible, because SMB sets a flag which requires messages to be signed with a session key. Without this signature, the authentication will fail. This typically prevents the authentications coerced via the PrinterBug or Petit Potam from being relayed. The signature cannot be stripped in transit due to NTLM including a Message Integrity Code (MIC) for the full NTLM negotiation.
NTLMv1 provides an exception to this as NTLMv1 doesn’t support computing a MIC. Using Impacket’s ntlmrelayx.py, it is possible to specify the –remove-mic flag. This was originally intended to exploit CVE-2019-1040, also known as “Drop the MIC”.
It is possible to exploit NTLMv1 in almost the exact the same way you would CVE-2019-1040.
The attack chain would look like this:
- Set up ntlmrelayx.py to strip the MIC while also performing a RBCD attack
- Coerce authentication
- Craft a service ticket for an impersonated user
This has a few more prerequisites than the last attack: It requires at least two domain controllers to relay between and requires that they are at least at a Windows Server 2012 functional level for the RBCD attack to work.
First, ntlmrelayx.py is set up to relay to one of the domain controllers:
ntlmrelayx.py -t ldaps://[DOMAIN CONTROLLER] --remove-mic -smb2support --delegate-access
The coerced authentication is then trigged, targeting a second domain controller.
The authentication is then relayed to LDAP, which then creates a computer account and modifies delegation rights on the targeted domain controller by adding the SID of the new computer account to the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the domain controller.
Once this is complete, it is then possible to perform a Resourced Based Constrained Delegation Attack.
A service ticket can then be created, impersonating a domain administrator.
getST.py -spn cifs/[RELAYED DC] -impersonate [DOMAIN ADMIN] [CREATED COMPUTER]':[PASSWORD]
Once this ticket is created, it is then possible to perform two attacks to recover NT hashes from the domain controller:
- Get a command shell on the system as an administrator and recover the NTDS.dit database with a tool like ntdsutil
- Perform a DCSync attack against the domain controller to extract the NT hashes over the network
Additionally, this RBCD can be swapped out with a Shadow Credentials attack.
I didn't mention this in the blog, but you can swap out RBCD with Shadow Credentials if you want also.
Pro: Don't need to create computer object
Con: Need ADCS /Server 2016+ https://t.co/EoBGckmZQ0
— n00py (@n00py1) September 30, 2022