Skip to content

Windows: reduce false positives on Suspicious PowerShell (AMSI Bypass) rule#2311

Open
rvald26 wants to merge 1 commit into
v11from
feature/powershell-amsi-bypass-fp-tuning
Open

Windows: reduce false positives on Suspicious PowerShell (AMSI Bypass) rule#2311
rvald26 wants to merge 1 commit into
v11from
feature/powershell-amsi-bypass-fp-tuning

Conversation

@rvald26

@rvald26 rvald26 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Reduces false positives on rules/windows/suspicious_powershell_obfuscation.yml — "Windows: Suspicious PowerShell (Encoded / Download Cradle / AMSI Bypass)" (event 4104, T1059.001). One line of detection logic changed; all attack coverage preserved.

Problem

The rule fired on every PowerShell session on affected hosts. Because the rule uses groupBy: [dataSource], the hits collapsed into a single HIGH alert that accumulated thousands of echoes — drowning out real detections.

Root cause

The first regex branch matches the token amsiinitfailed. The benign, injected defensive PSBreakpoint/AMSI "sentinel" instrumentation harness (the <#sentinelbreakpoints#> / Set-PSBreakpoint … out-file ':::::\windows\sentinel\N' canary tool) is loaded into essentially every PowerShell session and contains the literal string AmsiInitFailed (e.g. Remove-Variable AmsiInitFailed). That single token tripped the rule on every session.

Fix

Add a per-script-block exclusion for the harness's unique fingerprints, ANDed ahead of the detection logic:

&& !regexMatch("log.eventDataScriptBlockText",
     "(?i)(sentinelbreakpoints|windows.sentinel.[0-9]|po_wer_spl_oit_indicators)")
  • The three markers (<#sentinelbreakpoints#> comment tag, the \windows\sentinel\N canary path, the $Po_wer_Spl_oit_Indicators array) are unique to this defensive harness and do not appear in real malware.
  • The exclusion is per-script-block. PowerShell logs each script block as its own 4104 event, so if an attacker actually runs Invoke-Mimikatz through the harness, that malicious script block is a separate 4104 event and still fires.
  • No attack tokens were removed — AMSI-tamper, reflective-loading, mimikatz/shellcode/dll-injection, and download-cradle+exec detection are unchanged.

Validation

  • Regex logic tested (Go RE2-compatible) against the actual harness text plus real payloads: the harness no longer matches, while the real download cradle (iex ((New-Object Net.WebClient).DownloadString(...))), the classic AMSI amsiInitFailed SetValue bypass, Invoke-Mimikatz, a reflective shellcode loader, and IWR+IEX cradles all still match. Benign scripts (IWR download without exec, bare -enc without a cradle) remain silent.
  • Deployed and validated on a live v11 instance (server accepted the definition; verified firing behavior on real telemetry).

🤖 Generated with Claude Code

…Shell rule

The 'Suspicious PowerShell (Encoded / Download Cradle / AMSI Bypass)' rule (4104
script block) fired on every PowerShell session: the injected defensive
PSBreakpoint/AMSI 'sentinel' instrumentation harness contains the literal token
'AmsiInitFailed', which matches the first regex branch. With groupBy:[dataSource]
this collapsed into a single alert with thousands of echoes.

Add a per-script-block exclusion for the harness's unique markers
(sentinelbreakpoints, \windows\sentinel\, Po_wer_Spl_oit_Indicators). All
attack tokens are preserved; a real payload run through the harness is a separate
4104 event that still fires.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rvald26 rvald26 requested a review from a team July 1, 2026 20:26
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

❌ Go dependencies check failed

There are outdated Go dependencies, or modules that could not be inspected.
Run bash .github/scripts/go-deps.sh --update --discover locally and
commit the updated go.mod / go.sum files.

Script output
🔍 Discovered 25 Go projects

📦 Dependencies with updates available:

  📁 ./agent:
     - github.com/elastic/go-sysinfo: v1.15.4 → v1.15.5
     - google.golang.org/grpc: v1.81.1 → v1.82.0
     - gorm.io/gorm: v1.31.1 → v1.31.2

  📁 ./as400:
     - github.com/elastic/go-sysinfo: v1.15.4 → v1.15.5
     - google.golang.org/grpc: v1.81.1 → v1.82.0
     - gorm.io/gorm: v1.31.1 → v1.31.2

  📁 ./utmstack-collector:
     - github.com/elastic/go-sysinfo: v1.15.4 → v1.15.5
     - google.golang.org/grpc: v1.81.1 → v1.82.0
     - gorm.io/gorm: v1.31.1 → v1.31.2

  📁 ./installer:
     - github.com/cloudfoundry/gosigar: v1.3.121 → v1.3.122

  📁 ./plugins/inputs:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/sophos:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/gcp:
     - google.golang.org/api: v0.285.0 → v0.287.0
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/crowdstrike:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/bitdefender:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/azure:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/modules-config:
     - github.com/aws/aws-sdk-go-v2/config: v1.32.25 → v1.32.27
     - github.com/aws/aws-sdk-go-v2/credentials: v1.19.24 → v1.19.26
     - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs: v1.77.0 → v1.78.2
     - github.com/aws/aws-sdk-go-v2/service/sts: v1.43.3 → v1.43.5
     - google.golang.org/api: v0.285.0 → v0.287.0
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/aws:
     - github.com/aws/aws-sdk-go-v2: v1.42.0 → v1.42.1
     - github.com/aws/aws-sdk-go-v2/config: v1.32.25 → v1.32.27
     - github.com/aws/aws-sdk-go-v2/credentials: v1.19.24 → v1.19.26
     - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs: v1.77.0 → v1.78.2
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./plugins/o365:
     - google.golang.org/grpc: v1.81.1 → v1.82.0

  📁 ./agent-manager:
     - google.golang.org/grpc: v1.81.1 → v1.82.0
     - gorm.io/gorm: v1.31.1 → v1.31.2

�[0;31m❌ Please update dependencies before merging.�[0m

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

✅ AI review — Approved

No issues detected in this diff.

architecture (gemini-3-flash-lite) — clean

Summary: No reviewable changes in this diff (excluded paths only).

No findings.

bugs (gemini-3-flash-lite) — clean

Summary: No reviewable changes in this diff (excluded paths only).

No findings.

security (gemini-3-flash-lite) — clean

Summary: No reviewable changes in this diff (excluded paths only).

No findings.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

⛔ Permission denied

Only members of @utmstack/administrators or @utmstack/core-developers can merge PRs into this repository.

PR author: @rvald26

The comments above (deps + AI review) are still valid — if you address them, the checks will re-run automatically, but final approval is left to an administrator.

@utmstack/administrators please review.

@utmstackprapprover utmstackprapprover Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Author is not in @utmstack/administrators nor @utmstack/core-developers — admin review required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant