Windows自带certutil和PowerShell Get-FileHash可实现自动化文件完整性校验:首次生成SHA256基准清单(baseline.csv),后续比对并记录告警;certutil适用于关键系统文件轻量校验,需管理员权限、硬编码预期哈希、添加时间戳及响应机制,并注意排除WinSxS等更新目录、规避占用文件、保护清单文件。

不需要装额外工具,Windows 自带的 certutil 和 PowerShell 的 Get-FileHash 就能完成自动化校验。关键在于把“比对逻辑”和“定期执行”两部分搭起来,而不是每次手动敲命令。
用 PowerShell 脚本批量记录并比对哈希值
推荐用 PowerShell,语法清晰、权限可控、输出易解析。一个典型流程是:首次运行时生成基准哈希清单(.csv 或 .json),后续运行时读取清单并逐个校验。
- 首次生成哈希清单(保存为
baseline.csv):
Get-ChildItem "C:\Windows\System32\*.dll" -Force | ForEach-Object {
$hash = Get-FileHash $_.FullName -Algorithm SHA256
[PSCustomObject]@{Path=$_.FullName; SHA256=$hash.Hash; LastWriteTime=$_.LastWriteTime} } | Export-Csv baseline.csv -NoTypeInformation
- 后续校验脚本(
verify.ps1)会读取该文件,对每个路径重新计算 SHA256,并对比是否一致;不一致时记录到alerts.log并可触发邮件或弹窗提醒。 - 注意:系统目录如
System32下部分文件需管理员权限才能读取,脚本应以管理员身份运行。
用 certutil 实现轻量级定时校验
如果只盯几个关键文件(比如 net.exe、cmd.exe、lsass.exe),certutil 更轻快,且无需 PowerShell 执行策略调整。
- 写一个批处理(
check.bat):
@echo off
set EXPECTED_NET=a1b2c3d4...
for /f "tokens=2" %%i in ('certutil -hashfile "%windir%\System32\net.exe" SHA256 ^| findstr ":"') do set ACTUAL_NET=%%i
if not "%EXPECTED_NET%"=="%ACTUAL_NET%" echo [ALERT] net.exe changed at %date% %time% >> check_alert.log
- 把多个类似判断合并进去,再用 Windows 任务计划程序每天凌晨执行一次即可。
- 哈希值建议从干净系统中提前提取并硬编码,避免清单文件本身被篡改影响判断。
加入时间戳与变更响应机制
光知道“变了”不够,得知道“什么时候变的”以及“怎么响应”。
- 每次校验结果都追加时间戳写入日志,方便回溯;可用
Get-Date -Format "yyyy-MM-dd HH:mm:ss"插入。 - 发现异常时,脚本能自动调用
takeown+icacls检查文件权限,或用tasklist /m filename.dll查看是否被进程加载,辅助判断是否恶意替换。 - 若配合 SIEM 或本地日志转发,还可将告警推送到企业安全平台。
注意事项与避坑点
实际部署中容易忽略几个细节,导致误报或漏报:
- 系统更新后,合法的 DLL 或 EXE 文件哈希会自然变化——建议排除
Windows Update高频更新目录(如WinSxS子路径),或在校验前先检查wmic qfe list确认近期是否有补丁安装。 - 不要校验正在被占用的文件(如
lsass.exe),否则Get-FileHash可能失败;可改用certutil,它对锁住的系统文件兼容性更好。 - 哈希清单文件本身要设为只读+隐藏属性,或存放在受保护路径(如
%SystemRoot%\System32\config),防止被覆盖或删除。

















