Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save FriedrichWeinmann/8521a87074e32690383d369f3cb9f737 to your computer and use it in GitHub Desktop.
Save FriedrichWeinmann/8521a87074e32690383d369f3cb9f737 to your computer and use it in GitHub Desktop.
function Test-PrintNightmareVulnerability {
<#
.SYNOPSIS
Tests whether the target system is vulnerable to the PrintNightmare vulnerability.
.DESCRIPTION
Tests whether the target system is vulnerable to the PrintNightmare vulnerability.
Uses PowerShell remoting.
This checks whether vulnerable GPO/registry settings are applied.
It does NOT verify the also required security update being installed!
Specifically checked:
- Is vulnerable prompt-behavior defined?
- Point and Print Servers restricted?
- Spooler Service state
Computers are considered vulnerable when:
- Vulnerable prompt-behavior defined
- Point and Print Servers not constrained
- Spooler service is enabled
For more details, see:
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34527
https://support.microsoft.com/en-us/topic/kb5005010-restricting-installation-of-new-printer-drivers-after-applying-the-july-6-2021-updates-31b91c02-05bc-4ada-a7ea-183b129578a7
.PARAMETER ComputerName
The computers to scan.
.PARAMETER Credential
Credentials to use.
.EXAMPLE
PS C:\> Test-PrintNightmareVulnerability
Checks whether the local computer is vulnerable.
.EXAMPLE
PS C:\> Test-PrintNightmareVulnerability -ComputerName (Get-ADComputer -Filter *).DNSHostName
Checks all computers in the current Active Directory domain whether they are vulnerable.
Keep in mind, that this will NOT check for the installed update, that is also necessary to be protected!
#>
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true)]
[string[]]
$ComputerName,
[pscredential]
$Credential
)
begin {
[string[]]$defaultDisplaySet = 'ComputerName', 'Vulnerable', 'Error'
$defaultDisplayPropertySet = [System.Management.Automation.PSPropertySet]::new(‘DefaultDisplayPropertySet’, $defaultDisplaySet)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
}
process {
$param = @{
ErrorAction = 'SilentlyContinue'
ErrorVariable = 'failed'
}
if ($ComputerName) {
$param.ComputerName = $ComputerName
$param.HideComputerName = $true
}
if ($Credential) { $param.Credential = $Credential }
Invoke-Command @param -ScriptBlock {
$key = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint' -ErrorAction Ignore
$service = Get-Service -Name Spooler
$vulnerable = (
($key.NoWarningNoElevationOnInstall -or $key.UpdatePromptSettings) -and
-not ($key.ServerList -and $key.TrustedServers) -and
$service.StartType -match 'Automatic'
)
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
Vulnerable = $vulnerable
SpoolerStatus = $service.Status
SpoolerStartType = $service.StartType
Restricted = $key.Restricted -as [bool]
TrustedServersEnabled = $key.TrustedServers -as [bool]
TrustedServers = $key.ServerList
NoWarningNoElevationOnInstall = $key.NoWarningNoElevationOnInstall
UpdatePromptSettings = $key.UpdatePromptSettings
Error = $null
}
} | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers -PassThru
$failedObjects = foreach ($failure in $failed) {
[PSCustomObject]@{
ComputerName = $failure.TargetObject
Vulnerable = $null
Restricted = $null
TrustedServersEnabled = $null
TrustedServers = $null
NoWarningNoElevationOnInstall = $null
UpdatePromptSettings = $null
Error = $failure
}
}
$failedObjects | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers -PassThru
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment