Bring Your Own Installer: When the EDR Bypass Ships Inside the EDR
One of the cleanest ways to blind an endpoint sensor in 2026 doesn’t need a signed vulnerable driver or a kernel write primitive. It’s the agent’s own MSI and about a minute of patience. Aon’s Stroz Friedberg incident response team documented this against SentinelOne last year: kick off a local agent version change, and the platform terminates every running SentinelOne process roughly 55 seconds before the installer spawns the processes for the new version. A local admin who runs taskkill against msiexec.exe inside that window walks away with a host whose SentinelOne processes are gone — zero coverage from that agent — and, depending on how fast the console’s offline timer trips, a tile that can still read green for a while after the lights actually went out. They used it to drop a Babuk variant. No exploit, no CVE, no driver. Just the upgrade workflow doing exactly what it was designed to do, interrupted at the worst possible moment.
What makes this worth a full writeup isn’t the SentinelOne specifics — it’s that the class of risk generalizes even if the specific bypass doesn’t. Stroz found no EDR impacted when properly configured, and Palo Alto confirmed its agent wasn’t affected, so this is not a universal “all EDRs fall to this” claim. But any product whose agent can be upgraded, downgraded, or uninstalled locally without console approval has a version of this hole — and most detection programs are still pointed at the wrong artifact.
If you write a rule for the taskkill /im msiexec.exe line, you’ve caught one tool calling one binary one way. The next operator uses Stop-Process, or kills the installer’s parent, or doesn’t kill anything at all. There’s a public proof-of-concept — EDRChoker (analyzed by Zero Salarium; netcrook’s “Quiet Knife” writeup covers the same technique) — that uses Windows policy-based QoS (New-NetQosPolicy with an app-path rule pointed at the agent binary) to throttle the sensor’s outbound bandwidth to single-digit bits per second, low enough that it can’t even complete a TLS handshake to its backend. The process keeps running. Tamper protection stays happy. The agent is just functionally blind because it can’t reach its cloud backend, and a cloud-managed EDR with no outbound channel is a very expensive heartbeat generator. Different mechanism, same outcome: the telemetry stops.
So stop chasing the verb. The thing every one of these techniques has in common is the silence afterward. That’s the signal that survives the next variant.
The artifact you actually have
Before the silence, Bring Your Own Installer (BYOI) does leave host-side breadcrumbs, and you should collect them even though they’re not your primary detection. On a SentinelOne host the SentinelOne%4Operational.evtx log carries an EventID 1 each time the agent’s ProductVersion changes — in the Stroz writeup, two changes between 23.4.4.223 and 23.4.6.347 inside about a ten-minute span, which is not what a normal console-pushed upgrade looks like. The last operational entry before the lights go out is an EventID 93 with CommandType: unload. Over in Application.evtx you’ll find the matching MsiInstaller EventID 1042, “Installer Exited.” Two version flips in ten minutes plus an unload plus an installer that exited mid-flight is a clean signature.
Clean, and brittle. It lives in an EDR-specific channel that you’re probably not forwarding (most shops ingest the EDR’s cloud telemetry and never touch the agent’s local Windows event log), it’s specific to one vendor’s version strings, and it assumes the host kept logging — which is the whole thing the attacker just broke. Collect it for the post-incident timeline. Don’t make it your tripwire.
Sensor silence as a first-class signal
The detection that holds up is absence of telemetry. Your EDR fleet checks in on a cadence. When a host that should be reporting stops reporting, and there’s no maintenance ticket explaining it, that’s a security event until proven otherwise. Most consoles will eventually raise their own offline-agent alert, and that’s the zero-effort version of this detection — but it’s gated behind the same offline timer that keeps the host showing green well past the moment the agent went dark, and it resets as soon as the attacker’s reinstall completes. Computing the gap yourself in the SIEM is how you set the threshold instead of inheriting the vendor’s. The conventional home for this is system monitoring — SI-4 — and continuous monitoring, CA-7: sensor coverage is part of the posture you’re supposed to be watching. The control most teams don’t connect to it is AU-5, Response to Audit Logging Process Failures. Most teams read AU-5 as “alert when the disk fills up.” If you treat the EDR’s telemetry as an audit source, read it as “alert when a logging source goes dark,” because an attacker deliberately silencing your sensor is an audit logging process failure with intent — SI-4 says watch the sensor, AU-5 says its silence is itself a failure you’re required to respond to.
Here’s the shape in Splunk if you’re ingesting EDR telemetry into an index. The instinct is to run tstats over the accelerated data and compare last-seen to now — but tstats ... by host only returns hosts that sent at least one event in the window, so the host that’s been dark the entire time never shows up in the results, and that’s exactly the one you care about. Start from the inventory of what should be online and left-join the last-seen onto it:
| inputlookup asset_inventory where expected_online="true" AND asset_class="server"
| join type=left host
[| tstats latest(_time) as last_seen where index=edr earliest=-24h by host]
| eval gap_min=round((now()-coalesce(last_seen,0))/60)
| where gap_min > 25
One caveat before you scale this: Splunk’s join silently truncates its subsearch at the default 50,000-row limit, so on a large enough fleet the join itself can drop the very host you’re hunting for — the same silent-disappearance failure mode this whole detection exists to catch. Past a few thousand hosts, precompute last-seen into a summary index or a KV-store lookup with a scheduled tstats job and join against that instead.
The Elastic equivalent works, but the ingest pipeline makes the host normalization messier — you’ll spend the first afternoon reconciling host.name against agent.hostname against whatever the console calls the asset, because they will not agree. Pick the field the console uses as authoritative and map everything else to it in the lookup.
Threshold is the whole game, and the right number depends entirely on what you’re watching.
For always-on servers — domain controllers, the EKS worker nodes, the SQL boxes — a 20-to-30 minute gap with no change ticket is genuinely suspicious and the volume is low enough to alert on directly. For a fleet of managed laptops, that same rule is a disaster. Ship 8,000 Windows laptops and the “host went quiet for 25 minutes” query will return several hundred hits before lunch: lids closed, VPN dropped on the train, the user who works from a cabin with one bar of LTE, the sales org that lives in airplane mode. None of it is an attack and all of it looks identical to one in the index.
What the first week of tuning actually fixes
Nobody gets the threshold right on the first try. The first round of tuning is mostly carving out the legitimate reasons a sensor goes quiet, in roughly this order of payoff.
Asset class first. Split the rule by device type and only alert tightly on the always-on tier. Laptops get a longer fuse (I’d start around 8–12 hours of continuous silence during business hours, not minutes) and a lower severity, because the false-positive rate on a short laptop window is high enough to train your analysts to close the alert without looking — which is worse than not having the alert.
Then the upgrade windows, which is the cruel irony of this whole detection: the legitimate EDR agent upgrade looks exactly like the attack, because it is the attack minus the taskkill. When the console pushes a version change to a deployment group, every host in that group goes briefly quiet and flips its ProductVersion. If you don’t suppress around the maintenance window, your first vendor-pushed update will light up the SOC like a real incident. You need the console’s deployment schedule as a lookup, keyed by deployment group, and you suppress matching gaps inside it. Don’t suppress on “any version change” — suppress on “version change that matches a scheduled push to this host’s group.” The difference is the entire detection.
After that it’s the long tail. NTP skew is the one that’ll burn an afternoon: a host with a drifting clock reports timestamps that make now() - last_seen either negative or enormous, so your gap math lies. Filter or correct for hosts whose clock is more than a few minutes off the indexer, and flag the skew separately because a host that can’t keep time is its own small problem. Validate the indexer’s own clock before you trust any of this — if the indexer is the one that’s off, every host looks skewed at once. The sturdier version keys last-seen off _indextime, the moment the indexer received the event, rather than the event’s own _time: that sidesteps host-clock drift — and an attacker stomping the clock to forge a fresh check-in — entirely, at the cost of folding ingestion lag into the gap. Patch Tuesday reboots, the overnight backup window that saturates the uplink, the office that loses WAN every time the building HVAC cycles — each one becomes a suppression or a tuned threshold. Plan for two or three weeks before the alert is trustworthy. Anyone who tells you it’s a same-day deploy hasn’t run it against a real fleet.
Where the silence detection is blind, and what backs it up
The honest limitation: this is a coarse signal. It tells you a sensor stopped talking, not why. A reboot, a NIC driver crash, and a deliberate QoS starvation all present the same way in the gap query. That’s fine — coarse-but-reliable beats precise-but-evadable here — but it means the silence alert is a trigger for correlation, not a verdict.
There’s a second blind spot you build yourself: the maintenance-window suppression from the last section is an evasion surface. An operator who fires the taskkill during a genuine scheduled push lands inside your own suppression and the gap never alerts. This is the one place the brittle host-side artifact earns its keep — for silences that fall inside a maintenance window, fall back to the rapid double version-flip plus the EventID 93 unload plus the orphaned MsiInstaller exit, because a legitimate console-driven upgrade won’t carry a manual process kill in the middle of it.
Correlate against telemetry the endpoint sensor doesn’t control. If your NDR or firewall still sees the host generating traffic while the EDR says it’s offline, that’s not a sleeping laptop, that’s a live host with a muzzled agent, and it should escalate hard. AD authentication events for a “silent” host are the same tell. This is the architecture argument for keeping identity and network telemetry in the same index as endpoint — when the endpoint goes dark, the other two are how you tell “powered off” from “blinded.” For the QoS variant specifically, the cheap win is PowerShell logging — script-block (Event ID 4104) and module logging (Event ID 4103, which preserves the bound parameter values that 4104 can mangle when the operator hides the path or rate behind variables) — plus process-creation command-line telemetry, alerting on any New-NetQosPolicy or Set-NetQosPolicy whose app-path points at a security product’s install directory. Don’t stop at the registry, either: monitoring the persistent policy keys under HKLM\SOFTWARE\Policies\Microsoft\Windows\QoS misses policies written to the non-persistent ActiveStore (New-NetQosPolicy -PolicyStore ActiveStore), which never touch that path — so also enumerate live state with Get-NetQosPolicy and Get-NetQosPolicy -PolicyStore ActiveStore. QoS itself isn’t rare — Teams and VoIP shops push it through GPO all the time — so the cmdlet alone isn’t the signal; it’s the security-binary target that almost never has a legitimate reason to exist. Scoped that way it’s low-volume, high-signal. Worth the rule.
And close the door BYOI walked through. SentinelOne’s fix is the Local Upgrade Authorization (also called Online Authorization) setting, which forces any local agent upgrade, downgrade, or uninstall to be approved through the cloud console first. It’s off by default in a lot of tenants, which is the part that should bother you. Turn it on; Stroz confirmed the bypass stops working once it’s enabled. Whatever your EDR vendor is, go find the equivalent control — “can a local admin change the agent version without console approval?” — because if the answer is yes, you have the same hole with a different binary name.
| Control | What it covers here |
|---|---|
| AU-5 | Response to audit logging process failures — the sensor going dark is the logging failure AU-5 requires you to alert on |
| SI-4(5), SI-4(12) | System monitoring with automated alerting on the telemetry gap |
| SI-7 | Software/firmware integrity and tamper resistance — the agent’s anti-tamper and upgrade authorization |
| AU-12 | Audit record generation across the fleet; gaps are the exception to catch |
| CM-3, CM-5 | Change control over who can run an agent version change locally |
| CA-7 | Continuous monitoring; sensor coverage is part of the posture, not a given |
The mental shift is small and it costs nothing: treat your EDR’s check-in like any other log source whose disappearance is itself an event. A SOC that alerts when Splunk forwarders stop sending but shrugs when an endpoint sensor goes quiet has decided the security tool is the one source allowed to fail silently. Attackers noticed that before the defenders did. BYOI just made it cheap.
Sources
- Bring Your Own Installer: Bypassing EDR Through Agent Version Change Interruption (LevelBlue / SpiderLabs)
- Protection Against Local Upgrade Technique Described in Aon Research (SentinelOne)
- Babuk Ransomware Deployed via SentinelOne MSI Bypass (Anvilogic)
- ‘Bring Your Own Installer’ Attack Targets SentinelOne EDR (Dark Reading)
- EDRChoker: Choking the Telemetry Stream to Bypass Defenses (Zero Salarium)
- Windows’ Quiet Knife: How QoS Can Starve an EDR Sensor Without Killing It (netcrook)
- Solving the Telemetry Gap: Integrating SIEM with EDR and Identity — 2026 Guide (Huntress)