无文件攻击的取证入口
PowerShell 常被用于无文件攻击:命令可以在内存中直接执行,磁盘上没有可查杀的样本。开启脚本块日志(Script Block Logging)后,被执行的脚本文本会记录为事件 4104,包含编码命令解码后的内容,这正是洞察混淆脚本的关键。配合模块日志记录与脚本执行日志,能形成从“写了什么代码”到“触发了哪些管道”的证据链。策略通过组策略或注册表下发,核查要同时看策略与事件日志两侧。
基本信息
| 加固项 | 脚本执行审计 |
|---|---|
| 适用平台 | Windows 10/11、Windows Server(PowerShell 3.0 及以上) |
| 权限要求 | 本地管理员或域管理员 |
| 达标判据 | 脚本块日志已开启,事件日志中能看到 4104 记录 |
| 日志位置 | Microsoft-Windows-PowerShell/Operational |
典型使用场景
- 等保与 CIS 核查“安全审计”中对脚本执行的记录要求
- 应急响应中还原混淆脚本的原始内容
- 排查横向移动时确认哪个账号在哪台机器上执行过脚本
- 审计运维自动化脚本的实际执行情况
- 建立终端脚本行为基线,发现异常执行模式
策略与日志核查
策略与日志核查
# GPO 路径:计算机配置 → 管理模板 → Windows 组件 → Windows PowerShell
# 打开“PowerShell 脚本块日志记录”;可选“模块日志记录”“脚本执行日志”
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -ErrorAction SilentlyContinue
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -ErrorAction SilentlyContinue
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 5 | Select-Object TimeCreated, Id查询脚本块记录
查询脚本块记录
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -FilterXPath "*[System[(EventID=4104)]]" -MaxEvents 10 | Select-Object TimeCreated, Message
# 只筛包含可疑关键词的记录
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' | Where-Object {$_.Id -eq 4104 -and $_.Message -match 'FromBase64String|DownloadString|IEX'} | Select-Object -First 5 TimeCreated, Message
wevtutil gl 'Microsoft-Windows-PowerShell/Operational' | Select-String 'maxSize' # 确认日志容量相关事件与作用
| 事件 ID | 日志 | 含义 |
|---|---|---|
| 4104 | PowerShell/Operational | 脚本块内容,含解码后的明文 |
| 4103 | PowerShell/Operational | 模块日志:记录命令与参数 |
| 400 / 600 | PowerShell/Operational | 引擎启动与停止,辅助判断执行会话 |
| 800 | PowerShell/Operational | 管道执行详情,需单独开启 |
| 4103 与 4104 组合 | 同一日志 | 拼出“谁在何时执行了什么” |
4104 记录的是脚本块原文,攻击者常用编码或字符串拼接规避文本匹配,而这里保存的是解码后的内容,因此取证价值高于命令行历史。查询时用关键词(下载、反射加载、编码解码函数名)过滤,比逐条浏览效率高得多,也便于写进自动化巡检脚本。
未启用时 Operational 日志几乎为空,此时“查不到记录”并不代表“没有执行过”,而是审计没开——务必先查注册表策略再下结论。开启后日志量增长较快,需要把日志容量(maxSize)与集中转发(事件转发或 SIEM)一并规划,否则关键记录会被覆盖。