1 Punkte von GN⁺ 2024-07-23 | 1 Kommentare | Auf WhatsApp teilen
  • Der weltweite Windows-Ausfall vom 19. Juli 2024 war ein Fall, bei dem ein Update des Kernel-Treibers eines Sicherheitsprodukts zu einem fehlerhaften Speicherzugriff führte und Bluescreens sowie Boot-Schleifen auslöste
  • eBPF läuft zwar im Kernel, ist aber so konzipiert, dass Verifier und Sandbox gefährlichen Code ablehnen und ein einzelnes Programm nicht das gesamte System zum Absturz bringen kann
  • Linux enthält eBPF bereits; sobald Microsofts eBPF for Windows produktionsreif ist, kann auch Windows-Sicherheitssoftware auf dieselbe Weise umgestellt werden
  • Große Tech-Unternehmen wie Google, Meta und Cisco sowie eBPF-basierte Security-Startups nutzen Geschwindigkeit, tiefe Sichtbarkeit und Sicherheitsgarantien, um Sicherheitsprodukte und Erkennungssysteme auszubauen
  • Unternehmen, die kommerzielle Software mit Kernel-Treibern oder Kernel-Modulen kaufen, können eBPF-Unterstützung unter Linux schon jetzt und unter Windows bald zur Anforderung an Anbieter machen

Das Risiko von Kernel-Code, das der Windows-Ausfall vom 19. Juli offenlegte

  • Der Ausfall vom 19. Juli 2024 war ein beispielloser Fall, der die inhärenten Risiken der Kernel-Programmierung zeigte
  • Windows-Rechner weltweit erlebten Bluescreens (blue screen of death) und Boot-Schleifen; Krankenhäuser, Fluggesellschaften, Banken, Lebensmittelgeschäfte und Rundfunkanstalten waren betroffen
  • Ursache war ein Config-Update (config update) eines weit verbreiteten Sicherheitsprodukts, das einen Kernel-Treiber für Windows-Systeme enthielt
  • Nach dem Update versuchte der Kernel-Treiber, falschen Speicher zu lesen; diese Art von Fehler kann den Kernel zum Absturz bringen

Abstürze, die eBPF verhindern kann

  • eBPF ist kein Akronym mehr, sondern eine sichere Ausführungsumgebung im Kernel, ähnlich einer sicheren JavaScript-Runtime, die in Webbrowser integriert ist
  • Linux-Nutzer haben eBPF wahrscheinlich bereits in ihrem System; eBPF wurde vor einigen Jahren in den Linux-Kernel aufgenommen
  • eBPF-Programme sind so eingeschränkt, dass sie nicht das gesamte System zum Absturz bringen können
    • Ein Software-Verifier (verifier) prüft die Sicherheit
    • Programme laufen praktisch in einer Sandbox
    • Findet der Verifier unsicheren Code, wird das Programm abgelehnt und nicht ausgeführt
  • Der Verifier der Linux-Implementierung besteht aus mehr als 20.000 Zeilen Code, mit Beiträgen aus der Industrie wie Meta, Isovalent und Google sowie aus der Wissenschaft wie der Rutgers University und der University of Washington
  • Erhöhte Sicherheit, geringer Ressourcenverbrauch und Absturzvermeidung sind die wichtigsten Vorteile von eBPF

Einsatzmöglichkeiten unter Linux und Windows

  • Das Sicherheitsunternehmen, das diesen Ausfall verursachte, befand sich auf Linux-Systemen bereits in einem Einführungsprozess für eBPF
  • Sobald Microsofts eBPF support for Windows produktionsreif ist, kann auch Windows-Sicherheitssoftware auf eBPF portiert werden
  • Auf eBPF migrierte Windows-Sicherheitsagenten können dann keine Windows-Kernel-Abstürze mehr verursachen

Einführung in der Sicherheitsbranche und bei großen Tech-Unternehmen

  • Die eBPF-basierten Security-Startups Oligo und Uptycs hoben anlässlich des jüngsten Ausfalls die Vorteile einer Migration zu eBPF hervor
  • Auch große Tech-Unternehmen setzen eBPF für Sicherheitszwecke ein
    • Cisco übernahm das eBPF-Startup Isovalent und stellte Cisco Hypershield vor, ein Fabric für Sicherheitsdurchsetzung und Monitoring
    • Google und Meta erkennen und blockieren bösartiges Verhalten in großen Umgebungen auf Basis der Geschwindigkeit, tiefen Sichtbarkeit und Sicherheitsgarantien von eBPF
  • Neben Sicherheit wird eBPF auch für Networking und Observability (observability) eingesetzt

Grenzen von eBPF und operative Ergänzungen

  • Das Schlimmste, was ein eBPF-Programm tun kann, ist, unerwünscht viele Ressourcen wie CPU-Zyklen oder Speicher zu verbrauchen
  • Verschwenderischen Code verhindert es nicht vollständig, blockiert aber schwerwiegende Probleme, die zu Systemabstürzen führen
  • Auch eBPF ist eine neue Technologie; es gab Fehler im Verwaltungscode, darunter auch einen Linux kernel panic, den dasselbe Sicherheitsunternehmen entdeckt hat, das kürzlich in den Nachrichten war
  • Werden solche Bugs in eBPF behoben, profitieren alle eBPF-Anbieter von der Korrektur, wodurch sich die Gesamtsicherheit schneller verbessern lässt
  • Das Bereitstellungsrisiko endet nicht allein mit eBPF; es bleiben operative Verfahren, die ergänzend eingesetzt werden können
    • Canary-Tests
    • Stufenweise Rollouts
    • Allgemeines Resilience Engineering

Veränderungen, die Käufer einfordern können

  • Wichtig am eBPF-Ansatz ist, dass es sich um eine Softwarelösung handelt, die sowohl im Linux- als auch im Windows-Kernel standardmäßig bereitgestellt wird und für diesen Anwendungsfall bereits übernommen wurde
  • Wenn Unternehmen für kommerzielle Software bezahlen, die Kernel-Treiber oder Kernel-Module enthält, können sie eBPF zur Anforderung machen
  • Unter Linux ist das heute möglich, unter Windows bald
  • Einige Anbieter haben eBPF bereits proaktiv eingeführt, bei anderen kann es den Druck zahlender Kunden brauchen

1 Kommentare

 
GN⁺ 2024-07-23
Meinungen auf Hacker News
  • Wenn man sich die Liste der „Hooks“ ansieht, die eBPF für Windows bereitstellt, wirkt das ziemlich weit von der Realität entfernt. Derzeit geht es im Wesentlichen um eingehende Pakete und Socket-Operationen, also offenbar erwartet Microsoft, dass der Berkeley Packet Filter wortwörtlich für Paketfilterung genutzt wird.
    Das ist etwas anderes als I/O-Filtering, Objekterstellung/-nutzung und die zahlreichen Stellen, an denen Treiber wie der von CrowdStrike im NT-Kernel ansetzen.
    Außerdem muss auch Antimalware im Kernel laufen, wenn sie anderen Third-Party-Müll überwachen soll, der im Kernel-Space läuft. ELAM (Early Launch Anti-Malware) lädt den Antimalware-Treiber zuerst, damit er das Verhalten anderer Treiber überwachen kann; ich bezweifle stark, dass so etwas mit eBPF möglich ist.
    Microsoft hat noch einen sehr langen Weg vor sich, wenn es Kernel-Space-Antimalware-Treiber durch eBPF ersetzen will.
    https://microsoft.github.io/ebpf-for-windows/ebpf__structs_8...

    • Es stimmt, dass eBPF an Ereignisse andocken muss, die denen unter Linux entsprechen, aber Windows hat bereits viele Event-Produzenten und -Konsumenten. Die Aufgabe besteht nicht darin, ein Instrumentierungs-Framework von Grund auf neu zu bauen, sondern eBPF zu einem weiteren Konsumenten zu machen.
      Als Vergleich: Leute erledigen ihre Bankgeschäfte auf Websites mit JavaScript in Google Chrome, während Microsoft Edge sagt: „Wir unterstützen kein JavaScript, bitte laden Sie diese .EXE herunter und führen Sie sie aus.“ Es geht eher nicht darum, „ob“ Microsoft JavaScript oder eBPF unterstützt, sondern „wann“.
    • Microsoft hat bereits die erweiterbare Dateisystem-Filter-Funktion, die aktuelle Antivirenprogramme nutzen. Ich frage mich, ob es sinnvoll ist, darauf eBPF aufzusetzen, und falls ja, ob es Performance-Nachteile gibt, wie man sie bei Dateisystem-Filtern sieht.
    • Nach diesem Vorfall hoffe ich, dass Microsoft stärker in die eBPF-Unterstützung für Windows investiert.
  • Ich möchte mich nicht mit Leuten wie Brendan Gregg streiten, aber ich wünschte, die Anbieter in diesem Bereich würden die gesamte Ausfallkette ganzheitlicher untersuchen. Wenn drei Tage nach einem Ausfall ein Vorschlag kommt, dass „x das Problem behebt, das am Datum y aufgetreten ist“, werde ich vorsichtig.
    Das kann stimmen, aber ohne Analyse können blinde Flecken bleiben, und es kann viele Alternativen geben, die man nach Prüfung sinnvollerweise verwerfen sollte.
    Insbesondere dem Teil, dass „das schlimmste negative Ergebnis nur verschwendete CPU-Zeit ist“, kann ich schwer zustimmen. Für bestimmte Bug-Klassen mag das gelten, aber es gibt genug Ausfallmodi, bei denen ein fehlerhaftes Regelwerk ein System ernsthaft brickt und die Wiederherstellung erschwert.
    Das heißt nicht, dass eBPF-basierte Sicherheitsmodule für viele Anbieter nicht die richtige Wahl sein können; es heißt, dass wir verstehen sollten, welche Risiken sie vermeiden, welche nicht und welchen Teil der Ausfallkette sie adressieren.

    • Nur weil man nicht wusste, dass diese Diskussion seit einigen Jahren läuft, heißt das nicht, dass es sie nicht gab. Das ist keine Analyse, die plötzlich drei Tage nach dem Vorfall aufgetaucht ist, sondern eher ein weitgehend akzeptierter Konsens unter mehreren Fachleuten, die solche neuen APIs eingeführt haben, um unter anderem Stabilität und Sicherheit von Systemen zu verbessern.
    • Microsoft arbeitet mindestens seit einigen Jahren an eBPF.
      https://opensource.microsoft.com/blog/2021/05/10/making-ebpf...
      https://lwn.net/Articles/857215/
      Wenn es echte Bedenken gibt, existieren auch Diskussionskanäle, über die man Feedback geben kann, und sie sind auf GitHub dokumentiert.
      https://github.com/microsoft/ebpf-for-windows
      Vielleicht gibt es bereits Antworten; falls nicht, kann man es dort behandeln.
  • Das stimmt so nicht. Wenn ein System so aufgebaut ist, dass es nur mit einem bestimmten Codefragment läuft, dann sollte das System gar nicht erst starten, wenn dieser Code kaputt ist. Fehler einfach zu ignorieren, ist merkwürdig.
    Wenn zum Beispiel der Treibercode eines medizinischen Geräts eine Sicherheitsverriegelung garantiert, damit es keinen Menschen verbrennt, würde ich eher wollen, dass das Ganze anhält, als dass es bei deaktivierter Sicherheitsvorrichtung ganz normal weiterläuft.
    Am Ende bleibt es, auch wenn man weiter nach unten geht, immer dasselbe Problem.

    • Ich glaube, die Prämisse selbst ist falsch. Was bei fehlerhafter Eingabe passieren soll, kann der eBPF-Implementierer festlegen, und der Kernel kann in diesem Fall auch ein kontrolliertes Beenden wählen.
      Ich weiß nicht, wie Linux das tatsächlich handhabt, aber man kann sich auch eine Welt vorstellen, in der das Verhalten bei fehlerhafter Eingabe konfigurierbar ist.
      Außerdem ist diese Aussage nicht immer wahr. Im Allgemeinen stimme ich zu, aber in manchen Kontexten muss es weiterlaufen. Das Beispiel, das mir sofort einfällt, ist der Führungscomputer eines automatischen Marslanders. Die Roundtrip-Verzögerung zur Erde ist zu lang, um die Verantwortung abzugeben.
      Wenn er sich beendet, stürzt er ab; wenn er in beschädigtem Zustand sein Bestes versucht, stürzt er vermutlich auch nur ab – also könnte Letzteres besser sein.
    • Software für medizinische Geräte kann einfach eine Fehlermeldung ausgeben und den Start verweigern, wenn ein wichtiger Treiber nicht geladen wurde.
      Wenn das gesamte Betriebssystem gebrickt ist, muss ein IT-Techniker es manuell reparieren, was ein viel größeres Problem ist. Andernfalls hätte man nur den fehlerhaften Treiber aktualisieren müssen.
      Ein Auto startet auch nicht deshalb nicht, weil kein Wischwasser mehr da ist.
    • Ich stimme zu, dass manche Systemkomponenten zwingend als kritisch behandelt werden müssen, aber der hier betroffene Falcon Sensor oder typische Antivirenprogramme sind präventiv und ohnehin eher Best-Effort.
      Die meisten Organisationen, die am Freitag betroffen waren, hätten wohl ein leicht erhöhtes Risiko für Malware-Angriffe oder unbefugte Nutzung über 24 Stunden dem tatsächlich erlebten kompletten IT-Zusammenbruch vorgezogen.
      Außerdem musste dieser Bug nicht zwingend einen Bluescreen auslösen. Das System hätte auch in einem undefinierten Zustand mit unbegrenzten Folgen weiterlaufen können.
      Mit eBPF ließe sich zumindest ein Teil der möglichen Fehler erkennen und auf dieser Grundlage eine Risikomanagement-Entscheidung treffen.
    • Aus diesem Grund gefällt mir der Ansatz von Unison. Funktionen werden über kryptografische Hashes aufgerufen, sodass bis zu einem gewissen Grad garantiert ist, dass man dieselbe Funktion aufruft wie gestern.
      Für ein Update muss der Aufrufer eine andere Funktion aufrufen; die Verantwortung liegt also beim Aufrufer und nicht bei jemandem, der den Kernel auf Umwegen beeinflussen kann.
      Wenn es keine Funktion gibt, die dem angegebenen Hash entspricht, kann sie nicht aufgerufen werden; und selbst wenn es sie gibt, kann sie nur auf die vorgesehene Weise aufgerufen werden. So erhält man die gewünschte Eigenschaft „entweder funktioniert es vollständig oder gar nicht“.
    • Das System verhielt sich bereits so, dass es Fehler ignorierte. Denn die tatsächliche Behebung bestand darin, die problematische Datei einfach zu löschen. Wenn das eine Option ist, kann der Loader das ebenfalls tun – oder intelligenter vorgehen, etwa mit „auf die vorherige Version zurücksetzen“.
      Außerdem muss die Reaktion auf einen fehlerhaften Zustand nicht zwingend „ignorieren“ sein. Man könnte eingeschränkte Benutzeranmeldungen deaktivieren oder den Bildschirm ausschalten.
      Falls die Sorge ist, dass Malware das ausnutzen könnte: Wenn Malware bereits die Dateien des Antivirenprogramms auf der Platte umschreiben kann, ist fraglich, ob es eine gute Idee ist zu glauben, dass das System selbst damit umgehen kann.
      Sicherer könnte es sein, an eine übergeordnete Sicherheitsinstanz zu melden und ein externes System die Netzwerkzugriffe deaktivieren oder einschränken zu lassen. Darüber hinaus bräuchte eine solche Maßnahme nur Beobachtungsrechte statt Eingriffsrechte im System, wodurch auch die Wahrscheinlichkeit sinkt, dass das Antivirensystem selbst zum Malware-Pfad oder zur Ursache solcher Bugs wird.
  • eBPF ist hervorragend und kann für viele Zwecke eingesetzt werden und vieles verbessern, aber die Aussage, dass „Computer wegen schlechter Software-Updates nicht abstürzen werden“, wirkt übertrieben.
    Selbst wenn man annimmt, dass BPF selbst keine Bugs hat, ist der Umfang der Kernel-Hooks ziemlich groß; diese Hooks rufen eBPF-Code auf, und dieser Code kann wiederum den Kernel aufrufen.
    https://www.man7.org/linux/man-pages/man7/bpf-helpers.7.html
    Insbesondere bpf_probe_read_kernel() wird sehr häufig verwendet, ist aber nicht sicher. Es gibt zwar erhebliche Bemühungen, OOPS oder Abstürze zu vermeiden, aber perfekt ist das keineswegs.
    Auch in der restlichen Liste gibt es vieles, was ein System leicht kaputtmachen kann, selbst wenn es nicht tatsächlich einen oops oder panic auslöst.
    Und wenn es sich um ein Tool handelt, das „bösartiges Verhalten“ im Userspace erkennen und blockieren soll, kann es anfangen, alles als bösartig einzustufen und den Computer unbenutzbar zu machen.
    Gleichzeitig hat eBPF auf der Userspace-Seite kein echtes Sicherheitsmodell. Das tatsächliche Anhängen von eBPF-Programmen geschieht nicht über vernünftige Berechtigungsoperationen auf dem jeweiligen Kernel-Objekt, an das angehängt wird, sondern über den bpf()-Systemaufruf; außerdem gibt es überhaupt keinen Mechanismus, der von einem Container verwendetes eBPF innerhalb dieses Containers einsperrt. bpf_probe_read_kernel() kann im Grunde den gesamten Kernel-Speicher lesen.
    Der Vorteil von eBPF gegenüber normalem Kernel-C-Code liegt daher darin, dass es dem Schreiben von Code in einer sicheren Sprache mit einer begrenzten unsafe-API-Oberfläche ähnelt. Für solche Aufgaben ist das eine große Verbesserung, aber keineswegs perfekt.
    Es heißt auch, der Verifier sei streng und die Linux-Implementierung umfasse mehr als 20.000 Zeilen, aber der Verifier ist absurd komplex. Statt 20.000 Zeilen handgeschriebener Logik würde ich lieber eine Grundlage auf Basis formaler Methoden sehen.

    • Mich würde interessieren, wie man mit bpf_probe_read_kernel eine panic auslösen kann. Gibt es ein Beispiel, das mit einer aktuellen Kernel-Version funktioniert?
  • Die Aussage „eBPF-Programme werden von einem Software-Verifier auf Sicherheit geprüft und laufen praktisch in einer Sandbox, sie können also nicht das ganze System zum Absturz bringen“ macht mich stutzig.
    Ist es nicht einer der Zwecke eines Betriebssystems, Software zu überwachen? Ich weiß, dass das hier ein Problem betrifft, das mit dem Betriebssystem selbst zu tun hat, aber wenn man eine Schicht hinzufügt, die den Wächter überwacht, muss dann am Ende nicht auch diese Schicht wieder überwacht werden?
    Könnte man sich nicht für weniger Komplexität entscheiden, statt naiv zu glauben, dass neue Komplexität langfristig besser ist?

    • eBPF „überwacht nicht den Wächter“, sondern ist ein Werkzeug, das anderen Tools über eine sehr strikte Sandbox Zugriff auf Low-Level-Elemente des Kernels gibt.
      Der alte Ansatz besteht darin, Kernel-Treiber zu laden, sich in zahlreiche Systemaufrufe einzuklinken und zu hoffen, dass nichts kaputtgeht. Wenn es schiefgeht, kann es zu einer Panic kommen, aber Linux ist ziemlich robust.
      Der eBPF-Ansatz ähnelt eher dem Anfordern der gewünschten Informationen über eBPF-spezifische Instruktionen.
      Eine Übersicht über die Funktionsweise gibt es hier: https://ebpf.io/what-is-ebpf/
    • Man könnte auch einen AI-Chatbot erklären lassen, welcher Rechtfertigungsprozess überhaupt dazu geführt hat, etwas wie CrowdStrike einzusetzen.
  • Klingt nach einer tollen Technologie, aber der wirklich gravierende Punkt ist: „Man kann auch Methoden zur Risikominderung bei Software-Deployments wie Canary-Tests, gestaffelte Rollouts und Resilience Engineering einsetzen.“
    Um grundlegendes, branchenübliches Qualitätsmanagement umzusetzen, braucht man keine neue Technologie.

  • Man könnte anfangen, freitags freizunehmen, um an diesen Vorfall zu erinnern. Wenn Menschen weniger getrieben arbeiten müssten und mehr Zeit hätten, innezuhalten und darüber nachzudenken, wie sich die Dinge entwickeln und welchen Einfluss sie darauf nehmen können, wäre der Schaden möglicherweise geringer gewesen.

  • Die Erklärung, dass der Verifier der Linux-Implementierung über 20.000 Zeilen umfasst und Beiträge aus Industrie und Wissenschaft erhalten hat, beruhigt mich eher nicht. Die zusätzliche Angriffsfläche ist ein Problem, aber wer kann eine so große Codebasis garantieren?

    • Genau das habe ich auch gedacht. Ich weiß nicht, ob die Zahl von 20.000 Zeilen Vertrauen schaffen sollte, aber bei mir hatte sie den gegenteiligen Effekt. Bei 300 Zeilen hätte ich mehr Vertrauen gehabt.
      Der WebAssembly-Verifier wirkt auf mich deutlich einfacher.
  • Wenn ein Filter beim Booten geladen wird und sich in alles einklinkt, kann ein einzelner Bug das System so weit sperren, dass es weder bedient noch gepatcht werden kann. Zum Beispiel, wenn eine leere Allowlist geladen wird; am Ende könnte das eine Boot-Schleife in eine andere Form von Denial of Service verwandeln.
    Wenn Microsoft die für die Wiederherstellung nötigen Kernelemente in eine hartcodierte Allowlist aufnimmt, ließen sich Bugs solcher Tools vielleicht leichter beheben, aber bis der Fix ausgerollt ist, kann es zu realer Downtime kommen, obwohl das System eingeschaltet ist, weil es praktisch nicht nutzbar ist.

  • Im Blogpost steht: „eBPF ist gegen solche Crashes immun.“
    Ich habe gesucht, aber nichts Eindeutiges gefunden, und es sieht für mich weiterhin so aus, als könne man damit etwas kaputtmachen. Es wäre schön, wenn ein eBPF-Experte diese Behauptung erklären könnte. Das Beste, was ich gefunden habe, ist das hier: https://stackoverflow.com/questions/70403212/why-is-ebpf-sai...

    • eBPF-Programme können den Kernel nicht zum Absturz bringen, sofern der eBPF-Verifier keine Bugs hat. In der Vergangenheit gab es solche Bugs, aber sie scheinen immer seltener zu werden.