Detection rules › Elastic

Potential Evasion via Boot Time Removal Tool

Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies creation of a ":changelist" NTFS alternate data stream or a Windows service Args registry value pointing to a ":changelist" path. Microsoft Defender's Boot-Time Removal (BTR.sys) driver reads an RC4-encrypted transaction blob from a driver ADS named ":changelist", referenced by HKLM\SYSTEM*ControlSet*\Services*\Args. Adversaries can reproduce this staging outside Defender to abuse BTR.sys as a signed kernel primitive for arbitrary file and registry operations. This rule focuses on non-System writers and excludes Microsoft-signed MRT.exe running as SYSTEM, which may perform related remediation staging.

MITRE ATT&CK coverage

Rule body

[metadata]
creation_date = "2026/08/21"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/08/21"

[rule]
author = ["Elastic"]
description = """
Identifies creation of a ":changelist" NTFS alternate data stream or a Windows service Args registry value pointing to
a ":changelist" path. Microsoft Defender's Boot-Time Removal (BTR.sys) driver reads an RC4-encrypted transaction blob
from a driver ADS named ":changelist", referenced by HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\Args. Adversaries can
reproduce this staging outside Defender to abuse BTR.sys as a signed kernel primitive for arbitrary file and registry
operations. This rule focuses on non-System writers and excludes Microsoft-signed MRT.exe running as SYSTEM, which may
perform related remediation staging.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential Evasion via Boot Time Removal Tool"
note = """## Triage and analysis

### Investigating Potential Evasion via Boot Time Removal Tool

Windows Defender's Boot-Time Removal driver (`BTR.sys`) is instructed via an encrypted configuration stored in an
Alternate Data Stream named `:changelist` on a `.sys` image. The service `Args` value under
`HKLM\\SYSTEM\\*ControlSet*\\Services\\<name>\\Args` points at that ADS path. Check Point Research (BTR Reforged)
showed that the same staging can be performed by non-Defender tooling (for example BTR_CLI) to drive Ring-0 file and
registry actions, including neutralization of security products during early boot.

#### Possible investigation steps

- Identify whether the alert is a file ADS creation or a service `Args` registry write using `event.category`,
  `file.name` / `file.path`, and `registry.path` / `registry.data.strings`.
- Review `process.executable`, `process.name`, `process.pid`, `process.parent.executable`, and `user.id` to determine
  whether a Defender component, MRT, or an unexpected user-mode binary staged the `:changelist` artifact.
- For file events, inspect the base `.sys` path (strip `:changelist`), size, hash, and code signature. Confirm whether
  the driver was recently dropped under a user-writable path (Downloads, Temp, Desktop) versus a Defender-managed path.
- For registry events, note the service key name under `Services\\*` and check sibling values (`ImagePath`, `Type`,
  `Group`). Abuse tooling often sets `Group` to `Boot Bus Extender` and may create the service via direct registry
  writes / `NtLoadDriver` without a corresponding SCM service-install event (7045).
- Hunt on the same `host.id` for related activity: creation of `*.sys:*.dat` feedback ADS, load of a Microsoft-signed
  driver matching BTR, creation/deletion of `\\\\SystemRoot\\\\Temp\\\\BootClean.log` by PID 4, and deletions of security
  binaries attributed to System.
- Correlate with other alerts for the same `user.id` and `host.id` in the prior 48 hours for privilege escalation,
  driver load, or Defender tampering.

### False positive analysis

- Legitimate Defender or MRT reboot remediation may create `:changelist` ADS and related service Args values. This rule
  excludes PID 4 and Microsoft-signed `MRT.exe` as SYSTEM; unsigned or differently signed `MRT.exe` still alerts. Rare
  Defender paths (for example `MsMpEng.exe`) may still match and should be validated before exceptioning.
- Security research labs intentionally exercising BTR_CLI or similar PoCs will generate true-positive-looking events;
  confirm host cohort and change windows.

### Response and remediation

- If activity is unexplained: isolate the host, preserve the `.sys` file and `:changelist` stream, export the service
  registry key, and capture the staging process tree before cleanup.
- Search the estate for the same `file.name` / ADS pattern, service `Args` values containing `:changelist`, and related
  driver hashes.
- Remove unauthorized service keys and staged drivers, restore any deleted security components from known-good media,
  and rotate credentials for accounts that held `SeLoadDriverPrivilege` on the host.
- Restrict and monitor assignment/use of `SeLoadDriverPrivilege`; treat signed remediation drivers as LOLDrivers that
  require lineage and ADS context monitoring, not signature blocking alone.
"""

setup = """## Setup

This 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.

Setup instructions: https://ela.st/install-elastic-defend
"""

references = [
    "https://research.checkpoint.com/2026/btr-reforged-weaponizing-defenders-remediation-driver-as-a-kernel-operation-primitive/",
    "https://github.com/Dump-GUY/BTR_CLI",
]
risk_score = 73
rule_id = "942c8f59-f01c-4dc0-a05f-2f5bba836ad8"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-endpoint.events.file-*, logs-endpoint.events.registry-* metadata _id, _version, _index
| where host.os.type == "windows"
  and process.pid != 4
  and not (
    user.id == "S-1-5-18"
    and to_lower(process.executable) like """?:\\windows\\system32\\mrt.exe"""
    and process.code_signature.subject_name in ("Microsoft Windows", "Microsoft Corporation") 
    and process.code_signature.trusted == true
  )
  and (
    (
      event.category == "file"
      and event.type == "creation"
      and ends_with(to_lower(file.name), ":changelist")
    )
    or (
      event.category == "registry"
      and event.type == "change"
      and to_lower(registry.path) like """*\\system\\*controlset*\\services\\*\\args"""
      and to_lower(registry.data.strings) like "*:changelist"
    )
  )
| keep
    @timestamp,
    host.id,
    host.name,
    user.id,
    user.name,
    process.pid,
    process.name,
    process.executable,
    process.code_signature.subject_name,
    event.category,
    event.type,
    file.path,
    file.name,
    file.size,
    registry.path,
    registry.value,
    registry.data.strings,
    data_stream.namespace,
    _id,
    _version,
    _index
| limit 100
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.id",
    "host.name",
    "user.id",
    "user.name",
    "process.pid",
    "process.name",
    "process.executable",
    "process.code_signature.subject_name",
    "event.category",
    "file.path",
    "file.name",
    "file.size",
    "registry.path",
    "registry.value",
    "registry.data.strings",
]

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"

[[rule.threat.technique.subtechnique]]
id = "T1564.004"
name = "NTFS File Attributes"
reference = "https://attack.mitre.org/techniques/T1564/004/"

[[rule.threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"

[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"

[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"

[[rule.threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

Stages and Predicates

Stage 1: from

from logs-endpoint.events.file-*, logs-endpoint.events.registry-* metadata _id, _version, _index

Stage 2: where

| where host.os.type == "windows"
  and process.pid != 4
  and not (
    user.id == "S-1-5-18"
    and to_lower(process.executable) like """?:\\windows\\system32\\mrt.exe"""
    and process.code_signature.subject_name in ("Microsoft Windows", "Microsoft Corporation") 
    and process.code_signature.trusted == true
  )
  and (
    (
      event.category == "file"
      and event.type == "creation"
      and ends_with(to_lower(file.name), ":changelist")
    )
    or (
      event.category == "registry"
      and event.type == "change"
      and to_lower(registry.path) like """*\\system\\*controlset*\\services\\*\\args"""
      and to_lower(registry.data.strings) like "*:changelist"
    )
  )

Stage 3: keep

| keep
    @timestamp,
    host.id,
    host.name,
    user.id,
    user.name,
    process.pid,
    process.name,
    process.executable,
    process.code_signature.subject_name,
    event.category,
    event.type,
    file.path,
    file.name,
    file.size,
    registry.path,
    registry.value,
    registry.data.strings,
    data_stream.namespace,
    _id,
    _version,
    _index

Stage 4: limit

| limit 100

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryeq
  • file corpus 43 (elastic 43)
  • registry corpus 15 (elastic 15)
field:"event.category" kind:eq
event.typeeq
  • change corpus 95 (elastic 95)
  • creation corpus 52 (elastic 52)
field:"event.type" kind:eq
process.pidne
  • 4 corpus 45 (elastic 45)
field:"process_id" kind:ne value:"4"
to_lower(file.name)ends_with
  • :changelist
field:"to_lower(file.name)" kind:ends_with value:":changelist"

Exclusions

The rule actively suppresses these predicates.

Output fields

These fields are emitted when the rule matches.

FieldSource
@timestampKEEP @timestamp
host.idKEEP host.id
host.nameKEEP host.name
user.idKEEP user.id
user.nameKEEP user.name
process.pidKEEP process.pid
process.nameKEEP process.name
process.executableKEEP process.executable
process.code_signature.subject_nameKEEP process.code_signature.subject_name
event.categoryKEEP event.category
event.typeKEEP event.type
file.pathKEEP file.path
file.nameKEEP file.name
file.sizeKEEP file.size
registry.pathKEEP registry.path
registry.valueKEEP registry.value
registry.data.stringsKEEP registry.data.strings
data_stream.namespaceKEEP data_stream.namespace
_idKEEP _id
_versionKEEP _version
_indexKEEP _index