~/himanshu
← Case filescheckpoint 1 / 14 · ~18 min left
CASE-011INCIDENT18 MIN

One File, 8.5 Million Blue Screens

Himanshu Kukrejareads
Blueprint cover for the case file "One File, 8.5 Million Blue Screens"
FIG. 1 · Blueprint · CASE-011

Lesson · 16 min

Understanding the Problem: Friday Afternoon in Sydney#

It's Friday, July 19, 2024, just after 2 p.m. in Sydney.

You're on the IT team of a mid-sized company. Someone two desks away says their laptop just went blue. Then another. Then the screens at reception: the Windows crash screen, the "blue screen of death". They restart, the Windows logo appears, and the blue screen comes back.

Your phone starts buzzing. It isn't just your office: shop tills, airport check-in desks, banks, hospitals. As other countries wake up, it happens there too.

Nobody has been hacked; CrowdStrike would soon state that the issue was "not the result of or related to a cyberattack." The cause is a single file that arrived silently, minutes earlier, from the security software that was installed precisely to protect these machines.

That software is CrowdStrike Falcon, used by many of the world's largest companies. At 04:09 UTC, CrowdStrike pushed a routine update to Falcon on Windows: a small configuration file called Channel File 291. By 05:27 UTC it had pulled the file back. In those 78 minutes, every Windows machine running a recent Falcon sensor that was online and picked up the file could crash.

Microsoft later estimated that about 8.5 million Windows devices were affected. That was less than one percent of all Windows machines, but, as Microsoft noted, CrowdStrike is used by enterprises that run many critical services, so the damage spread far beyond those devices.

And here's the cruel part: CrowdStrike fixed the file in 78 minutes, but fixing the machines took days. Many of them had to be repaired by hand, one at a time.

July 19, 2024, by the numbers
  • 8.5M — Windows devices affected (Microsoft's estimate)
  • < 1% — of all Windows machines
  • 78 min — how long the bad file was being served (04:09 to 05:27 UTC)
  • 1 — configuration file, Channel File 291
  • 21 vs 20 — fields the rule expected vs inputs the sensor supplied
  • $5.4B — estimated direct losses for US Fortune 500 firms (Parametrix)

Using CrowdStrike's own post-incident reports and Microsoft's posts, let's see exactly how one file did this, and what "safe rollout" means when your code runs at the heart of the operating system.

Five Terms You Need#

Plain-language glossary
Endpoint security sensor

A program installed on every computer (each "endpoint") that watches for attacks. CrowdStrike calls theirs the Falcon sensor.

Kernel

The core of the operating system. It controls memory, hardware and every other program. Code running in the kernel has full power over the machine, so if it crashes, the whole machine crashes.

Channel file

A data file CrowdStrike sends to sensors to tell them what suspicious behaviour to look for. Channel File 291 was one of them. On disk its name starts with C-00000291 and ends in .sys.

Blue screen (BSOD)

What Windows shows when the kernel hits an error it can't recover from. The machine stops and restarts.

BitLocker

Windows' disk encryption. If you need to repair a locked-down machine from outside Windows, you often need its recovery key, a 48-digit number stored somewhere else.

Chapter 1: Why Security Software Lives in the Kernel#

Most programs (your browser, your email) run in user space. If one crashes, Windows closes it and you reopen it. Annoying, not fatal.

Falcon's core runs as a kernel driver, a program loaded into the kernel itself, starting early in the boot process. CrowdStrike explained why: being in the kernel gives "rich visibility" into what's happening across the system (processes starting, files being written) and lets the sensor block malicious activity as it happens, including malware that tries to launch before normal programs start.

That power has a price. Microsoft's David Weston put the trade-off plainly in a post after the incident: kernel drivers provide these properties "at the cost of resilience", and "all code operating at kernel level requires extensive validation because it cannot fail and restart like a normal user application."

DiagramThe same bug in two different places
%% title: The same bug in two different places
flowchart TD
  subgraph US["User space"]
    APP["Normal app<br/>browser · email"]:::service
  end
  subgraph KS["Kernel space"]
    DRV["Security driver<br/>loaded early in boot"]:::core
    OS["Windows core"]:::store
  end
  APP -->|"bad memory read"| C1(["App crashes<br/>Windows closes it · you reopen it"]):::ok
  DRV -->|"bad memory read"| C2(["Whole machine stops<br/>blue screen"]):::bad
  DRV --- OS

The bug in this story is an ordinary one, the kind user-space programs hit every day. What made it catastrophic was where it ran.

Chapter 2: Two Ways to Update a Sensor#

New attack techniques appear constantly, so CrowdStrike updates Falcon in two different ways.

DiagramTwo delivery paths into the sensor
%% title: Two delivery paths into the sensor
flowchart TD
  subgraph SLOW["Sensor Content · part of a sensor release"]
    SC["Sensor code<br/>includes Template Types"]:::core --> QA["Release testing<br/>stress · fuzzing · performance"]:::service
    QA --> WHQL["Microsoft driver certification<br/>WHQL"]:::external
  end
  subgraph FAST["Rapid Response Content · from the cloud"]
    TI["Template Instances<br/>matching rules"]:::queue --> CV{"Content Validator"}:::hot
    CV --> CF[["Channel File 291"]]:::queue
  end
  WHQL --> SEN["Falcon sensor<br/>on each Windows machine"]:::core
  CF -->|"pushed to online sensors"| SEN
  • Sensor Content ships as part of a new sensor version. It's compiled code and goes through a long release process, including Microsoft's driver certification program (WHQL). This path is thorough, and slow.
  • Rapid Response Content is delivered from the cloud as channel files, without changing the sensor's code. It's how CrowdStrike reacts to new threats at "operational speed". In its own words: "Rapid Response Content is configuration data; it is not code or a kernel driver."

Hold onto that sentence.

Templates and instances#

How Rapid Response Content is put together
  • Template Type — a detection capability built into the sensor's code; defines a set of input fields to match on
    • Template Type Definitions file — says how many inputs each Template Type uses and which channel file delivers it
  • Template Instance — a specific rule written by a detection engineer: which values to match in each field (regex patterns)
    • Channel file — a bundle of Template Instances sent to sensors
  • Content Validator — checks channel files against the Template Type Definitions file before they ship
  • Content Interpreter — the code inside the sensor that runs each rule against live system data

Think of a Template Type as a form with numbered boxes, built into the sensor. A Template Instance is a filled-in copy of that form: "box 1 must look like this, box 2 can be anything, box 3 must look like that". The sensor's Content Interpreter fills in the boxes from what's happening on the machine and checks whether the rule matches.

Chapter 3: The Form With 21 Boxes#

In February 2024, sensor version 7.11 shipped with a new Template Type for watching named pipes, a standard way Windows programs talk to each other (one kind of "interprocess communication", or IPC). Attackers abuse named pipes too, so it's a useful thing to watch. Rules for it would be delivered in Channel File 291.

Here's the flaw, straight from CrowdStrike's Root Cause Analysis:

  • The IPC Template Type's definition said it had 21 input fields.
  • But the sensor code that called the Content Interpreter for these rules supplied only 20 input values.

The form said 21 boxes. The sensor only ever filled in 20.

How did that survive testing? Because every rule tested and shipped so far used a wildcard for the 21st field, meaning "match anything". With a wildcard there, the sensor never had to look at box 21, so the missing value never mattered.

Why the bug stayed hidden for months

Field 21 = wildcard

  • The rule says "box 21: anything is fine"
  • The sensor doesn't need to read box 21
  • The missing 21st input is never touched
  • Tests pass, deployments in March and April go fine

Field 21 = a real value

  • The rule says "box 21 must look like this"
  • The sensor has to read box 21 to compare
  • There is no box 21: it reads past the end of a 20-item list
  • In kernel code, that crashes the whole machine

Here's the shape of the bug in code. This is illustrative only, written to show the idea; it is not CrowdStrike's source.

c7 lines
// Illustrative only - not CrowdStrike's code.
InputString *inputs[20];            // the sensor prepares 20 inputs

// ...later, evaluating a rule from Channel File 291...
int i = rule->field_index;          // the new rule asks for index 20 (the 21st field)
InputString *s = inputs[i];         // no check that i < 20: reads past the end
compare(s->buffer, s->length, rule->pattern);   // follows a garbage pointer -> crash

CrowdStrike's crash-dump analysis shows exactly this: the faulting driver was csagent.sys, the requested input was at index 0x14 (20 in decimal, the 21st item), and the value found there "does not point to valid memory". Windows reported a PAGE_FAULT_IN_NONPAGED_AREA bugcheck, and the machine went down.

And the safety net had the same blind spot#

There was a check meant to catch bad content: the Content Validator. But it judged the new rules against the Template Type definition, which said 21 fields. By that yardstick, a rule using field 21 was perfectly valid. The validator was checking the content against the paperwork, not against what the sensor actually supplied.

CrowdStrike's review summed it up as a "confluence" of three issues: the 21-versus-20 mismatch, a missing bounds check in the Content Interpreter, and no test that used a real (non-wildcard) value in the 21st field.

The Incident Timeline#

From the new sensor version to the root cause report. Times on July 19 are UTC.

Channel File 291, February to August 2024
  • Feb 28 —
    sensor 7.11 ships with the new IPC Template Type (21 fields defined, 20 inputs supplied)
  • Mar 5 —
    the IPC Template Type passes stress testing; the first IPC rule goes out in Channel File 291
  • Apr 8 to Apr 24 —
    three more IPC rules ship successfully; all use a wildcard for field 21
  • Jul 19, 04:09 —
    two new IPC rules are deployed; one uses a real value in field 21. It passes the Content Validator.
  • Jul 19, 04:09 onwards —
    Windows machines with sensor 7.11+ that receive the file crash at the next named-pipe event, and again on restart
  • Jul 19, 05:27 —
    CrowdStrike reverts Channel File 291; machines that are still up stop receiving the bad version
  • Jul 20 —
    Microsoft estimates 8.5 million Windows devices affected
  • Jul 23 —
    CrowdStrike adds the bad file to Falcon's cloud known-bad list, which can automatically recover some boot-looping machines with good network connections
  • Jul 24 —
    CrowdStrike publishes its Preliminary Post Incident Review
  • Jul 25 —
    CrowdStrike reports more than 97% of affected Windows sensors back online
  • Jul 29 —
    about 99% of Windows sensors online compared with the week before
  • Aug 6 —
    CrowdStrike publishes the full Root Cause Analysis

04:09 UTC was 2:09 p.m. in Sydney, 9:39 a.m. in India, 5:09 a.m. in London and just after midnight in New York. Asia and Australia hit it mid-workday; Europe and the Americas woke up to it.

Chapter 4: What Happened Inside Each Machine#

DiagramOne machine, July 19
%% title: One machine, July 19
sequenceDiagram
  autonumber
  participant CS as CrowdStrike cloud
  participant SEN as Falcon sensor · kernel
  participant WIN as Windows
  CS->>SEN: new Channel File 291 · 04:09 UTC
  WIN->>SEN: a named pipe is created
  SEN->>SEN: rule asks for field 21 · only 20 exist
  SEN-->>WIN: invalid memory read in kernel
  WIN->>WIN: blue screen · restart
  Note over SEN,WIN: the bad file is still on disk
  WIN->>SEN: driver loads early in boot
  SEN-->>WIN: crash again
  Note over CS,WIN: a fixed file exists from 05:27,<br/>but the machine may crash before it can fetch it

Two things made it nasty.

First, named pipes are everywhere. They're a normal part of how Windows works, so the crash didn't wait for some rare event. It happened at "the next IPC notification from the operating system", and on a working machine that is rarely a long wait.

Second, the crash survived a restart. The bad file stayed on disk. Falcon's driver loads early in boot. So many machines crashed, restarted, loaded the same file, and crashed again: a boot loop.

CrowdStrike's early guidance was simply to "reboot the host to give it an opportunity to download the reverted channel file". Sometimes that worked: the machine stayed up just long enough to fetch the fix. Microsoft reported that some Azure virtual machines needed several reboots, "as many as 15", before recovering. Many machines never won that race.

Chapter 5: "Config Is Code"#

Go back to that sentence: "Rapid Response Content is configuration data; it is not code or a kernel driver."

That's literally true. Channel File 291 held no program instructions, just patterns to match. But look at what that data did. It told kernel code which memory to read. A new value in field 21 sent the sensor down a code path that had never run in the real world. The data didn't contain the bug, but it switched it on.

This is why many engineers say "config is code". Not because configuration files contain programs, but because changing configuration changes what your program does, sometimes as dramatically as a code change. If a change can crash production, it deserves the same care as code: tests that exercise it, a gradual rollout, and a way back.

Treating content like data vs treating it like code

Content as "just data"

  • Validated against a definitions file
  • Tests used wildcards for some fields
  • Shipped to every eligible online sensor at once
  • More customer control over its timing came only afterwards

Content as code

  • Validated against what the code actually supplies
  • Tests use real values in every field
  • Shipped in rings, starting with a canary, with bake time between
  • Customers can choose where and when updates land

The right-hand column isn't hypothetical. It's close to what CrowdStrike itself committed to afterwards.

Chapter 6: Blast Radius#

Blast radius means: if this change is bad, how much breaks? For Channel File 291, the answer was potentially every Windows machine running Falcon 7.11 or later that was online during those 78 minutes. CrowdStrike's own RCA lists this as a finding in so many words: "Each Template Instance should be deployed in a staged rollout."

A staged rollout (also called a ring or canary deployment) means you don't send an update to everyone at once. You send it to a small group first, watch what happens, and only widen the circle if nothing breaks. The first group is the canary, named after the birds miners once carried to detect poisonous gas.

DiagramA ring rollout with bake time
%% title: A ring rollout with bake time
flowchart TD
  NEW(["New content update"]):::client --> R0["Ring 0 · canary<br/>your own machines"]:::core
  R0 --> B0{"Bake time<br/>crashes or errors?"}:::hot
  B0 -->|"yes"| RB(["Stop and roll back<br/>blast radius stays tiny"]):::bad
  B0 -->|"no"| R1["Ring 1 · early adopters<br/>small share of customers"]:::service
  R1 --> B1{"Bake time<br/>crashes or errors?"}
  B1 -->|"yes"| RB
  B1 -->|"no"| R2["Ring 2 · broad<br/>larger share"]:::service
  R2 --> B2{"Bake time<br/>healthy?"}
  B2 -->|"no"| RB
  B2 -->|"yes"| GA(["All sensors"]):::ok

Rings matter even more for a crash like this: it triggered quickly on any machine that got the file, so a canary ring would have lit up fast.

WorksheetBlast radius with and without a canary (illustrative numbers)
  • Without rings: every eligible online sensor gets the file = about 8,500,000 devices hit (Microsoft's estimate)
  • With a canary of, say, 5,000 machines, halted at the first crashes: 5,000 devices hit
  • Share of the real impact: 5,000 ÷ 8,500,000 = about 0.06%
  • Even a 1% first ring: 1% × 8,500,000 = about 85,000 devices, 100 times fewer

The canary sizes are made up to show the arithmetic. The point: the first ring caps the damage, and bake time between rings turns a global outage into a bad afternoon for a test lab.

Chapter 7: Why Recovery Took Days#

CrowdStrike reverted the file at 05:27 UTC. So why were companies still recovering days later?

Because the usual way to fix software, pushing an update over the network, needs the machine to be running and connected. A machine stuck in a boot loop is neither for long. For many machines, the fix had to be done in person.

DiagramGetting one machine back
%% title: Getting one machine back
flowchart TD
  A(["Machine shows blue screen"]):::bad --> RB{"Reboot a few times<br/>does it stay up long enough?"}
  RB -->|"yes · fetches fixed file"| OK(["Back in service"]):::ok
  RB -->|"no · still looping"| SM["Boot into Safe Mode or<br/>Windows Recovery Environment"]:::service
  SM --> BL{"Disk encrypted<br/>with BitLocker?"}
  BL -->|"yes"| KEY["Find and type the<br/>48-digit recovery key"]:::hot
  BL -->|"no"| DEL["Delete C-00000291*.sys"]:::core
  KEY --> DEL
  DEL --> OK

The manual fix itself was short. CrowdStrike and Microsoft both published versions of it:

The manual fix, per machine
  1. Boot into Safe Mode or the Windows Recovery Environment — so the Falcon driver doesn't load and crash the machine
  2. Unlock the disk if needed — on BitLocker-encrypted machines this may require the recovery key
  3. Go to %WINDIR%\System32\drivers\CrowdStrike — the folder holding the channel files
  4. Delete the files matching C-00000291*.sys — the bad Channel File 291
  5. Restart normally — Windows boots and Falcon fetches the corrected file

Five steps. Simple, until you multiply them by thousands of machines, each needing someone at the keyboard. For encrypted machines, someone also has to find the right recovery key for each one, often stored in a key management system that may itself run on Windows.

Microsoft released a USB recovery tool (support article KB5042429) offering two options: boot from a recovery environment that deletes the file automatically, or boot into Safe Mode to do it. Even then, for BitLocker-protected devices, a recovery key could still be needed. CrowdStrike later added the bad file to Falcon's cloud known-bad list, which it said could automatically recover some boot-looping machines that had a strong network connection.

The bill#

What the outage cost
  • Delta Air Lines: CEO Ed Bastian put the cost at about $500 million over five days. According to Bastian, as reported by NPR, the airline had to manually reset 40,000 servers, and it cancelled more than 5,000 flights.
  • Parametrix, a cloud-outage insurance firm, estimated $5.4 billion in direct losses for US Fortune 500 companies, excluding Microsoft. It said about a quarter of the Fortune 500 was affected, with airlines hit hardest on average.

Delta's figure is a company claim and Parametrix's is a modelled estimate; neither has been independently audited.

What CrowdStrike Changed#

CrowdStrike's Root Cause Analysis lists the fixes. Here they are in plain terms, grouped by the layer they protect.

Fixes from the Root Cause Analysis
  • Build time
    • the Sensor Content Compiler now checks that each Template Type supplies the number of inputs it declares (in production July 27, 2024)
  • Runtime
    • a bounds check in the Content Interpreter so an out-of-range field can't be read (added July 25; hotfix for sensors 7.11+ due by August 9)
    • the IPC Template Type now supplies all 21 inputs
  • Testing
    • automated tests with real, non-wildcard values in every field, for all Template Types
    • every new Template Instance gets tested, not just the first one
    • fuzz testing extended to more content handlers
  • Validation
    • Content Validator checks that rules don't match on more fields than the sensor provides (due in production by August 19)
    • meanwhile, only wildcards are allowed in field 21 of Channel File 291
  • Rollout
    • staged deployment rings: canary first, then wider rings, with bake time and rollback
    • customers can choose where and when Rapid Response Content is deployed
  • Outside review
    • two independent software security vendors reviewing the sensor code and the end-to-end quality process

Count the layers. Several of them (the input-count check, the bounds check, the non-wildcard tests) would each have stopped July 19 on their own, and the rings would have shrunk whatever got through. That's the point: you don't rely on one check being perfect. You stack checks so a single miss can't reach millions of machines.

Lessons for Any Engineer#

You may never write a kernel driver. But you almost certainly push configuration, flags, rules or data files that change how your software behaves.

  • Config is code. If a change can alter what your program does, it can break production. Test it and roll it out like code.
  • Every fast path needs a brake. Fast delivery is a feature. Fast delivery to everyone at once is a risk. Rings with bake time give you speed and a brake.
  • Validate against reality, not just the spec. A validator that checks content against a definitions file inherits every mistake in that file. Test against the code that will actually run.
  • Wildcards hide bugs. If your tests only ever use "match anything", you've never tested matching. Give every field a real value at least once.
  • Plan recovery for machines that can't phone home. If a bad update can stop a machine from booting, your normal update channel can't fix it. Know where your recovery keys are, and practise the hands-on fix before you need it.

Summary: The Smallest Change, the Biggest Reach#

Strip away the scale and July 19 is a tiny bug. A list had 20 items. A rule asked for the 21st. Every engineer has made that off-by-one mistake.

What turned it into what is widely called the largest IT outage in history was everything around it: kernel code, where a crash takes down the whole machine; a fast path built to reach everyone within minutes; checks that trusted a definitions file the code disagreed with; and machines that couldn't stay up long enough to be fixed.

CrowdStrike fixed the file in 78 minutes. The world spent days fixing the machines.

Next time you push "just a config change" to every server at once, picture the canary that wasn't there. A few thousand machines going blue in a test ring is a bad afternoon. Eight and a half million is a headline.

Sources#

  • Blog

    CrowdStrike, "Falcon Content Update Preliminary Post Incident Report" (July 24, 2024): crowdstrike.com

  • Paper

    CrowdStrike, "External Technical Root Cause Analysis — Channel File 291" (August 6, 2024): crowdstrike.com (PDF)

  • Read

    CrowdStrike, "Technical Details: Falcon Content Update for Windows Hosts" (July 2024): crowdstrike.com

  • Read

    CrowdStrike, Falcon Content Update Remediation and Guidance Hub: crowdstrike.com

  • Blog

    David Weston, Microsoft, "Helping our customers through the CrowdStrike outage" (July 20, 2024): blogs.microsoft.com

  • Read

    David Weston, Microsoft, "Windows Security best practices for integrating and managing security tools" (July 27, 2024): microsoft.com

  • Read

    Microsoft Support, KB5042429, "New recovery tool to help with CrowdStrike issue impacting Windows devices": support.microsoft.com

  • Book

    Brandon Vigliarolo, The Register, "Azure VMs ruined by CrowdStrike patchpocalypse? Microsoft has recovery tips" (July 19, 2024), quoting Microsoft's Azure status guidance on repeated reboots: theregister.com

  • Book

    Eduard Kovacs, SecurityWeek, "97% of Devices Disrupted by CrowdStrike Restored as Insurer Estimates Billions in Losses" (July 26, 2024), on CrowdStrike's recovery figure and Parametrix's estimate: securityweek.com

  • Read

    Jason Breslow, NPR, "Delta's CEO says the CrowdStrike outage cost the airline $500 million in 5 days" (July 31, 2024), via HPPR: hppr.org

End of file · CASE-011

Read it through to close the case.

0/14 sections read. Each one counts after a few minutes of actual reading in it; skipping ahead doesn't. The case closes itself once every section is read.

All case files →
Debrief · close the case+50 XP for the right call

A new content update for software that runs in the OS kernel has just passed your validator. What's the safest next step?

> debrief --interactiveCASE-011 · +25 XP at 5/6
End-of-file activity · decide

Plan the rollout

You own the next Channel File 291 update: a new named-pipe rule for a sensor that runs in the Windows kernel. Take it from test bench to every machine, ring by ring. One call per step; each wrong call costs the step. Clear 70% to crack the case.

  • ~4 MIN
  • 6 STEPS · 6 PTS
  • SOLVE AT 5/6
  • +25 XP
Staged RolloutsCanary DeploymentsConfigurationKernelInput ValidationBlast RadiusProduction IncidentsReal-World Engineering

Discussion

Add to the post-mortem
loading the record…