Sooua
登录
返回文章列表
Windows 安全··4 分钟阅读

PowerShell 执行策略不是安全边界:从 Windows 实测到可审计基线

用 Windows 测试机实测 PowerShell 执行策略、日志与 Code Integrity 事件,给出从执行控制到审计闭环的工程基线。

PowerShell 执行策略不是安全边界:从 Windows 实测到可审计基线

取材:Windows 测试机 DESKTOP-HT6EO5E 实测 + Microsoft 官方文档

这篇不从“最佳实践”讲起。先看一段真实机器输出,因为 PowerShell 安全最容易被一句 RemoteSigned 讲虚。

一台测试机先把问题摊开

通过 OpenClaw 全能力 Windows Node 在 DESKTOP-HT6EO5E 上采集到的基线如下。命令只读取状态,没有改策略。

=== identity ===
desktop-ht6eo5e\sooua
DESKTOP-HT6EO5E
=== os ===
Microsoft Windows NT 10.0.19045.0
=== ps version ===
PSVersion                      5.1.19041.6456
PSEdition                      Desktop
=== execution policy ===
        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process          Bypass
  CurrentUser    RemoteSigned
 LocalMachine       Undefined
=== defender status subset ===
AMServiceEnabled          : False
AntivirusEnabled          : False
RealTimeProtectionEnabled : False
BehaviorMonitorEnabled    : False
IoavProtectionEnabled     : False
NISEnabled                : False
AntispywareEnabled        : False

这份输出挺典型:用户级是 RemoteSigned,当前进程又是 Bypass。如果只截取前半句,会误以为“机器有脚本执行策略”;如果把进程级策略也看进去,就知道这次 Agent 执行没有被 Execution Policy 拦住。

PowerShell 执行控制基线

RemoteSigned 到底挡住了什么

Microsoft 文档对 execution policy 的措辞很克制:它是 safety feature,不是限制用户动作的 security system。这个差异很重要。

Execution Policy 主要影响这些事情:

  • 是否加载 PowerShell profile;
  • 是否允许从磁盘运行脚本;
  • 脚本是否需要签名;
  • 策略在哪个 scope 生效,例如 MachinePolicy、CurrentUser、Process。

它不负责这些事情:

  • 阻止用户在命令行里直接输入逻辑;
  • 阻止进程以 -ExecutionPolicy Bypass 启动;
  • 判定脚本行为是否危险;
  • 约束子进程、网络、文件写入或凭据访问。

所以,RemoteSigned 更像门口的提示牌:能拦住误操作,拦不住拿着钥匙的人。

我会把 PowerShell 基线拆成三层

层级负责的问题典型证据
摩擦层默认能不能直接跑脚本Get-ExecutionPolicy -List
取证层跑了什么、谁跑的、上下文是什么Script Block Logging、Module Logging、Transcription、进程命令行
授权层哪些脚本/二进制本来就不该跑App Control / WDAC audit 与 enforcement

很多环境卡在第一层:把 Execution Policy 调严一点,然后认为 PowerShell 风险已经治理了。真正出事时,调查人员需要的是第二层;想减少未知执行面,靠的是第三层。

查询命令应该长这样

这些命令适合放进基线检查脚本。它们不会修复问题,只负责把当前状态说清楚。

Get-ExecutionPolicy -List
 
Get-ItemProperty `
  -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging `
  -ErrorAction SilentlyContinue
 
Get-ItemProperty `
  -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription `
  -ErrorAction SilentlyContinue
 
Get-WinEvent -LogName Microsoft-Windows-CodeIntegrity/Operational -MaxEvents 20 |
  Select-Object TimeCreated, Id, ProviderName, Message

在测试机上,Script Block Logging 和 Transcription 的策略注册表项没有读到显式配置;Code Integrity 最近事件能读到 VBS policy refresh 一类记录。这说明下一步不该是“再调一个 Execution Policy”,而是先把日志和应用控制审计补上。

App Control 应该先审计,再收紧

App Control for Business / WDAC 的 audit mode 有一个实际好处:它先告诉你哪些二进制、脚本和 MSI 会被策略拒绝。Microsoft 文档说明,二进制记录在 Microsoft-Windows-CodeIntegrity/Operational,脚本和 MSI 记录在 AppLocker 的 MSI and Script 日志。

这比拍脑袋写 allowlist 可靠。推荐流程:

部署 audit mode 策略

收集 CodeIntegrity / AppLocker 事件

按业务 owner 标注 allow / deny / exception

生成补充策略并灰度

再进入 enforcement

PowerShell 审计闭环

一份可以直接落地的检查单

  • 记录五个 ExecutionPolicy scope,不只看 CurrentUser。
  • 进程创建日志必须包含 command line、parent process、user、host、script path、hash。
  • Script Block Logging 用来回答“实际执行了什么内容”。
  • Transcription 用来回答“交互会话里发生了什么”。
  • App Control audit 用来回答“哪些东西本应被策略拒绝”。
  • 所有例外都要有 owner、过期时间和回滚路径。

这台测试机的边界

DESKTOP-HT6EO5E 是专用 Windows 测试机,当前系统为 Windows NT 10.0.19045.0 / build 19045。OpenClaw Companion 已提示这台机器不满足 MXC supported build 26300,Node Sandbox unavailable,commands run uncontained。也就是说,上面的 PowerShell 输出是宿主机无 Node Sandbox 兜底的真实状态证据,不是沙箱内执行结果。当前 Defender subset 输出为 false;这可以用于验证文章步骤、失败模式和命令证据,但不能当成生产基线示例。生产环境里,Execution Policy、PowerShell 日志、Defender、App Control 和最小权限要一起设计。

一句话收束:Execution Policy 管“别误跑”,日志管“跑了什么”,App Control 才开始接近“能不能跑”。

分享

评论

登录 后参与讨论。

加载中…

相关文章