跳转到帖子

漏洞库】Windows PrintNightmare(CVE-2021-34527)授权验证、日志留痕与修复基线

精选回复

发布于

背景

这篇记录放在漏洞库里,主要针对 Windows 打印后台处理程序漏洞 PrintNightmare(CVE-2021-34527)做一次可复现、可审计的授权验证笔记。该漏洞影响点在 Print Spooler 服务,常见风险是低权限域用户在特定配置下通过远程打印相关接口触发提权或远程代码执行。

实际内网里,很多域控、文件服务器、终端镜像都会默认启用 Spooler 服务。即使补丁打过,如果 Point and Print 策略、驱动安装权限、RPC 暴露面配置不当,仍可能留下可利用路径。因此验证时不能只看补丁号,还要看服务状态、组策略和日志行为。

以下内容仅用于授权渗透测试、蓝队自查和漏洞复核。生产环境验证前建议先在隔离测试 OU 或单台非核心主机上复现,避免对打印业务造成影响。

漏洞适用场景

  • 目标为 Windows Server 2012 R2、2016、2019 或 Windows 10/11 相关版本。
  • Print Spooler 服务处于运行状态。
  • 域环境中普通用户可访问目标的 MS-RPRN / MS-PAR RPC 接口。
  • Point and Print 或打印驱动安装策略配置宽松。
  • 补丁不完整,或补丁后未同步加固注册表与组策略。

问题定位

漏洞排查时建议按“服务是否暴露、系统是否修补、策略是否收紧、日志是否有异常”四个方向看。很多误判来自只检查 KB 补丁,而忽略了 Spooler 服务仍在域控上运行。

本地检查 Print Spooler 服务:

sc query Spooler
Get-Service Spooler | Select-Object Name,Status,StartType

# 查看服务依赖和启动配置
sc qc Spooler

远程检查目标是否暴露打印相关 RPC,授权环境下可使用 PowerShell 远程查询:

Invoke-Command -ComputerName DC01 -ScriptBlock {
    Get-Service Spooler | Select-Object Name,Status,StartType
    Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint' -ErrorAction SilentlyContinue
}

如果域控上 Spooler 为 Running,就需要重点关注。域控通常没有打印业务需求,建议默认关闭。

技术分析

PrintNightmare 的核心问题在于 Windows Print Spooler 对打印驱动加载、远程接口调用和权限边界处理不当。攻击链通常不是单点触发,而是由以下条件组合而成:

  • 远程用户可以调用打印后台相关 RPC 接口。
  • 目标允许从非受信路径安装或更新打印驱动。
  • 驱动安装过程可能以高权限上下文加载恶意 DLL。
  • 域内普通账号具备基本认证能力,可访问目标 IPC/RPC 服务。

蓝队侧判断风险时,不建议只问“能不能 RCE”,而要确认目标是否允许非管理员安装打印驱动。以下注册表项是排查重点:

配置项路径建议值
NoWarningNoElevationOnInstallHKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint0 或不存在
UpdatePromptSettingsHKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint0 或不存在
RestrictDriverInstallationToAdministratorsHKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint1

如果 NoWarningNoElevationOnInstall 为 1,或 UpdatePromptSettings 为 1,通常意味着安装/更新驱动时对普通用户提示和提权限制较弱,需要按高风险处理。

操作步骤:授权验证流程

下面给一套偏蓝队复核的验证流程,不包含恶意载荷投递,只验证暴露面和配置风险。

1. 确认系统补丁状态

wmic qfe get HotFixID,InstalledOn | findstr /i "KB5004945 KB5004237 KB5004245 KB5004296"

# PowerShell 方式
Get-HotFix | Where-Object {$_.HotFixID -match 'KB5004945|KB5004237|KB5004245|KB5004296'} | Select HotFixID,InstalledOn

不同 Windows 版本对应 KB 不完全一样,建议结合 Microsoft 官方安全更新指南按系统版本确认。没有对应补丁不代表一定可利用,但应直接列为待修复项。

2. 检查 Spooler 服务是否运行

Get-Service Spooler | Format-List Name,DisplayName,Status,StartType

# 域内批量检查示例
$servers = Get-Content .\servers.txt
foreach ($s in $servers) {
    try {
        $svc = Get-Service -ComputerName $s -Name Spooler -ErrorAction Stop
        [PSCustomObject]@{
            Host = $s
            Status = $svc.Status
            StartType = $svc.StartType
        }
    } catch {
        [PSCustomObject]@{
            Host = $s
            Status = 'QueryFailed'
            StartType = '-'
        }
    }
}

重点关注域控、AD CS、Exchange、文件服务器、运维跳板机。对这些资产来说,Spooler 运行通常不是必要条件。

3. 检查 Point and Print 策略

$path = 'HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint'
Get-ItemProperty -Path $path -ErrorAction SilentlyContinue | Select-Object \
NoWarningNoElevationOnInstall,UpdatePromptSettings,RestrictDriverInstallationToAdministrators

若路径不存在,不一定是风险,需要结合默认策略和系统补丁判断。若存在且值配置宽松,应优先修复。

4. 检查打印相关日志

默认情况下,部分打印服务操作日志可能未启用。建议在验证窗口临时开启 PrintService Operational 日志,用于观察异常驱动安装和远程调用行为。

# 启用打印服务操作日志
wevtutil sl Microsoft-Windows-PrintService/Operational /e:true

# 查看最近 50 条打印服务日志
Get-WinEvent -LogName 'Microsoft-Windows-PrintService/Operational' -MaxEvents 50 |
Select-Object TimeCreated,Id,ProviderName,Message

常见关注事件:

  • Event ID 316:打印机驱动相关操作。
  • Event ID 808:打印机驱动安装失败或异常。
  • Event ID 842:驱动包安装相关记录。
  • Security 4624:远程认证登录,关注 LogonType 3。
  • Security 4672:特殊权限登录,若与异常打印操作时间接近需重点排查。

按时间线关联日志更有价值,例如先出现普通域账号的 4624 网络登录,随后出现 PrintService 驱动安装事件,再出现异常服务创建或进程启动,就需要作为疑似利用链处理。

5. 进程与文件落点排查

Print Spooler 相关进程为 spoolsv.exe,正常路径应为:

C:\Windows\System32\spoolsv.exe

驱动文件常见目录:

C:\Windows\System32\spool\drivers\x64\
C:\Windows\System32\spool\drivers\W32X86\

排查最近变更的驱动文件:

Get-ChildItem 'C:\Windows\System32\spool\drivers\x64' -Recurse -ErrorAction SilentlyContinue |
Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} |
Select-Object FullName,Length,LastWriteTime

如果发现新写入的 DLL、GPD、PPD 或异常命名文件,应结合签名和哈希进一步确认:

Get-AuthenticodeSignature 'C:\Windows\System32\spool\drivers\x64\3\example.dll'
Get-FileHash 'C:\Windows\System32\spool\drivers\x64\3\example.dll' -Algorithm SHA256

风险判断

可以按下面标准给漏洞风险分级,方便进漏洞库或内网整改台账:

风险等级判断条件处置优先级
高域控或核心服务器开启 Spooler,且 Point and Print 配置宽松或补丁缺失立即修复
中普通服务器开启 Spooler,补丁状态不明确,但策略已收紧限期整改
低终端开启 Spooler,补丁完整,驱动安装限制为管理员持续监控
已缓解非打印服务器关闭 Spooler,补丁完整,策略收紧纳入基线

修复建议

修复时建议先处理域控和核心服务器,再处理普通成员服务器,最后覆盖终端。

1. 非打印服务器关闭 Spooler

Stop-Service Spooler -Force
Set-Service Spooler -StartupType Disabled

# 或使用 sc
sc stop Spooler
sc config Spooler start= disabled

域控上建议默认禁用。关闭前确认是否存在老旧应用依赖打印队列或报表打印功能。

2. 限制普通用户安装打印驱动

reg add "HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" /v NoWarningNoElevationOnInstall /t REG_DWORD /d 0 /f
reg add "HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" /v UpdatePromptSettings /t REG_DWORD /d 0 /f
reg add "HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" /v RestrictDriverInstallationToAdministrators /t REG_DWORD /d 1 /f

域环境建议通过 GPO 下发,不建议单机手工改完就结束。GPO 路径可参考:

Computer Configuration
  - Administrative Templates
    - Printers
      - Point and Print Restrictions
      - Package Point and Print - Approved servers

3. 限制 RPC 暴露面

如果业务允许,可通过防火墙限制 445、135 及动态 RPC 端口访问范围,只允许管理网段或打印服务器访问。不要在办公网大平面直接暴露域控 RPC。

# 示例:仅允许管理网段访问 SMB,实际网段按现场调整
New-NetFirewallRule -DisplayName "Allow SMB From AdminNet" -Direction Inbound -Protocol TCP -LocalPort 445 -RemoteAddress 10.10.10.0/24 -Action Allow
New-NetFirewallRule -DisplayName "Block SMB From Others" -Direction Inbound -Protocol TCP -LocalPort 445 -Action Block

4. 日志监控规则建议

建议至少监控以下行为:

  • 域控上 Spooler 服务被启动。
  • spoolsv.exe 产生异常子进程,例如 cmd.exe、powershell.exe、rundll32.exe。
  • spool 目录下短时间新增 DLL 文件。
  • 普通域账号对多台服务器产生打印服务相关访问。
  • PrintService Operational 中出现异常驱动安装事件。

如果部署了 Sysmon,可关注 Event ID 1、7、11。一个简单的排查方向是看 spoolsv.exe 是否创建了不该出现的子进程:

Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1; StartTime=(Get-Date).AddDays(-3)} |
Where-Object {$_.Message -match 'ParentImage.*spoolsv.exe'} |
Select-Object TimeCreated,Message

复测标准

  • 域控和非打印核心服务器上 Spooler 服务为 Disabled。
  • 普通用户无法安装或更新打印驱动。
  • Point and Print 相关危险配置不存在或为安全值。
  • 系统补丁符合当前 Windows 版本要求。
  • PrintService 日志和安全日志中无异常驱动安装痕迹。
  • EDR/Sysmon 未发现 spoolsv.exe 异常拉起命令解释器或脚本解释器。

总结

PrintNightmare 这类漏洞在内网里不能只按 CVE 补丁扫描结果判断。更稳妥的做法是把 Spooler 服务状态、Point and Print 策略、RPC 暴露面、日志留痕一起纳入验证。特别是域控,只要没有明确打印需求,关闭 Spooler 是最直接有效的缓解措施。

漏洞库记录建议保留三类证据:配置截图或命令输出、关键日志事件、修复后复测结果。这样后续复盘和审计时能说明漏洞是否真实存在、影响边界在哪里、整改是否闭环。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意

这个漏洞建议别只看“是否打补丁”,还要把 Spooler 暴露面和 Point and Print 策略一起核掉。实际排查时我一般按下面几项做基线检查:

  • 域控优先:域控上如果没有明确打印需求,直接停用 Print Spooler,PrintNightmare 当年最危险的就是域控侧可被低权限用户打到高权限。
  • 补丁状态:确认系统已安装 2021-07 之后相关累积更新,老系统尤其要单独核 KB。
  • Point and Print:确认普通用户不能静默安装/更新打印驱动。
  • 驱动安装权限:限制非管理员安装打印驱动,避免“修了补丁但策略放开”的情况。

可以用下面的 PowerShell 快速拉一遍关键配置:

Get-Service Spooler | Select-Object Name,Status,StartType

Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" -ErrorAction SilentlyContinue |
Select-Object RestrictDriverInstallationToAdministrators,
              NoWarningNoElevationOnInstall,
              UpdatePromptSettings,
              TrustedServers,
              ServerList

Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Print" -ErrorAction SilentlyContinue |
Select-Object RpcAuthnLevelPrivacyEnabled

比较稳妥的修复基线可以参考:

# 非打印服务器 / 域控建议直接禁用
Stop-Service Spooler -Force
Set-Service Spooler -StartupType Disabled

# 如果必须保留打印服务,至少强制限制驱动安装
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" -Force | Out-Null

New-ItemProperty `
  -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" `
  -Name "RestrictDriverInstallationToAdministrators" `
  -PropertyType DWord `
  -Value 1 `
  -Force

New-ItemProperty `
  -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" `
  -Name "NoWarningNoElevationOnInstall" `
  -PropertyType DWord `
  -Value 0 `
  -Force

New-ItemProperty `
  -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" `
  -Name "UpdatePromptSettings" `
  -PropertyType DWord `
  -Value 0 `
  -Force

日志留痕这块建议重点看三个位置:

  • Microsoft-Windows-PrintService/Admin
  • Microsoft-Windows-PrintService/Operational,默认可能没开
  • Security,配合 4688 进程创建和对象访问审计

先把 PrintService Operational 打开:

wevtutil sl Microsoft-Windows-PrintService/Operational /e:true
wevtutil sl Microsoft-Windows-PrintService/Admin /e:true

排查可疑驱动安装和 Spooler 异常加载,可以重点搜这些路径和行为:

# 近 7 天打印服务相关事件
Get-WinEvent -FilterHashtable @{
  LogName = "Microsoft-Windows-PrintService/Operational"
  StartTime = (Get-Date).AddDays(-7)
} | Where-Object {
  $_.Message -match "driver|驱动|install|安装|spool|DLL"
} | Select-Object TimeCreated,Id,ProviderName,Message

# 可疑 spool 驱动目录文件变更
Get-ChildItem "C:\Windows\System32\spool\drivers" -Recurse -ErrorAction SilentlyContinue |
Where-Object {
  $_.LastWriteTime -gt (Get-Date).AddDays(-7) -and
  $_.Extension -in ".dll",".dat",".tmp"
} | Select-Object FullName,Length,LastWriteTime

如果环境有 Sysmon,建议补一条检测:关注 spoolsv.exe 加载非系统默认打印驱动目录下新出现的 DLL,尤其是 spool\drivers\x64\3\、spool\drivers\W32X86\3\。典型规则思路:

Image = C:\Windows\System32\spoolsv.exe
EventID = 7
ImageLoaded contains \Windows\System32\spool\drivers\
ImageLoaded endswith .dll

另外可以结合文件创建:

EventID = 11
TargetFilename contains \Windows\System32\spool\drivers\
TargetFilename endswith .dll

如果已经怀疑被打过,不建议只删除 DLL。要同时做:

  • 导出并核对已安装打印驱动:Get-PrinterDriver
  • 检查异常驱动对应文件路径、签名、时间戳
  • 检查 spoolsv.exe 是否有异常网络连接
  • 回溯同时间段的 4624、4672、4688,尤其是普通域用户到域控或打印服务器的登录行为
Get-PrinterDriver | Select-Object Name,Manufacturer,DriverVersion,InfPath

Get-Process spoolsv -ErrorAction SilentlyContinue | Select-Object Id,Path,StartTime

Get-NetTCPConnection -OwningProcess (Get-Process spoolsv).Id -ErrorAction SilentlyContinue |
Select-Object LocalAddress,LocalPort,RemoteAddress,RemotePort,State

个人经验是:PrintNightmare 的治理重点不只是补 CVE,而是把“普通用户可下发打印驱动”这条链路彻底收掉。域控禁 Spooler、打印服务器单独分区管理、Point and Print 白名单化,基本能把风险压下去。

补充一点:授权验证最好不要只看注册表值,建议结合“策略生效结果 + 普通用户实际行为 + 日志”做闭环。尤其是域环境里,OU 级 GPO、计算机本地策略和旧的 Point and Print 配置可能互相覆盖。

先确认最终生效的策略,而不是只读某个注册表路径:

gpresult /h C:\Temp\gp.html /scope computer
gpresult /r /scope computer

reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" /s
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers" /s

重点核对以下配置是否符合预期:

  • RestrictDriverInstallationToAdministrators=1:限制只有管理员可以安装打印驱动。
  • NoWarningNoElevationOnInstall:不应允许普通用户绕过提示或提权安装驱动。
  • UpdatePromptSettings:驱动更新也不应对普通用户静默放行。

不要直接修改注册表后就认为修复完成,建议使用一个普通域用户在测试 OU 中验证:连接一台测试打印机、更新已有驱动、删除后重新添加打印机,均应触发管理员凭据或被策略拒绝。测试应使用受控打印机和非生产驱动,避免把“验证”变成实际利用。

日志方面,可以先打开 PrintService Operational,并将进程创建审计纳入基线:

wevtutil sl Microsoft-Windows-PrintService/Operational /e:true

auditpol /set /subcategory:"Process Creation" /success:enable

# 如果使用组策略,建议同时启用“在进程创建事件中包含命令行”
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" `
  /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f

排查时不要只盯着某一个事件号,可以按时间、账户和进程链关联查看:

$since = (Get-Date).AddDays(-7)

Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-PrintService/Operational'
    StartTime = $since
} | Select-Object TimeCreated, Id, LevelDisplayName, ProviderName, Message

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4688
    StartTime = $since
} | Where-Object {
    $_.Message -match 'spoolsv\.exe|rundll32\.exe|regsvr32\.exe|PrintIsolationHost\.exe'
} | Select-Object TimeCreated, Id, Message

重点关注非预期账户触发的驱动安装或更新、spoolsv.exe 派生出异常子进程,以及打印服务重启、服务配置变更等行为。若部署了 Sysmon,建议额外关注 Image 为 spoolsv.exe 的进程创建事件和网络连接事件。

另外建议把打印驱动目录的写权限作为一次性检查项,避免 ACL 被其他软件或历史脚本放宽:

icacls "$env:windir\System32\spool\drivers"
icacls "$env:windir\System32\spool\PRINTERS"

这里不建议直接用脚本强制重置 ACL,应先保存当前权限并确认是否存在 Users、Everyone 等主体的写入或修改权限。修复基线最终可以记录为:系统累积更新版本、最终生效的 GPO、Spooler 服务状态、普通用户测试结果,以及最近一段时间的打印服务审计结果。这样比单独记录“已安装某个 KB”更容易在复核时发现配置回退。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。