Unusual File Creation - Alternate Data Stream

Identifies suspicious creation of Alternate Data Streams on highly targeted files using a script or command interpreter. This is uncommon for legitimate files and sometimes done by adversaries to hide malware.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2021/01/21"
  3integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
  4maturity = "production"
  5updated_date = "2026/09/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies suspicious creation of Alternate Data Streams on highly targeted files using a script or command interpreter.
 11This is uncommon for legitimate files and sometimes done by adversaries to hide malware.
 12"""
 13from = "now-9m"
 14index = [
 15    "winlogbeat-*",
 16    "logs-endpoint.events.file-*",
 17    "logs-windows.sysmon_operational-*",
 18    "logs-m365_defender.event-*",
 19    "logs-sentinel_one_cloud_funnel.*",
 20    "endgame-*",
 21]
 22language = "eql"
 23license = "Elastic License v2"
 24name = "Unusual File Creation - Alternate Data Stream"
 25risk_score = 73
 26rule_id = "71bccb61-e19b-452f-b104-79a60e546a95"
 27severity = "high"
 28tags = [
 29    "Domain: Endpoint",
 30    "OS: Windows",
 31    "Use Case: Threat Detection",
 32    "Tactic: Defense Evasion",
 33    "Resources: Investigation Guide",
 34    "Data Source: Elastic Defend",
 35    "Data Source: Sysmon",
 36    "Data Source: Microsoft Defender XDR",
 37    "Data Source: SentinelOne",
 38    "Data Source: Elastic Endgame",
 39    "Noise: Medium",
 40    "Performance: Normal",
 41    "Rule Type: Event Correlation (EQL)",
 42    "Platform: Windows",
 43]
 44timestamp_override = "event.ingested"
 45type = "eql"
 46
 47query = '''
 48file where host.os.type == "windows" and event.type == "creation" and
 49   process.name : ("cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe", "wscript.exe", "cscript.exe", "node.exe", "python*.exe") and
 50   file.extension in~ (
 51    "pdf", "dll", "exe", "dat", "com", "bat", "cmd", "sys", "vbs", "vbe", "ps1", "hta", "txt", "js", "jse",
 52    "wsh", "wsf", "sct", "docx", "doc", "xlsx", "xls", "pptx", "ppt", "rtf", "gif", "jpg", "png", "bmp", "img", "iso"
 53  ) and
 54  file.path : "C:\\*:*" and
 55  not file.name :("*:$DATA", "*PG$Secure", "*Zone.Identifier", "*com.apple.lastuseddate#PS", "*com.apple.provenance")
 56'''
 57
 58note = """## Triage and analysis
 59
 60### Investigating Unusual File Creation - Alternate Data Stream
 61#### Possible investigation steps
 62
 63- What ADS target did the alert create?
 64  - Focus: `file.path`, `file.extension`, `file.size`, and the stream suffix after the base file.
 65  - Implication: escalate when a command or script interpreter writes ADS on an executable, script, user document, or disk-image host file with a payload-like, DLL-like, or config-like stream name; lower concern only when stream name and file class match a narrow classification, tagging, or packaging marker.
 66
 67- Does stream metadata or collected content look like payload material?
 68  - Focus: `file.size`, `file.Ext.header_bytes`, `file.Ext.entropy`, and collected ADS content when available.
 69  - Hint: retrieve raw ADS content with "Get-Content -Path <host_file> -Stream <stream_name>" or collect the host file before cleanup; without content, do not close from absence.
 70  - Implication: escalate for script text, encoded blobs, PE bytes, launcher syntax, or execution configuration; if content cannot be recovered, keep unresolved unless lineage, staging, or reuse proves the answer. Lower concern requires small, readable classification, package, validation, or test metadata.
 71
 72- How was the creating interpreter launched?
 73  - Focus: `process.executable`, `process.command_line`, `process.parent.executable`, `process.parent.command_line`, and `process.code_signature.subject_name`. $investigate_2
 74  - Implication: escalate when launched by a document, browser, user-writable binary, unusual parent command, or command line that writes hidden content; lower concern when identity, parent, command line, and user-host scope match a recognized tagging, packaging, or validation workflow.
 75
 76- Did the creating process stage, rename, or clean up supporting files?
 77  - Focus: same-process file events on `host.id` and `process.entity_id`: `file.path`, `file.extension`, and `file.size`. $investigate_3
 78  - Implication: escalate when the same process drops executables or scripts, renames content into a deceptive path, deletes staging material, or writes related ADS artifacts; lower concern when file activity stays limited to the expected file set and stream metadata pattern.
 79
 80- Did later commands reuse the ADS path or base file?
 81  - Why: ADS creation becomes decisive when a later command uses file:path:stream syntax or a helper consumes hidden content.
 82  - Focus: later process events on `host.id` and `user.id` where `process.command_line` references the ADS path, base path, or stream name; include `process.executable` and `process.parent.executable`. $investigate_4
 83  - Hint: search first for the literal ADS path, then the base path and stream name separately if quoting or escaping differs.
 84  - Implication: escalate when later commands read, execute, copy, extract, or persist from ADS; if no reuse appears, keep unresolved unless content and lineage prove benign metadata use.
 85
 86- Does the ADS pattern recur broadly enough to change scope?
 87  - Focus: smallest stable suspicious indicator, such as stream name, `file.path` pattern, `process.executable`, or `process.command_line`, plus `host.id` and `user.id` scope.
 88  - Hint: review host-related alerts for matching ADS or interpreter patterns. $investigate_1
 89  - Hint: review user-related alerts before treating activity as one-host. $investigate_0
 90  - Implication: broaden containment and scoping when unrelated hosts or users share the ADS pattern; keep scope local only when local content, lineage, and reuse are resolved or the pattern remains confined to one unresolved host.
 91
 92- Escalate for hidden payload staging, ADS execution, suspicious cleanup, or spread beyond the first host; close only when ADS path/content, command lines, parent lineage, same-process file activity, and `host.id`/`user.id` scope prove one exact marker-writing or lab workflow with no contradictory reuse; preserve artifacts and escalate when answers stay mixed or incomplete.
 93
 94### False positive analysis
 95
 96- Data-classification, packaging, or validation tools can legitimately create small ADS markers on fixed file classes. Confirm identity (`process.executable`, `process.code_signature.subject_name`, parent command line), artifacts (`file.path`, stream name, readable marker content), and scope (`host.id`, `user.id`, host cohort) all align with one exact workflow; if workflow records are unavailable, require prior alerts with the same process identity, parent command line, stream name, file class, and host cohort.
 97- Controlled security testing or forensic labs can place samples or markers in ADS on isolated systems. Confirm the same `process.executable`, `process.command_line`, `file.path`, stream name, and lab host cohort, and no later execution or persistence from ADS; if test plans are unavailable, require repeated bounded testing patterns. Do not create exceptions on `process.name` or `file.extension` alone.
 98
 99### Response and remediation
100
101- If confirmed benign:
102  - Document the evidence that established the workflow before changing response state: `process.executable`, `process.command_line`, parent command line, `file.path` pattern, stream name, stream content type, and the `host.id` or `host.name` cohort. Then reverse temporary containment. Build exceptions only from the minimum confirmed pattern, not from a generic interpreter or file-extension condition.
103- If suspicious but unconfirmed:
104  - Preserve the exact ADS path, base host file, recovered stream content or computed hash, process timeline, `process.entity_id`, `process.pid`, `process.command_line`, `process.parent.command_line`, and same-process file events before cleanup.
105  - Apply reversible containment tied to the findings, such as heightened monitoring, execution restrictions for the affected interpreter, or temporary containment of the affected `host.id`; avoid deleting the stream or base file until evidence is collected.
106  - Escalate to host isolation only if ADS reuse, payload-like content, suspicious cleanup, or continued staging shows active risk and the asset can tolerate isolation.
107- If confirmed malicious:
108  - Use endpoint response to isolate the host after preserving the ADS path, base file, stream content, process timeline, command lines, parent lineage, and related file artifacts. If direct endpoint response is unavailable, hand off that evidence set to the team that can contain the host.
109  - Review other hosts and users for the same stream name, ADS path pattern, `process.executable`, or `process.command_line` before deleting the stream, removing the base file, or terminating related processes.
110  - Remove the malicious stream, launched payloads, staging files, and the entry vector that created them, then remediate any persistence or delivery path identified during the investigation.
111- Post-incident hardening:
112  - Keep process and file telemetry enabled for the affected host class, and record recurring ADS naming or interpreter patterns for future triage.
113  - Restrict or monitor interpreter workflows that create ADS on high-value file types when that behavior is not required for the host role.
114"""
115
116setup = """## Setup
117
118This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
119
120Setup instructions: https://ela.st/install-elastic-defend
121
122### Additional data sources
123
124This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
125
126- [Microsoft Defender XDR](https://ela.st/m365-defender)
127- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
128- [Sysmon Event ID 15 - FileCreateStreamHash](https://ela.st/sysmon-event-15-setup)
129"""
130
131[rule.investigation_fields]
132field_names = [
133    "@timestamp",
134    "host.name",
135    "host.id",
136    "user.name",
137    "user.id",
138    "process.parent.executable",
139    "process.entity_id",
140    "process.pid",
141    "process.name",
142    "process.executable",
143    "process.command_line",
144    "file.path",
145    "file.name",
146    "file.extension",
147    "file.size",
148]
149
150[transform]
151
152[[transform.investigate]]
153label = "Alerts associated with the user"
154description = ""
155providers = [
156  [
157    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
158    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
159  ]
160]
161relativeFrom = "now-48h/h"
162relativeTo = "now"
163
164[[transform.investigate]]
165label = "Alerts associated with the host"
166description = ""
167providers = [
168  [
169    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
170    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
171  ]
172]
173relativeFrom = "now-48h/h"
174relativeTo = "now"
175
176[[transform.investigate]]
177label = "Process events for the same process"
178description = ""
179providers = [
180  [
181    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
182    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
183    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
184  ]
185]
186relativeFrom = "now-1h"
187relativeTo = "now"
188
189[[transform.investigate]]
190label = "File events for the same process"
191description = ""
192providers = [
193  [
194    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
195    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
196    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
197  ]
198]
199relativeFrom = "now-1h"
200relativeTo = "now"
201
202[[transform.investigate]]
203label = "Process events for the same host and user"
204description = ""
205providers = [
206  [
207    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
208    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
209    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
210  ]
211]
212relativeFrom = "now-1h"
213relativeTo = "now"
214
215[[rule.threat]]
216framework = "MITRE ATT&CK"
217[[rule.threat.technique]]
218id = "T1564"
219name = "Hide Artifacts"
220reference = "https://attack.mitre.org/techniques/T1564/"
221[[rule.threat.technique.subtechnique]]
222id = "T1564.004"
223name = "NTFS File Attributes"
224reference = "https://attack.mitre.org/techniques/T1564/004/"
225
226[rule.threat.tactic]
227id = "TA0005"
228name = "Defense Evasion"
229reference = "https://attack.mitre.org/tactics/TA0005/"

Triage and analysis

Investigating Unusual File Creation - Alternate Data Stream

Possible investigation steps

  • What ADS target did the alert create?

    • Focus: file.path, file.extension, file.size, and the stream suffix after the base file.
    • Implication: escalate when a command or script interpreter writes ADS on an executable, script, user document, or disk-image host file with a payload-like, DLL-like, or config-like stream name; lower concern only when stream name and file class match a narrow classification, tagging, or packaging marker.
  • Does stream metadata or collected content look like payload material?

    • Focus: file.size, file.Ext.header_bytes, file.Ext.entropy, and collected ADS content when available.
    • Hint: retrieve raw ADS content with "Get-Content -Path <host_file> -Stream <stream_name>" or collect the host file before cleanup; without content, do not close from absence.
    • Implication: escalate for script text, encoded blobs, PE bytes, launcher syntax, or execution configuration; if content cannot be recovered, keep unresolved unless lineage, staging, or reuse proves the answer. Lower concern requires small, readable classification, package, validation, or test metadata.
  • How was the creating interpreter launched?

    • Focus: process.executable, process.command_line, process.parent.executable, process.parent.command_line, and process.code_signature.subject_name. $investigate_2
    • Implication: escalate when launched by a document, browser, user-writable binary, unusual parent command, or command line that writes hidden content; lower concern when identity, parent, command line, and user-host scope match a recognized tagging, packaging, or validation workflow.
  • Did the creating process stage, rename, or clean up supporting files?

    • Focus: same-process file events on host.id and process.entity_id: file.path, file.extension, and file.size. $investigate_3
    • Implication: escalate when the same process drops executables or scripts, renames content into a deceptive path, deletes staging material, or writes related ADS artifacts; lower concern when file activity stays limited to the expected file set and stream metadata pattern.
  • Did later commands reuse the ADS path or base file?

    • Why: ADS creation becomes decisive when a later command uses file:path:stream syntax or a helper consumes hidden content.
    • Focus: later process events on host.id and user.id where process.command_line references the ADS path, base path, or stream name; include process.executable and process.parent.executable. $investigate_4
    • Hint: search first for the literal ADS path, then the base path and stream name separately if quoting or escaping differs.
    • Implication: escalate when later commands read, execute, copy, extract, or persist from ADS; if no reuse appears, keep unresolved unless content and lineage prove benign metadata use.
  • Does the ADS pattern recur broadly enough to change scope?

    • Focus: smallest stable suspicious indicator, such as stream name, file.path pattern, process.executable, or process.command_line, plus host.id and user.id scope.
    • Hint: review host-related alerts for matching ADS or interpreter patterns. $investigate_1
    • Hint: review user-related alerts before treating activity as one-host. $investigate_0
    • Implication: broaden containment and scoping when unrelated hosts or users share the ADS pattern; keep scope local only when local content, lineage, and reuse are resolved or the pattern remains confined to one unresolved host.
  • Escalate for hidden payload staging, ADS execution, suspicious cleanup, or spread beyond the first host; close only when ADS path/content, command lines, parent lineage, same-process file activity, and host.id/user.id scope prove one exact marker-writing or lab workflow with no contradictory reuse; preserve artifacts and escalate when answers stay mixed or incomplete.

False positive analysis

  • Data-classification, packaging, or validation tools can legitimately create small ADS markers on fixed file classes. Confirm identity (process.executable, process.code_signature.subject_name, parent command line), artifacts (file.path, stream name, readable marker content), and scope (host.id, user.id, host cohort) all align with one exact workflow; if workflow records are unavailable, require prior alerts with the same process identity, parent command line, stream name, file class, and host cohort.
  • Controlled security testing or forensic labs can place samples or markers in ADS on isolated systems. Confirm the same process.executable, process.command_line, file.path, stream name, and lab host cohort, and no later execution or persistence from ADS; if test plans are unavailable, require repeated bounded testing patterns. Do not create exceptions on process.name or file.extension alone.

Response and remediation

  • If confirmed benign:
    • Document the evidence that established the workflow before changing response state: process.executable, process.command_line, parent command line, file.path pattern, stream name, stream content type, and the host.id or host.name cohort. Then reverse temporary containment. Build exceptions only from the minimum confirmed pattern, not from a generic interpreter or file-extension condition.
  • If suspicious but unconfirmed:
    • Preserve the exact ADS path, base host file, recovered stream content or computed hash, process timeline, process.entity_id, process.pid, process.command_line, process.parent.command_line, and same-process file events before cleanup.
    • Apply reversible containment tied to the findings, such as heightened monitoring, execution restrictions for the affected interpreter, or temporary containment of the affected host.id; avoid deleting the stream or base file until evidence is collected.
    • Escalate to host isolation only if ADS reuse, payload-like content, suspicious cleanup, or continued staging shows active risk and the asset can tolerate isolation.
  • If confirmed malicious:
    • Use endpoint response to isolate the host after preserving the ADS path, base file, stream content, process timeline, command lines, parent lineage, and related file artifacts. If direct endpoint response is unavailable, hand off that evidence set to the team that can contain the host.
    • Review other hosts and users for the same stream name, ADS path pattern, process.executable, or process.command_line before deleting the stream, removing the base file, or terminating related processes.
    • Remove the malicious stream, launched payloads, staging files, and the entry vector that created them, then remediate any persistence or delivery path identified during the investigation.
  • Post-incident hardening:
    • Keep process and file telemetry enabled for the affected host class, and record recurring ADS naming or interpreter patterns for future triage.
    • Restrict or monitor interpreter workflows that create ADS on high-value file types when that behavior is not required for the host role.

Related rules

to-top