Featured image
Truesec pattern
Blog
2021-06-30

Fix for PrintNightmare CVE-2021-34527 exploit to keep your Print Servers running while a patch is not available

Fabio Viggiani
2 min readFabio Viggiani
Share

UPDATE JULY 6th, 2021:
Please check the updated recommendations in our previous post here.

As we wrote in our previous post, the PrintNightmare vulnerability is critical and should be addressed immediately, as a patch is not yet available. A regular domain user can easily take over the entire Active Directory domain.

While we still recommend that the print spooler service should be disabled on any system that does not need it, we also want to provide a temporary workaround to make the exploit ineffective, while allowing you to keep your print servers running, until a patch is available.

The exploit works by dropping a DLL in a subdirectory under C:\Windows\System32\spool\drivers

By restricting the ACLs on this directory (and subdirectories) we can prevent malicious DLLs to be introduced by the print spooler service.

At the moment, we are not aware of any way to force the DLL to be dropped in a different location.

Restricting the ACLs

The following PowerShell script will do the trick.

$Path = "C:\Windows\System32\spool\drivers"

$Acl = (Get-Item $Path).GetAccessControl('Access')

$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("System", "Modify", "ContainerInherit, ObjectInherit", "None", "Deny")

$Acl.AddAccessRule($Ar)

Set-Acl $Path $Acl

This will add a Deny rule for the drivers directory and all subdirectories, preventing the SYSTEM account to modify its contents.

If administrators need to perform configuration changes that require the service to write in these directories, this rule can temporarily be removed, and re-added after the change.

To remove the ACL we just added (as commented by u/bclimber):

$Path = "C:\Windows\System32\spool\drivers"

$Acl = (Get-Item $Path).GetAccessControl('Access')

$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("System", "Modify", "ContainerInherit, ObjectInherit", "None", "Deny")

$Acl.RemoveAccessRule($Ar)

Set-Acl $Path $Acl

This is not a perfect solution, but until a patch is available, it is a way to keep the print server running in cases where it is strictly necessary.

We have verified that the ACL prevents the successful execution of the following exploit implementations:

EDIT:

We changed:

$Acl <strong>=</strong> Get-Acl $Path

to:

$Acl <strong>=</strong> (Get-Item $Path).GetAccessControl('Access')

to avoid errors when running this as SYSTEM. Thanks _Dadministrator_ for bringing this up

EDIT2:

For a fancier version, Chaim Black wrote a nice wrapper function around it.

EDIT3:

If print jobs fail, you can test the following (thanks @ve55ev for the suggestion) – NOTE: we have not tested this.


Stay ahead in cyber

Join 1000+ other cyber professionals and get our regular updates with cyber knowledge and technical know-how.