Am Freitag hatte ein Update der Sicherheitsfirma CrowdStrike über 8 Millionen Windows-Systeme weltweit auf wohl eine der mühsamsten Arten lahmgelegt. Damit das nicht mehr passiert, müssen wir verstehen, wie das alles passiert ist. Nur so können wir vermeiden, dass sich solche Katastrophen wiederholen, auch in einem ganz anderen Umfeld.
Dies ist eine Fortsetzung von Teil 1: «CrowdStrike oder: Wie eine Closed-Source-Firma fast die Welt lahmlegte»
Inzwischen gibt es auch Teil 3: CrowdStrike: Sind EU und Ratingagenturen schuld? (Und: Updates)
Unsere IT-Infrastruktur ist eine der Schlagadern unserer Zeit geworden. Ohne sie läuft vieles nicht oder nur sehr schlecht. Das Leben von Personen, das Überleben von Firmen und das Wohl unserer Gesellschaft hängt daran. Es sollte uns deshalb allen am Herzen liegen, dass diese Infrastruktur auch zuverlässig funktioniert. Dieser Artikel versteht sich als Schritt in Richtung dieses Ziels.
Er ist technischer als sein Vorgänger, weite Teile sollte aber immer noch ohne Informatikstudium zugänglich sein.
Inhalte
ToggleNeue Informationen von CrowdStrike zur Ursache [neu 2024-07-24]
CrowdStrike hat heute einen «Preliminary Post-Incident Report» (=«vorläufige Bericht nach dem Vorfall») veröffentlicht. Das Wichtigste in Kürze:
Was ist passiert?
- Es wurden am 19. Juli zwei zusätzliche Erkennungsmuster eingefügt (zur Erkennung von Kommunikation mit Command-and-Control-Servern via Named Pipes).
- Eines der beiden Muster war fehlerhaft, es wurde aber von den automatisierten Testfunktionen von CrowdStrike nicht erkannt; deshalb wurde das neue «Channel File» mit diesen beiden Mustern an alle Kunden verteilt.
- Beim Laden des neuen Musters durch den Falcon Scanner wurde die Struktur dieses Musters nur ungenügend überprüft. Deshalb wurde das fehlerhafte Muster akzeptiert; eigentlich sollten solche ungültigen Muster zurückgewiesen werden.
- Beim Benutzen dieses ungültigen Musters durch den Falcon Scanner wurde in der Folge auf falsche Speicherstellen zugegriffen, was zu einem Absturz führte. Da der Scanner im Kernel läuft, riss dieser Absturz die ganze Maschine mit: sie crashte mit dem Bluescreen.
Was wird CrowdStrike tun?
- Die Software wird gründlicher getestet (inklusive Fuzzing, einer Technik, mit der die Reaktion auf falsche Eingaben bzw. hier falsche Konfigurationsdateien getestet werden kann). Eigentlich ist alles auf der CrowdStrike-Liste «state of the art»; wenn das vorher nicht so gemacht wurde, ist das ein schlechtes Zeichen.
- Der Falcon Scanner wird Muster beim Laden gründlicher testen.
- Auch die Musterupdates über die Channel Files werden zukünftig gründlich(er) getestet.
- Er wird Staged Rollout (CrowdStrike nennt sie «Staggered Deployment» bzw. «Phased Rollout») auch für Musterupdates geben.
- Die Kunden werden über Musterupdates informiert.
Wenn diese Massnahmen wie versprochen umgesetzt werden, sollten zukünftige Probleme nach dem Stand der Technik vermieden werden. (Wie gesagt, 100%ige Sicherheit gibt es nie und nirgends.)
Die Software wird von Kunden gekauft, die die Zuverlässigkeit und Sicherheit ihrer Systeme erhöhen wollen. Dass eine derartige Software an einer derartigen Schlüsselstelle bisher ihre Eingabewerte (die Erkennungsmuster) nicht genügend getestet hatte und die Effizienz dieser Tests bisher nicht evaluiert wurde (das ist das Ziel von Fuzzing: Wo laden wir Daten, ohne sie genügend auf Plausibilität zu testen), ist allerdings erschreckend.
Wie können wir sowas vermeiden?
1. «Don’t deploy on Friday»
Am Tag des Ausfalls, einem Freitag, sah ich viele Social-Media-Posts, die sagten: «Don’t deploy on Friday», also: «Am Freitag installiert man keine Software-Updates».
Unser kürzlicher Artikel zu «Move fast and break things» fasst sehr gut zusammen, dass unabhängig davon, an welchen Tagen man neue Software aktiviert, die Prozesse dahinter funktionieren müssen. Und wenn die Prozesse funktionieren, dann ist es egal, an welchen Tagen neue Software ausgeliefert wird.
Wenn man erst einmal damit angefangen hat, am Freitag keine neue Software mehr auszuliefern, hat man sich auf einen Pfad begeben, der schlussendlich dazu führt, dass man gar nie mehr neue Software ausliefert. Das ist keine Option, da Software manchmal rasch auf Änderungen von ausserhalb reagieren muss. Wenn man keinen Prozess hat, mit dem man rasch auf Änderungen reagieren kann, zieht man sich besser gleich ganz aus dem Softwarebusiness zurück.
Es ist vor allem nötig, dass man seine Prozesse und Systeme so resilient (=ausfallsicher) macht wie nur möglich, um sicherzustellen, dass man so gut wie nie gröbere Probleme bekommt. Dazu gehören u.a.
- Testen, testen, testen.
- Monitoring (also seine Systeme automatisiert zu überwachen).
- Sicherzustellen, dass wenn doch einmal etwas schief geht, dass Sicherheitsnetze aufgestellt sind, die das auffangen können.
Das neue Channel-File scheint nicht auf einem echten Windows-Rechner getestet worden zu sein und etliche Sicherheitsnetze scheinen gefehlt oder versagt zu haben (siehe weiter unten).
Übrigens: In diesem Fall würde ich das Auftauchen des Fehlers an einem Freitag sogar als positiv bewerten. So blieb den Administratoren, welche die Probleme am Freitag nicht vollständig beheben konnten, noch das Wochenende zur Problemlösung. Auch wenn ich verstehe, dass viele wohl lieber das Wochenende im Kreise ihrer Familien verbracht hätten.
2. Staged rollout
Eines der beliebtesten, wirksamsten und oft gleichzeitig einfachsten Sicherheitsnetze ist der Staged Rollout. D.h. es bekommen nicht alle Maschinen gleichzeitig die neue Version, sondern erst einmal nur ein paar wenige. In mehreren Phasen kommen zusätzliche Maschinen hinzu, bis am Schluss alle Maschinen die neueste Version der Software einsetzen.
Damit werden häufige, katastrophale Fehler im Normalfall erkannt, bevor sie wirklich Schaden anrichten.
Die Schritte und ihre Geschwindigkeit hängen natürlich von vielen Parametern ab. Und nein, Staged Rollout ersetzt in keiner Weise gründliches Testen im Vorfeld (mit automatisierten Tests, im Labor, mit Betakunden, …).
Bei CrowdStrike können Kunden für Softwareupdates «Staged Rollout» aktivieren. D.h. der Kunde hat die Option zu wählen, dass er die Softwareupdates nicht sofort ausgeliefert bekommt. Berichten zufolge gilt diese Einstellung aber nur für die Software selbst, nicht für die Channel-Files, also die Konfigurationsdateien, wonach der Falcon Scanner eigentlich suchen soll.
Dies verunmöglicht es den Kunden, Vorsichtsmassnahmen gegen solche Ausfälle zu treffen; bei sicherheitskritischen Anwendungen eigentlich ein No-Go.
3. Raus aus dem Kernel
«Wenn der Falcon Scanner nicht im Kernel gelaufen wäre, wäre das alles nicht passiert» war der Tenor vieler Social-Media-Posts am Freitag. Ja, im Sinne des Swiss-Cheese-Modells kann Zuverlässigkeit und Sicherheit am besten durch übereinanderlegen vieler Lagen von (löchrigen) Schutzmechanismen erreicht werden. Löchrig deswegen, weil kein einzelner Schutzmechanismus vor allen Angriffen perfekt schützen kann, jeder hat also Löcher. Deshalb braucht es mehrere Schichten. Die Stärke eines IT-Schutzkonzepts liegt in der richtigen Kombination der einzelnen Käseschichten.
Dies ist übrigens auch der Weg, den Apple und Linux seit vielen Jahren anstreben: Dass das Betriebssystem selbst gewisse Funktionen für die Analyse (und ggf. Unterbindung) von gefährlichen Aktivitäten vorsieht. Diese sind vorbildlich programmiert und mit allen möglichen Sicherheitsnetzen versehen. Die eigentliche Sicherheitssoftware liefert dann nur noch die Regeln, die Umsetzung passiert im Kernel.
Trotzdem gibt es auch dann noch Möglichkeiten, sich in den Fuss zu schiessen. Besonders einfach ist es, wenn eine Funktion bei jedem Systemstart wieder automatisch aktiviert wird, wie dies bei Securityprodukten der Fall ist.
Beispielsweise kann die Sicherheitssoftware aus Versehen lebensnotwendige Netzwerkverbindungen blockieren oder die Ausführung eines notwendigen Programms verhindern, um nur einige Beispiele zu nennen.
Deshalb brauchen wir mehrere Lagen zur Sicherstellung der Zuverlässigkeit.
4. Sichere Programmiersprachen
Kasten: Flexibilität und Sicherheit als Antagonisten am Beispiel der Programmiersprache «C»
Betriebssysteme müssen die Hardware verwalten. Dazu braucht es Programmiersprachen, welche einfach direkt mit Hardware umgehen können. Seit fünf Jahrzehnten ist die Programmiersprache «C» mit ihren Dialekten das Arbeitspferd der Betriebssystementwickler.
Zu den Eigenschaften von C gehört, dass das Vorgehen bei der Verwaltung des Speichers sich sehr an der Hardware orientiert. Das war für die Betriebssystementwicklung ein Vorteil, führt aber auch dazu, dass die Softwareentwicklerinnen aber auch selbst an Dinge denken müssen, die andere Programmiersprachen ihnen automatisch abnehmen.
So ist es beispielsweise nötig, dass in vielen Fällen von der Softwareentwicklerin zu überprüfen ist, ob noch genügend Speicher vorhanden ist. Wenn dies vergessen geht, kann dies zu einem Buffer Overflow führen, welcher zu Sicherheitslücken und Programmabstürzen führen kann.
Die ersten Anzeichen des CrowdStrike-Crashes hätten auf einen Pufferüberlauf schliessen lassen können. Entsprechend schnell waren die Reaktionen von Leuten, die behaupteten, mit einer sichereren Programmiersprache (eine Sprache, die sich selbst um Speicherverwaltung und Überprüfung von Speicherzugriffen kümmert) wäre das nicht passiert.
Ob sie in diesem Fall auch geholfen hätten, bleibt aber im Moment noch unklar.
Bis alle relevanten Betriebssysteme auf sichere Programmiersprachen umgeschrieben sind, wird es noch Jahrzehnte dauern. (Aber z.B. Linux macht einen Anfang, dass man gewise Funktionen statt in C neu in Rust umsetzen könne.)
Übrigens:
- Auch C bietet inzwischen Möglichkeiten, mit denen die Programmiersprache mithelfen kann, Buffer Overflows zu vermeiden.
- Auch sichere Programmiersprachen können zu Abstürzen führen. Manchmal sogar wörtlich. So ist die Ariane 5 bei ihrem Jungernflug ausser Kontrolle geraten, weil die Programmiersprache zur Laufzeit einen Fehler melden wollte. Die Rakete wurde daraufhin von der Bodenkontrolle gesprengt.
Auch sichere Programmiersprachen ersetzen nicht die Erfahrung im Team und die Wichtigkeit, dass (mindestens) jemand den Überblick über alle Zusammenhänge und Auswirkungen der Systemkomponenten und ihrem Zusammenspiel hat.
Was ist denn eigentlich ein «Logik-Fehler»?
In den von CrowdStrike am 20. Juni veröffentlichten «technischen Details» fehlt vor allem Eines: Technische Details zur Ursache. Ausser, dass es ein «Logik-Fehler» gewesen sei:
[…] as part of ongoing operations, CrowdStrike released a sensor configuration update to Windows systems. […] This configuration update triggered a logic error resulting in a system crash and blue screen (BSOD) on impacted systems.
(Auf Deutsch etwa: «Als Teil unseres normalen Geschäftsbetriebs gab CrowdStrike ein Update für die Konfiguration des Sensors auf Windows-Systemen aus. Diese Konfigurations-Aktualisierung löste einen Logikfehler aus, der auf betroffenen Systemen zu in einem Systemabsturz und Bluescreen (BSOD) führte.»
CrowdStrike: Technical Details: Falcon Content Update for Windows Hosts, 2024-07-20
Was zum Teufel ist denn aber ein Logikfehler?
Das Ziel eines jeden Programmcodes ist es, die Logik des Programms und seiner Algorithmen umzusetzen. Ein Programm ist also nichts anderes als umgesetzte Logik. Was wiederum heisst, dass ein Logikfehler nichts anderes ist als ein beliebiger Programmfehler.
Es wäre also gut möglich, dass
- ein Buffer Overflow,
- die Verwendung von Daten, welche falsche (oder noch keine richtigen) Werte beinhalten,
- ein logischer Widerspruch für Anweisungen oder
- eine Unzahl anderer Fehler der Grund waren.
Also eigentlich hat die Aussage mit dem «Logik-Fehler» Null Informationswert.
Wieso dann diese Aussage? Darüber lässt sich zum aktuellen Zeitpunkt nur spekulieren.
Eine korrupte Konfigurationsdatei (in diesem Fall also ein Channel-File) sollte die Software niemals zum Absturz bringen können. Es ist die Aufgabe der Software, beim Laden der Konfigurationsdatei auf deren Korrektheit zu prüfen. Fehlerhafte oder korrupte Konfigurationsdateien sollten von der Software erkannt und abgewiesen werden.
Vorbeugen ist besser als heilen
Es gibt viele Möglichkeiten, mit einem zentralisierten Management im grossen Stil viele Rechner funktionsunfähig zu machen. Wahrscheinlich passiert sowas im kleineren Rahmen fast täglich irgendwo auf der Welt. CrowdStrike hat es einfach an mehreren Millionen Rechnern gleichzeitig geschafft.
Hier ein paar Möglichkeiten, wie man das Risiko reduzieren kann. Nicht alle davon können durch Endkunden selbst umgesetzt werden. Entsprechend sollten Kunden sicherstellen, dass sich ihre Lieferanten um diese verbleibenden Punkte kümmern, bevor die Kunden sich für ein Produkt entscheiden.
- «Don’t put all your eggs in one basket» (oder: Nicht alles auf eine Karte setzen): Monokulturen mögen effizient in der Beschaffung und Administration sein: Lösungen lassen sich effizient auf alle Geräte übermitteln. Sie sind aber auch dann effizient, wenn es gilt, Probleme effizient auf alle Geräte zu verteilen. Eine gewisse Heterogenität ist also durchaus gesund. Und hilft auch dabei, Vendor-Lock-In und seine negativen Auswirkungen zu reduzieren. Weil wir sonst auch ein systemrelevantes Clusterrisiko haben. (Wie stark man sich auf Homogenität einlassen will, ist aber eine komplexe Geschäftsentscheidung mit vielen Faktoren.) Das Ziel sollte also sein, dass beim Ausfall irgendeiner Komponente, und sei es auch das EDR (in diesem Fall CrowdStrike), nicht alle anderen Systeme gleichzeitig ausfallen. Das bedeutet auch, dass nicht alle Systeme vom gleichen EDR mit den gleichen Einstellungen gemanagt werden sollten.
- Testen, testen, testen: Man kann es nicht oft genug betonen: Alle Systeme sollten durch eine vollständige Liste mit automatischen Testszenarien durch müssen, bevor sie im grossen Stil auf produktiv eingesetzte Geräte verteilt werden. In unserem «Move fast and break things»-Artikel gehen wir tiefer darauf ein. Die plausibelste Erklärung: Dieses Channel-Update nicht (oder nicht korrekt) auf Windows-Systemen getestet, bevor es in die ganze Welt verteilt wurde. (CrowdStrike schweigt sich bisher dazu aus. [neu 2024-09-27] «Qualitätssicherung wird erst ernst genommen, wenn es unausweichlich ist»)
- Staged Rollout: Auch dies ist eine Binsenweisheit, die aber viel zu häufig ignoriert wird: Alle Änderungen sollten in Phasen auf die Geräte verteilt werden. Auch Konfigurationsänderungen. (Auch hier ist die Wahl der Geschwindigkeit und Schrittgrösse eine komplexe Geschäftsentscheidung, auch abhängig von der Kritikalität der Änderung.)
- Last Known Good State: Geräte sollten sich ihren letzten Zustand merken, in dem sie korrekt funktioniert haben. Und einfach auf diesen zurückgesetzt werden können. (Auch dies ist einfacher gesagt als getan und kann u.U. auch von Angreifern missbraucht werden, wenn es nicht richtig umgesetzt wird. Aber es gibt bereits seit Jahren Systeme, welche einen Systemstart von einem automatisch gespeicherten früheren Zustand ermöglichen.)
- Systeme aus der Ferne neu aufsetzen: Viele Rechner booten standardmässig ab ihrem lokalen Speichermedium (Harddisk, SSD, USB-Stick, …). Etliche Rechner bieten aber auch die Möglichkeit, beim Neustart im Netz nach einem Server zu fragen von dem das Betriebssystem geladen werden soll. Damit gäbe es eine Möglichkeit, bei fehlerhaftem Systemzustand den Rechner aus der Ferne neu aufzusetzen. Dieser Prozess ist u.a. als PXE-Boot bekannt. (Auch hier gilt es einige Überlegungen anzustellen, bevor man diese Funktion aktiviert.)
- Gute Ingenieure: In vielen IT-Firmen werden IT-Ingenieure vor allem als Kostenpunkt angesehen. Es wird übersehen, dass gute, erfahrene Personen auch helfen können, die Firma vor potenziell sehr grossen Kosten zu bewahren. Wenn niemand die Auswirkungen von Management-Entscheidungen auf die Funktion der Technik einschätzen kann, wird es gefährlich. (Mehr dazu hier.)
«Mit Linux wäre das nicht passiert»
Etliche Social-Media-Poster freuten sich hämisch über diesen Windows-Fehler und posteten Aussagen wie: «Mit Linux wäre das aber nicht passiert!»
Solche Aussagen sind nicht wirklich konstruktiv (und in dieser Absolutheit auch falsch). Ja, Linux bietet CrowdStrike die Möglichkeit, ohne eigenes Kernelmodul auszukommen. Dies wird aber scheinbar bisher nur optional von CrowdStrike genutzt. Aber auch mit Linux (und anderen Sicherheitsprodukten als CrowdStrike) bleiben immer noch unzählige Möglichkeiten, Maschinen via automatisierte Updates und Konfigurationsänderungen im grossen Stil gleichzeitig ausser Gefecht zu setzen.
Anscheinend waren die Crashes von CrowdStrike Falcon unter Linux im April bis Juni diesen Jahres durch einen Fehler im Linux-Kernel ausgelöst. Eine detailliertere Einschätzung folgt im demnächst erscheinenden dritten Teil der Serie. [neu 2024-08-03]
Aber ein wichtiger Punkt wäre bei Linux und anderen Open-Source-Projekten wohl deutlich anders gelaufen: Wir wüssten inzwischen deutlich mehr über die eigentliche Ursache und könnten beginnen, mit vollständiger Information darüber zu diskutieren, wie wir solche Probleme zukünftig abwenden können.
Bei xz hatten wir 24 bis 48 Stunden nach dem ersten Bekanntwerden schon ein sehr gutes Lagebild, obwohl die Hintermänner versucht hatten, ihre Aktivitäten zu verschleiern.
Bei CrowdStrike haben wir auch nach über 72 Stunden kaum mehr als Brosamen. Möglicherweise hofft die Firma, dass Intransparenz sie davor bewahrt, interne Probleme preisgeben zu müssen. Dabei sollte doch der CrowdStrike-CEO aus seiner Zeit bei McAfee wissen, dass Intransparenz bei Sicherheitslösungen das Kundenvertrauen sehr rasch erodieren kann.
4 Antworten
Software mit Fehlern wird es immer geben. Überlegte Deployment Modelle helfen das Risiko eines Totalausfalls erheblich zu reduzieren (selbst angewendet bei Windows Massen-Deployments an mehr als 100k Systeme).
Das sehe ich auch so und hoffte, dass das sowohl in diesem Artikel als auch durch den Verweis auf unseren «Move fast and break things»-Artikel klar geworden ist.
Wo ist es deiner Meinung nach noch unklar?
Problem mit dem Staged/Phased-Rollout ist natürlich, dass man die Signatur-/Regel-Updates eigentlich schnell haben will. Deshalb ist es ein Unding, wie schlecht diese Signatur-Daten offenbar beim Einlesen geprüft wurden und quasi unkontrolliert ein Null-Pointer/Bad-Memory-Access erzeugt wurde.
Was ich aber gerade bei so einer Software nicht verstehe: Wenn das System in einen BSOD geht und danach neu gestartet wird, lässt sich rausfinden, ob der letzte System-Shutdown sauber war oder nicht. Wenn das der Fall war, dürfte die Kernel-Software selber aus Sicherheitsgründen gar nicht erst starten. Windows kann sowas ähnliches mit dem Safe-Boot: Da starten nur Komponenten, die zum OS-Lieferumfang gehören, eine Kernelsoftware wie die von CrowdStrike gehört nicht dazu und wird folglich auch nicht gestartet. So etwas in der Art müsste es auch für den regulären Boot nach einem BSOD geben, natürlich mit entsprechenden Warnhinweisen, dass nicht alles gestartet wurde. Microsoft hat so etwas durchaus in seine Produkte eingebaut, Outlook kann sowas.
Lustig ist, dass Microsoft jetzt die EU für die Panne verantwortlich macht:
https://de.euronews.com/reise/2024/07/23/microsoft-macht-eu-fur-den-schlimmsten-it-ausfall-der-welt-verantwortlich
Danke für das viele Feedback/Ideen!