4104 记录什么
4104 事件位于 PowerShell/Operational 通道,在启用脚本块日志(ScriptBlockLogging)后记录脚本块的实际内容,包括被编码或混淆之前或之后的代码,是无文件攻击取证最有价值的一类日志。
前提与边界
4104 属于「事前准备型」证据:策略未启用就完全没有记录,事后无法补录。姊妹事件中 4103 记录模块与管道执行,400、600 记录引擎启动与提供程序加载,用它们可以补出执行时间线。
基本信息
| 事件 | 4104 脚本块日志(PowerShell/Operational 通道) |
|---|---|
| 姊妹事件 | 4103 模块日志、400 引擎启动、600 提供程序加载 |
| 启用方式 | 组策略或注册表开启 ScriptBlockLogging |
| 用途 | 还原混淆与无文件攻击的实际代码 |
| 记录范围 | 由策略决定,可能只记录可疑脚本块 |
| 权限要求 | 读取该通道通常需管理员 |
典型使用场景
- 还原 -EncodedCommand 编码命令的原始逻辑
- 确认攻击者执行过的下载与横向移动命令
- 判断主机是否被用于无文件落地攻击
- 与其他事件对照,重建命令执行时间线
- 事后核查该策略是否启用并提出补齐建议
查询脚本块与检查策略
查询脚本块与检查策略
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 200 -ErrorAction SilentlyContinue |
Where-Object { $_.Id -eq 4104 } | Select-Object -First 10 TimeCreated, Message | Format-List
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -ErrorAction SilentlyContinue
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 50 -ErrorAction SilentlyContinue | Group-Object Id | Select-Object Name, Count
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 50 | Select-Object TimeCreated, @{n='Len';e={$_.Message.Length}}输出逐列读法
| 字段 | 含义 | 正常/异常 |
|---|---|---|
| Event Id | 事件编号 | 4104 为脚本块,4103 为模块日志 |
| Message | 脚本块内容 | 出现下载、编码、凭据相关代码需立即跟进 |
| ScriptBlock ID | 脚本块唯一标识 | 用同一 ID 串联同一段代码的多次执行 |
| 记录范围 | 策略决定的内容粒度 | 只记录可疑块时可能缺少上下文 |
没启用策略就查不到 4104:此时只能靠 4688、命令行审计、PowerShell 转录文件或 EDR 记录回推,判断「查不到」的原因比直接下结论更重要。
终端直接读取超长 Message 容易被截断:先导出成文件再分析,保证脚本块内容完整。另注意脚本块可能含明文凭据,按敏感证据管理。
导出后检索关键字
导出后检索关键字
$ev = Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 200 -ErrorAction SilentlyContinue | Where-Object Id -eq 4104
$ev | ForEach-Object { $_.TimeCreated.ToString('s') + ' ' + $_.Message } | Out-File C:\evidence\ps_4104.txt -Encoding UTF8
Select-String -Path C:\evidence\ps_4104.txt -Pattern 'DownloadString|IEX|FromBase64|New-Object Net' | Select-Object -First 20与其他日志配合
- 4688 进程创建:确认 powershell.exe 的父进程与命令行
- 4672 特权分配:确认脚本执行时是否已是高权限
- 安全软件的检测记录:补充被拦截的脚本块内容