CVE-2021-1675 is a elevation of privilege vulnerability that affected all Windows Servers from version 2004 to 20H2 and all windows desktops from Windows 7 to Windows 10. While CVE-2021-1675 and CVE-2021-34527 (PrintNightmare) take advantage of the windows print spooler, both exploits approach the vulnerability in different ways. CVE-2021-1675 can only be exploited locally and is only used to escalate user privileges while PrintNightmare is uses Remote Code Execution which makes the threat of the vulnerability much higher.

Breakdown of CVE-2021-1675

The initially discovered exploit is a Local Privilege Escalation to create a user with admin permissions. The source of the vulnerability is the AddPrinterDriverEx function on windows systems, which installs a printer driver and links the configuration, data and driver files. Microsoft states that the function of AddPrinterDriverEx requires SeLoadDriverPivilege which is only given to Administrators and Print Operators. however, using the parameters in the function, the SeLoadDriverPrivilege check can be bypassed.

The AddPrinterDriverEx function requires 4 parameters:

BOOL AddPrinterDriverEx(
	_In_ LPTSTR pName,
	_In_ DWORD Level,
	_Inout_ LPBYTE pDriverInfo,
	_In_DWORD dwFileCopyFlags );
  • pName is the name of the server on which the driver should be installed
  • Level is the DriverInfo structure version
  • pDriverInfo is the structure with all the printer driver information
  • dwFileCopyFlags is the option for copying driver files

To exploit the function the following Proof of Concept is used,

$APD_COPY_ALL_FILES = 0x00000004

$driver_info = New-Object $DRIVER_INFO_2
$driver_info.cVersion = 3
$driver_info.pConfigFile = $DLL
$driver_info.pDataFile = $DLL

$pDriverInfo = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Runtime.InteropServices.Marshal]::SizeOf($driver_info))
[System.Runtime.InteropServices.Marshal]::StructureToPtr($driver_info, $pDriverInfo, $false)

AddPrinterDriverEx($null, 2, $pDriverInfo, $APD_COPY_ALL_FILES -bor 0x10 -bor 0x8000

The pName parameter chosen was Null, as if the value is null, the function installs the driver on the local computer. Driver Level structure version 2 was chosen with the $pDriverInfo containing the payload as a Dynamic Linked Library (DLL) in its config file and data file. The $APD_COPY_ALL_FILES being set to 0x00000004 and having “-bor 0x10 -bor 0x8000” is requirement to bypass the authentication check done by the function

Bypassing Authentication

Within the spoolsv.exe process there is a DLL called localspl.dll which contains a Function called SplAddPrinterDriverEx. image | 600 The code contains the requirements for the AddPrinterDriverEx function to be executed. In the code Var_5 is set to 0 with a following “if statement” seeing if the 15th bit in param_4 is a 0. If the result is a 0, Var5 is set to param_7

The next if statement says if Var5 does not equal 0, then it will attempt to verify the user’s permission to execute the function. However the important part of the code is that the param_4 is editable by the attacker. As the base bit of the APD_COPY_ALL_FILES is set to 4, and a bitwise OR operation is run on 10 and 8000, the total hex value is 8014 which is 1000 0000 0001 0100 in binary. Due to the bit check including 0, the 15th bit in param_4 is now a 1, skipping all authentication. This means that an attacker can add a printer drive which has the privileges of the system.

To upload the payload to create a new administrator, a DLL payload is created, encoded then placed into the $pDriverInfo so when the driver is run, the code can be executed as system.

To see the CVE exploited, view my HackTheBox Writeup on Driver