Skip to Main Content
September 15, 2022

Practical Attacks against NTLMv1

Written by Esteban Rodriguez

1.1   Introduction

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) / Shadow Credentials

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.

Figure 1 - LmCompatibilityLevel Registry Setting
Figure 2 - LAN Manager Authentication Level Group Policy Setting

1.2   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.

Figure 3 - Responder with Static Challenge

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 cracked 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.

Figure 4 - Coerced Authentication via Petit Potam
Figure 5 - NTLMv1 Hash with SSP Enabled
Figure 6 - NTLMv1 Hash without SSP Enabled

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.

Figure 7 - DCSync Attack

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]
Figure 8 - Crafting ad Using a Silver Ticket

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.

Figure 9 - Dumping Domain info

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.

1.3   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
  • DCsync

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.

Figure 10 - Coercing Authentication via Coercer

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.

Figure 11 - LDAP Relay Attack

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]
Figure 12 - Creation of Service Ticket

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
Figure 13 - Shell as Domain Admin via wmiexec
Figure 14 - DCSync as Domain Admin via secretsdump

While the RBCD method works most of the time, it is sometimes hindered when accounts are not allowed to create new computer objects. Another method exists, this requires at least a Server 2016 functional level, and Active Directory Certificate Services to be configured.

The Shadow Credentials attack works much in the same way, however instead of modifying the msDS-AllowedToActOnBehalfOfOtherIdentity attribute we will instead update the msDS-KeyCredentialLink attribute.

We will set up the relay using the --shadow-credentials flag instead of --delegate access.

The coercion with Coercer is performed the same way.

python3 ntlmrelayx.py -t ldaps://[DOMAIN CONTROLLER] --remove-mic -smb2support --shadow-credentials


After completion, a certificate will be generated. With this certificate, it is then possible to request a TGT for the coerced domain controller’s computer account. In order to request a ticket, PKINITtools can be used.

python3 gettgtpkinit.py -cert-pfx [CERTIFICATE].pfx -pfx-pass [PASSWORD] [DOMAIN]/[DOMAIN CONTROLLER] [TICKET].ccache


The ticket alone is enough to perform a DCSync attack, but it also possible to use PKINITtools to also recover the NT Hash of the domain controller’s computer account. After configuring your system to use the recovered Kerberos ticket, you can then UnPAC the hash.

export KRB5CCNAME=[TICKET].ccache
python3 getnthash.py [DOMAIN]/[DOMAIN COMNTROLLER] -key [KEY]

1.4   Conclusion

There are a number of different ways to disrupt steps in these attack chains, but the most significant of all is simply disabling NTLMv1 from being used on the network. I recommend setting a domain-wide GPO to only send NTLMv2 responses.

I hope this blog serves as a quick reference for performing these types of attacks in addition to the pre-existing guides and technical deep dives referenced throughout the blog.

If you know of even more practical attacks against NTLMv1, I'd love to hear about them. You can always DM me on Twitter at @n00py1.