PrintSpoofer is a tool that performs local privilege escalation by exploiting a vulnerability in the Windows Print Spooler service (CVE-2019-1040 / CVE-2019-1019). This project implements the PrintSpoofer exploit in Reflective DLL format, making it suitable for use with penetration testing frameworks such as Cobalt Strike.
- Overview
- How It Works
- Technical Details
- Requirements
- Build
- Usage
- Project Structure
- Security Disclaimer
- References
PrintSpoofer exploits a vulnerability in the Windows Print Spooler service that allows a low-privileged user to obtain SYSTEM-level privileges. The exploit abuses the way the Print Spooler service handles named pipes.
- Reflective DLL format — can be loaded entirely in memory without touching disk
- Works with SE_IMPERSONATE_NAME privilege
- Communicates with the Print Spooler service using the RPC protocol
- Uses the Named Pipe mechanism to perform token impersonation
PrintSpoofer operates by performing the following steps:
The exploit first checks whether the current token has the SE_IMPERSONATE_NAME privilege. This is required to impersonate another user’s token.
A named pipe is created using a random UUID. The pipe path is:
\\.\pipe\<UUID>\pipe\spoolss
An asynchronous connection is awaited on the created named pipe. An event is created, and the pipe is prepared to accept incoming connections.
In a separate thread, an RPC call is made to the Print Spooler service.
By invoking RpcRemoteFindFirstPrinterChangeNotificationEx, the service attempts to connect to the pipe we created.
When the Print Spooler service (running as SYSTEM) connects to the named pipe, the exploit uses ImpersonateNamedPipeClient to impersonate the service’s token.
This results in obtaining SYSTEM privileges.
With a SYSTEM token, high-privilege actions can now be executed.
The Windows Print Spooler service processes printer notifications through named pipes. Because the service does not properly validate pipe connections, an attacker can coerce it into connecting to a malicious pipe and then impersonate the SYSTEM token.
The project communicates with the Print Spooler service using the MS-RPRN (Print System Remote Protocol). This protocol is defined through an IDL (Interface Definition Language) file and enables RPC calls.
A reflective DLL behaves differently from standard DLLs:
- It can be loaded directly into memory without touching disk
- Does not require the
LoadLibraryAPI - Manually parses and loads the PE (Portable Executable) format
- Visual Studio 2022 (C++ Desktop Development workload)
- Windows 10/11
- Windows 10/11
- Print Spooler service running
- SE_IMPERSONATE_NAME privilege (available to most standard users by default)
- Cobalt Strike or a similar framework (optional)
-
Open the PrintSpoofer.sln file in Visual Studio.
-
Select your Solution Platform and Configuration:
- Platform:
x64orWin32(depending on the target architecture) - Configuration:
Release(production) orDebug(development)
- Platform:
-
Build the solution through
Build Solution(Ctrl+Shift+B). -
The compiled DLL will be located at:
PrintSpoofer\x64\Release\PrintSpoofer.dll (for x64) PrintSpoofer\Win32\Release\PrintSpoofer.dll (for x86)
The project uses the following preprocessor definitions:
REFLECTIVE_DLL_EXPORTS: Enables Reflective DLL exportsREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN: Uses a custom DllMainREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR: Enables LoadRemoteLibraryR (in Release mode)
PrintSpoofer can be used with Cobalt Strike's elevate command:
elevate PrintSpoofer LISTENER_NAME
Where:
PrintSpoofer: The elevator module nameLISTENER_NAME: The listener that will receive the elevated shell
The DLL can be manually loaded using Reflective DLL Injection techniques.
A successful exploit execution will show:
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] ImpersonateNamedPipeClient OK
[+] Exploit successfully, enjoy your shell
- DLL entry point (
DllMain) - Controls exploit logic
- Handles reflective DLL–specific functionality
- CheckAndEnablePrivilege: Checks and enables token privileges
- GenerateRandomPipeName: Generates pipe names using random UUIDs
- CreateSpoolNamedPipe: Creates named pipes and configures security
- ConnectSpoolNamedPipe: Prepares pipes for asynchronous connections
- TriggerNamedPipeConnection: Creates a thread to trigger Print Spooler connection
- TriggerNamedPipeConnectionThread: Performs RPC call
- GetSystem: Performs token impersonation
- IDL definition of Microsoft’s MS-RPRN protocol
- Processed by the MIDL compiler to generate RPC stubs
- Implements PE parsing and memory loading for Reflective DLL injection
This tool is intended for educational purposes only and for authorized penetration testing.
- https://www.itm4n.fr/printspoofer-abusing-impersonate-privileges/
- https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation
This project is licensed under the MIT License. For more information, see the LICENSE file.