fix(crowdstrike): keep command lines intact and repair rule conditions and grouping - #2744
Merged
osmontero merged 6 commits intoSep 25, 2026
Merged
Conversation
The two trim steps that removed a double quote from the start and from the
end of log.eventCommandLine each strip one quote after trimming spaces
(EventProcessor plugins/trim). A Windows command line that starts with a
quoted program path or ends with a quoted argument therefore lost one quote
of a pair and was stored with unbalanced quotes. The stored text no longer
matched what ran, and three rules group alerts by it. The parent and
grandparent command lines were never trimmed.
Only these two steps are removed. The '[{' and '}]' trims stay, and they
still remove surrounding spaces. No retained real record carries a command
line, so the proof uses fabricated detection records.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
log.event.Attributes.trace_id, log.event.ServiceName and log.event.Message were each renamed twice to the same target. The first rename moves the value and no step in between recreates the source, so the second one never finds anything. On the EventProcessor 8a3ade7 playground every sampled real record is identical before and after. The version comment on line 1 stays at 1.2.0: draft utmstack#2680 changes that line, and whichever draft merges second takes the next version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne rules The CrowdStrike plugin forwards Falcon event-stream records whose only top-level keys are metadata and event (plugins/crowdstrike/main.go, processEvent), and no filter step writes log.event_simpleName, a Falcon Data Replicator field. The condition could never be true, so these five rules never fired. Without it they match detection summaries whose command line matches their patterns. Rules: inhibit_system_recovery, os_credential_dumping_activity, suspicious_encoded_powershell_execution, suspicious_native_downloaders and windows_event_log_clearing. Names, patterns, impact and MITRE labels are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An alert has no origin. For rules with adversary: origin the CEL plugin copies the event's origin into the alert's adversary, and plugins/alerts grouping.go skips keys it cannot resolve. So origin.host and origin.user in groupBy were always skipped: three rules never grouped, and four grouped only by their lastEvent key, which merged alerts from different hosts. The brute-force rule's deduplicateBy origin.ip never deduplicated. Seven rules now group by adversary.host (and adversary.user where they used origin.user), and the brute-force rule deduplicates by adversary.ip. Its condition, threshold, window and history search are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crowdstrike_review_test.go runs 18 fabricated Falcon event-stream records (testdata/crowdstrike-review/raw.json) through a model of the EventProcessor 8a3ade7 step plugins, with every where clause evaluated by go-sdk v1.1.36. The model gave the same fields as the real 8a3ade7 playground on every record tried. The tests check that: - command lines are stored as sent, apart from surrounding spaces; - no unconditional rename repeats an earlier one; - each record matches exactly the listed rules, and every field a rule reads is one the filter writes; - every groupBy and deduplicateBy key is an alert field that resolves, through grouping.go, on the alert the CEL plugin would build. All four tests fail on the original filter and rules. Identifiers and file names differ from draft utmstack#2680's, so both drafts compile together. The records carry no UserIp and assert no actionResult, which belong to utmstack#2680. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
filters/audits/crowdstrike.md states what the corrections rest on (the CrowdStrike plugin, EventProcessor 8a3ade7, grouping.go and go-sdk v1.1.36, with genuine records read privately and vendor documentation unavailable), each change with its proof, the relationship with draft utmstack#2680 (no shared lines; the version comment stays at 1.2.0 so the drafts do not conflict), the deferred items including the MITRE ATT&CK v19 relabel and the AuditLogV3Event double-count risk, an operational note on a failing API client, and the limits of the proof. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five of the seventeen CrowdStrike rules test a field that this integration can never deliver, so they can never fire. Eight rules group or deduplicate alerts by fields that do not exist on an alert, and the filter damages quoted command lines.
This draft fixes those. It deliberately leaves the outcome block and the sign-in address mapping to the separate outcome draft #2680. The two drafts merge cleanly, and both test sets pass together.
Built and tested on the latest versions: v11
d2479c1a, go-sdk v1.1.36, and EventProcessor8a3ade7. That engine revision is the same source as today'seventprocessor:v11.2.14image andeventprocessor/base:1.1.7.Predecessor: #2602 (closed, historical context only). Related: #2680 (outcome-only, separate campaign).
Evidence (read-only, described without identifying data)
APIActivityAuditEvent;AuditLogV3Event(a second, nested copy of each audit record);UserActivityAuditEvent;AuthActivityAuditEvent.Filter (
filters/crowdstrike/crowdstrike.yml)log.eventCommandLine. They left quoted Windows paths and arguments unbalanced; for example,"C:\Tools\x.exe" -a "C:\Temp\y.dmp"was stored asC:\Tools\x.exe" -a "C:\Temp\y.dmp.Rules
inhibit_system_recovery,os_credential_dumping_activity,suspicious_encoded_powershell_execution,suspicious_native_downloaders,windows_event_log_clearing:equals("log.event_simpleName", "ProcessRollup2");event_simpleNameis a Data Replicator field; the plugin forwards only event-stream records (metadataandevent), and no filter step writes it.groupByusesadversary.host/adversary.userinstead oforigin.*. An alert has noorigin, so these keys were always skipped.deduplicateBy: adversary.ipinstead oforigin.ip. Before, every failure after the threshold raised another alert.Validation
grouping.go).plugins/alertssuite passes.Deferred
These need Falcon documentation, real records or an owner decision:
AuditLogV3Eventcopies (drop, pass through or map). If they were ever normalized, each failure would count twice in the brute-force history.PolicyDisabled;Operational notes (not code changes)
plugins/crowdstrike/main.go).See
filters/audits/crowdstrike.md.🤖 Generated with Claude Code