Skip to content

Crowdstrike.fdr: map CommandHistory events to ECS process fields#20285

Open
chemamartinez wants to merge 4 commits into
elastic:mainfrom
chemamartinez:crowdstrike-fdr-map-process-fields-commandhistory
Open

Crowdstrike.fdr: map CommandHistory events to ECS process fields#20285
chemamartinez wants to merge 4 commits into
elastic:mainfrom
chemamartinez:crowdstrike-fdr-map-process-fields-commandhistory

Conversation

@chemamartinez

@chemamartinez chemamartinez commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Proposed commit message

crowdstrike.fdr: map CommandHistory events to ECS process fields

Parse CommandHistory events in the FDR ingest pipeline to populate
ECS process fields. The CommandHistory string (commands delimited by
the pilcrow character ¶) is mapped to process.command_line and split
into an array stored at crowdstrike.CommandHistory.

CrowdStrike uses U+00B6 PILCROW SIGN (¶) as the separator between 
individual commands in the CommandHistory field.
This character has no formal documentation from CrowdStrike,
but it is consistently observed in FDR CommandHistory events collected
in real scenarios.

The UserName field is copied to process.user.name for CommandHistory
events. A new script processor derives process.interactive from LogonType,
treating types 2 (Interactive), 10 (RemoteInteractive), 11 (CachedInteractive)
and 12 (CachedRemoteInteractive) as interactive sessions.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.
  • I have verified that any added dashboard complies with Kibana's Dashboard good practices

@chemamartinez chemamartinez self-assigned this Jul 22, 2026
@chemamartinez chemamartinez added enhancement New feature or request Integration:crowdstrike CrowdStrike Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] labels Jul 22, 2026
@chemamartinez
chemamartinez marked this pull request as ready for review July 22, 2026 14:23
@chemamartinez
chemamartinez requested review from a team as code owners July 22, 2026 14:23
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/security-service-integrations (Team:Security-Service Integrations)

@github-actions

Copy link
Copy Markdown
Contributor

✅ Elastic Docs Style Checker (Vale)

No issues found on modified lines!


The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.

- script:
tag: script_process_interactive_logon_type_9b3d6c7a
description: Set process.interactive from crowdstrike.LogonType; types 2 (Interactive), 10 (RemoteInteractive), and 11 (CachedInteractive) indicate an interactive shell session.
if: ctx.crowdstrike?.LogonType instanceof String && ctx.crowdstrike.LogonType != ''

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟡 Medium confidence: medium path: packages/crowdstrike/data_stream/fdr/elasticsearch/ingest_pipeline/default.yml:1148

The process.interactive script fires on any event carrying a LogonType, so authentication events (UserLogon/UserLogoff) get a bare process.interactive with no process context; gate it on an established process instead.

Details

The new script's condition is only ctx.crowdstrike?.LogonType instanceof String && ctx.crowdstrike.LogonType != '', which is not scoped to process events. LogonType is present on Windows authentication events, so this stamps process.interactive onto documents that have no process. This is observable in the regenerated fixtures: in test-fdr.log-expected.json a UserLogoff event (event.category: ["authentication"]) now gains a lone process: { "interactive": false } object, and test-user-map / test-windows show the same on non-process events. The effect is also broader than the changelog entry ("Map CommandHistory events to ECS process fields") describes. Attaching a process attribute to an authentication event is semantically misleading and creates a process object where none belongs.

Recommendation:

Gate the script on an already-established process so it only applies to genuine process events (CommandHistory and ProcessRollup set process.entity_id from TargetProcessId earlier in the pipeline; authentication events do not):

- script:
    tag: script_process_interactive_logon_type_9b3d6c7a
    description: Set process.interactive from crowdstrike.LogonType; types 2 (Interactive), 10 (RemoteInteractive), and 11 (CachedInteractive) indicate an interactive shell session.
    if: >-
      ctx.crowdstrike?.LogonType instanceof String && ctx.crowdstrike.LogonType != '' &&
      ctx.process?.entity_id != null
    source: |-
      def logonType = ctx.crowdstrike.LogonType;
      ctx.process.interactive = (logonType == '2' || logonType == '10' || logonType == '11');
    on_failure:
      - append:
          field: error.message
          value: "Failed to set process.interactive from LogonType: {{{_ingest.on_failure_message}}}"

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@elastic-vault-github-plugin-prod

elastic-vault-github-plugin-prod Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🚀 Benchmarks report

Package crowdstrike 👍(8) 💚(4) 💔(2)

Expand to view
Data stream Previous EPS New EPS Diff (%) Result
falcon 4878.05 3316.75 -1561.3 (-32.01%) 💔
identity_protection_assessment 25000 18726.59 -6273.41 (-25.09%) 💔

To see the full report comment with /test benchmark fullreport

@andrewkroh andrewkroh added the documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. label Jul 22, 2026
"version": "1007.3.0021003.10"
},
"process": {
"command_line": "sc stop CSFalconService¶Stop-Service -Name CSFalconService -Force",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this right? I've looked for the any documentation for the semantics of this character and have found none. I think we need some explanation of how we are interpreting it in the commit message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've added an explanation in the commit message. The use of this character has been observed in several real log samples.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So how does that work with process.command_line? The string that its holding is not the "Full command line that started the process, including the absolute path to the executable, and all arguments."

Comment on lines +986 to +988
if (ctx.process == null) {
ctx.process = new HashMap();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (ctx.process == null) {
ctx.process = new HashMap();
}
ctx.process = ctx.process ?: [:];

source: |-
def logonType = ctx.crowdstrike.LogonType;
if (ctx.process == null) ctx.process = new HashMap();
ctx.process.interactive = (logonType == '2' || logonType == '10' || logonType == '11');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this wants a comment explaining the logon types.

@chemamartinez
chemamartinez requested a review from efd6 July 23, 2026 06:34
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

@vera-review-bot

Copy link
Copy Markdown

No issues across the latest commits 61ccfa37d507a3 (17 commits).

Review summary

Issues found across earlier commits d0257c7 — 1 medium
  • 🟡 The process.interactive script fires on any event carrying a LogonType, so authentication events (UserLogon/UserLogoff) get a bare process.interactive with no process context (link) (Unresolved)

A new commit triggers another review — at most once every 15 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

💚 Build Succeeded

History

cc @chemamartinez

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

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. enhancement New feature or request Integration:crowdstrike CrowdStrike Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants