Band-Aid PrintNightmare Zero-Day Exploit on Domain Controllers

This is an exploit that affects domain controllers. In a nutshell, if you have the “Print Spooler” service enabled (which is the default), any remote authenticated user can execute code as SYSTEM on the domain controller. More detail in this article:

This worklet disables the print spooler service on domain controllers and disables it from running at startup. You can run it against any group that contains domain controllers and it will only target the DCs.

Note: More information has come out that this might affect all servers - not just DCs. I modified my original evaluation with the option of checking all servers (not just DCs). If you want to run this against all servers, just remark out the first If…Statement and un-remark the second one.

Evaluation:

$svcName = "Spooler"
$svcRunning = Get-Service -Name $svcName

# Used for the domain controller check
$dc = Get-ADDomainController

# Used for the server check
$compConfig = Get-WmiObject -Class Win32_ComputerSystem
$role = $compConfig.DomainRole
$serverRole = @(2,3,4,5) # 2 = Standalone Server, 3 = Member Server, 4 = Backup DC, 5 = Primary Domain Controller

# Check if system is a domain controller (or server) and if the Print Spooler service is running.  If so, exit 1 to remediate.

### Use this If statement if you only want to check domain controllers ###
If ($dc) {

### Remark out the above If statement and un-remark this one if you want to check all servers ###
# If ($role -in $serverRole) {

  If ($svcRunning.Status -eq 'Running') {
    Exit 1
  }
}
Exit 0

Remediation:

$svcName = "Spooler"

# Stop the Print Spooler service and disable it from running at system startup
Stop-Service -Name $svcName
Set-Service -Name $svcName -StartupType Disabled
5 Likes

Nice Write-up @Tony ! It is worth noting that current information suggests this attack can take place on anything that uses the Printer Spooler service. In the evaluation script, I just commented out the DC part and am running it against our server groups currently.

Thanks @Mrichards. I’m starting to see that too. I tweaked the evaluation code so that users can go with the default of just checking DCs, or they can use the alternative If statement to check all servers. I don’t know that my method for checking all servers with roles is the best, but I think it will work fine.

Is there a worklet to reverse this ?

It should just be a matter of changing this in evaluation:

If ($svcRunning.Status -eq ‘Running’) {
to
If ($svcRunning.Status -eq ‘Stopped’) {

and changing this in remediation:

Stop-Service -Name $svcName
Set-Service -Name $svcName -StartupType Disabled
to
Start-Service -Name $svcName
Set-Service -Name $svcName -StartupType Automatic