1 Punkte von GN⁺ 2023-10-11 | 1 Kommentare | Auf WhatsApp teilen
  • Ein HTTP/2-basierter Layer-7-DDoS-Angriff auf Google-Dienste und Google-Cloud-Kunden erreichte im August 2023 seinen Höhepunkt und überschritt maximal 398 Millionen Anfragen pro Sekunde
  • Der Angriff wurde größtenteils durch Googles globale Load-Balancing-Infrastruktur abgewehrt und führte zu keinem Ausfall; anschließend wurden zusätzliche Schutzmaßnahmen zur Abschwächung ähnlicher Angriffe eingeführt
  • Rapid Reset bricht direkt nach einer Anfrage mit einem RST_STREAM-Frame nur den Stream ab und hält die Verbindung offen, um Begrenzungen für gleichzeitige Streams zu umgehen und wiederholt Anfragen zu erzeugen
  • Server können auch bei abgebrochenen Anfragen Arbeiten wie Header-Dekomprimierung, URL-Mapping oder Backend-Proxying durchführen, wodurch eine große Kostenasymmetrie entsteht
  • HTTP/2-Betreiber sollten ihre Exponierung prüfen und Patches einspielen; bei erkannter missbräuchlicher Nutzung ist das Beenden der TCP-Verbindung selbst statt einzelner Anfragen die zentrale Gegenmaßnahme

Angriffsumfang und Googles Reaktion

  • Google-Dienste und Cloud-Kunden wurden Ziel eines HTTP/2-basierten Layer-7-DDoS-Angriffs, der im August 2023 seinen Höhepunkt erreichte
  • Der größte Angriff überschritt 398 Millionen Anfragen pro Sekunde und war damit weit größer als zuvor gemeldete Layer-7-Angriffe
  • Googles globale Load-Balancing-Infrastruktur blockierte den Großteil des Angriffs am Netzwerk-Edge
    • Es kam zu keinem Ausfall
    • Die Auswirkungen blieben begrenzt
  • Das Google DDoS Response Team untersuchte den Angriff und implementierte zusätzliche Schutzmaßnahmen, um ähnliche Angriffe zu reduzieren
  • Google leitete gemeinsam mit Branchenpartnern ein koordiniertes Offenlegungsverfahren, um den neuen HTTP/2-Angriffsvektor zu adressieren

Warum HTTP/2 DDoS-Angriffe begünstigen kann

  • Seit Ende 2021 basierte ein großer Teil der bei Googles 1st-Party-Diensten und durch Cloud Armor geschützten Google-Cloud-Projekten beobachteten Layer-7-DDoS-Angriffe auf HTTP/2
    • Sowohl gemessen an der Zahl der Angriffe
    • Als auch gemessen an den maximalen Anfrageraten
  • Die Effizienz von HTTP/2 kann nicht nur legitimen Clients zugutekommen, sondern auch DDoS-Angriffe effizienter machen
  • Stream-Multiplexing

    • HTTP/2 überträgt Frames zwischen Endpunkten über eine bidirektionale Abstraktion namens Stream
    • Durch Stream-Multiplexing können mehrere Anfragen gleichzeitig über eine einzige TCP-Verbindung verarbeitet werden
    • Eine wesentliche Einschränkung bei Layer-7-DoS-Angriffen ist die Zahl gleichzeitiger Transportverbindungen
      • Jede Verbindung benötigt Betriebssystemspeicher für Socket-Records und Puffer
      • Der TLS-Handshake benötigt CPU-Zeit
      • Es ist ein eindeutiges 4-Tupel aus den beiden IP-Adressen und Port-Paaren erforderlich
    • HTTP/1.1 verarbeitet Anfragen in der Regel seriell, sodass die Anfragerate einer einzelnen Verbindung ungefähr bei einer Anfrage pro Round-Trip-Zeit liegt
    • Bei HTTP/2 können über eine einzige TCP-Verbindung mehrere gleichzeitige Streams geöffnet werden, wobei jeder Stream einer HTTP-Anfrage entspricht
    • In realen Umgebungen können Clients pro Anfrage 100 Streams öffnen und Server diese parallel verarbeiten, sodass der effektive Durchsatz einer einzelnen Verbindung auf etwa 100 Anfragen pro Round-Trip steigen kann
    • Dadurch kann die Verbindungsauslastung gegenüber HTTP/1.1 um nahezu den Faktor 100 steigen

Funktionsweise von Rapid Reset

  • HTTP/2 ermöglicht es Clients, dem Server durch Senden eines RST_STREAM-Frames mitzuteilen, dass ein vorheriger Stream abgebrochen wird
  • Für den Abbruch ist keine separate Abstimmung zwischen Client und Server erforderlich
    • Der Client kann einseitig abbrechen
    • Es kann davon ausgegangen werden, dass ein Server, der einen RST_STREAM-Frame empfängt, den Abbruch vor anderen Daten auf derselben TCP-Verbindung anwendet
  • Rapid Reset beruht darauf, direkt nach dem Senden eines Anfrage-Frames einen RST_STREAM-Frame zu senden
    • Der Gegen-Endpunkt wird dazu gebracht, mit der Arbeit zu beginnen, danach wird die Anfrage schnell zurückgesetzt
    • Die Anfrage wird abgebrochen, die HTTP/2-Verbindung bleibt jedoch geöffnet
  • Der Angriffsablauf ist einfach
    • Wie bei einem Standard-HTTP/2-Angriff werden viele Streams auf einmal geöffnet
    • Es wird nicht auf die Antwort des Servers oder Proxys gewartet
    • Jede Anfrage wird sofort abgebrochen
  • Wenn ein sofortiger Reset möglich ist, kann jede Verbindung faktisch unbegrenzt viele Anfragen in einen laufenden Zustand versetzen
    • Der Angreifer überschreitet die Begrenzung für gleichzeitig offene Streams nicht explizit
    • Die Zahl laufender Anfragen hängt stärker von der verfügbaren Netzwerkbandbreite als von der Round-Trip-Zeit (RTT) ab
  • Typische HTTP/2-Serverimplementierungen müssen möglicherweise auch für abgebrochene Anfragen Arbeit leisten
    • Allokation einer neuen Stream-Datenstruktur
    • Parsen der Query
    • Dekomprimierung der Header
    • Mapping der URL auf Ressourcen
  • In Reverse-Proxy-Implementierungen kann eine Anfrage an Backend-Server weitergeleitet werden, bevor der RST_STREAM-Frame verarbeitet wird
  • Da der Client kaum Kosten für das Senden der Anfrage trägt, entsteht zwischen Server und Client eine ausnutzbare Kostenasymmetrie
  • Wird die Anfrage abgebrochen, bevor eine Antwort geschrieben wird, sendet der Reverse-Proxy-Server keine Antwort, wodurch auch die Downlink-Bandbreite vom Server oder Proxy in Richtung Angreifer sinkt

Beobachtete Angriffsvarianten

  • In den Wochen nach dem ersten DDoS wurden Varianten von Rapid Reset beobachtet
  • Diese Varianten sind zwar nicht so effizient wie die ursprüngliche Methode, können aber weiterhin effizienter sein als Standard-HTTP/2-DDoS-Angriffe
  • Batch-Cancel-Variante

    • Die erste Variante bricht Streams nicht sofort ab, sondern öffnet ein Bündel von Streams, wartet kurz und bricht sie dann auf einmal ab
    • Direkt nach dem Abbruch wird erneut ein großes Bündel von Streams geöffnet, um den Angriff fortzusetzen
    • Diese Methode kann Gegenmaßnahmen umgehen, die nur auf dem Anteil eingehender RST_STREAM-Frames basieren
      • Beispiel: Eine Richtlinie, die pro Verbindung maximal 100 RST_STREAM pro Sekunde erlaubt und die Verbindung bei Überschreitung schließt
    • Da die Verbindungsauslastung nicht maximiert wird, sinkt der wichtigste Vorteil des Abbruchangriffs
    • Dennoch kann sie implementierungsseitig effizienter sein als Standard-HTTP/2-DDoS-Angriffe, sodass reine Begrenzungen der Stream-Abbruchrate recht streng sein müssten
  • Variante ohne Abbruch

    • Die zweite Variante bricht Streams überhaupt nicht ab
    • Stattdessen versucht sie optimistisch, mehr Streams zu öffnen, als der Server als Anzahl gleichzeitiger Streams angekündigt hat
    • Die Anfrage-Pipeline kann dadurch dauerhaft gefüllt bleiben, was den RTT-Flaschenhals zwischen Client und Proxy verringern kann
    • Wenn HTTP/2-Server mit sofort antwortenden Ressourcen angegriffen werden, kann auch der RTT-Flaschenhals zwischen Proxy und Server beseitigt werden
    • Die aktuelle HTTP/2-RFC, RFC 9113, schlägt vor, bei Versuchen, zu viele Streams zu öffnen, nicht die gesamte Verbindung, sondern nur die Streams oberhalb des Limits ungültig zu machen
    • Da die meisten HTTP/2-Server überschüssige Streams nicht verarbeiten, können sie unmittelbar nach der Antwort auf einen vorherigen Stream fast sofort einen neuen Stream annehmen und verarbeiten; dadurch wird die Variante ohne Abbruch möglich

Abwehrstrategien

  • Diese Angriffsfamilie lässt sich durch das Blockieren einzelner Anfragen allein nur schwer praktikabel abwehren
  • Wenn Missbrauch erkannt wird, muss die gesamte TCP-Verbindung geschlossen werden
  • HTTP/2 unterstützt das Beenden von Verbindungen über den Frame-Typ GOAWAY
  • Die RFC definiert ein schrittweises Beendigungsverfahren: Zunächst wird ein informativer GOAWAY gesendet, der das Öffnen neuer Streams nicht einschränkt, und nach einem Round-Trip ein weiterer GOAWAY, der zusätzliche Stream-Öffnungen untersagt
  • Ein solches schrittweises GOAWAY-Verfahren ist gegenüber bösartigen Clients jedoch oft nicht robust genug
    • Die Verbindung bleibt Rapid-Reset-Angriffen zu lange ausgesetzt
    • Eingehende Anfragen werden nicht gestoppt
  • Für Abwehrzwecke sollte GOAWAY so konfiguriert sein, dass es die Erstellung von Streams sofort begrenzt
  • Missbräuchliche Verbindungen erkennen

    • Dass ein Client Anfragen abbricht, ist nicht immer missbräuchlich
    • Die Abbruchfunktion von HTTP/2 dient dazu, die Anfrageverarbeitung besser zu steuern
      • Wenn ein Nutzer eine Seite verlässt und der Browser die angeforderten Ressourcen nicht mehr benötigt
      • Anwendungen, die Long Polling mit clientseitigem Timeout verwenden
    • Gegenmaßnahmen konzentrieren sich darauf, Verbindungsstatistiken zu verfolgen und anhand mehrerer Signale sowie Business-Logik den Nutzen jeder Verbindung zu bewerten
    • Wenn eine Verbindung beispielsweise mehr als 100 Anfragen aufweist und davon über 50 % abgebrochen wurden, kann sie als Kandidat für Gegenmaßnahmen gelten
    • Umfang und Art der Reaktion hängen vom plattformspezifischen Risiko ab
      • Ein erzwungener GOAWAY-Frame
      • Sofortiges Beenden der TCP-Verbindung
    • Zur Abwehr der Variante ohne Abbruch wird HTTP/2-Servern empfohlen, Verbindungen zu schließen, die das Limit für gleichzeitige Streams überschreiten
      • Entweder sofort
      • Oder nach wenigen wiederholten Verstößen

Anwendbarkeit auf HTTP/3

  • Aufgrund von Protokollunterschieden geht Google nicht davon aus, dass diese Angriffsmethode direkt auf HTTP/3 (QUIC) anwendbar ist
  • Derzeit beobachtet Google nicht, dass HTTP/3 als Vektor für groß angelegte DDoS-Angriffe genutzt wird
  • Dennoch wird HTTP/3-Serverimplementierungen empfohlen, proaktiv Mechanismen zu implementieren, die die Arbeitsmenge einer einzelnen Transportverbindung begrenzen
    • In ähnlicher Richtung wie die diskutierten HTTP/2-Gegenmaßnahmen

Branchenkoordination und CVE

  • Bereits zu Beginn der Untersuchung durch das Google DDoS Response Team wurde deutlich, dass dieser Angriffstyp breite Auswirkungen auf alle Dienste haben könnte, die HTTP/2 anbieten
  • Google nutzte bestehende Gruppen für koordinierte Schwachstellenoffenlegung, um ein koordiniertes Offenlegungsverfahren zu leiten
  • Das Offenlegungsverfahren konzentrierte sich darauf, große HTTP/2-Implementierer zu informieren
    • Infrastrukturunternehmen
    • Anbieter von Serversoftware
  • Ziel der Vorabinformation war es, Gegenmaßnahmen zu entwickeln und für einen koordinierten Veröffentlichungstermin vorzubereiten
  • In der Vergangenheit führte ein solcher Ansatz bereits dazu, dass Dienstanbieter breitflächig Schutzmaßnahmen einführten oder Softwareupdates für mehrere Pakete und Lösungen bereitstellten
  • Zur Nachverfolgung von Korrekturen in mehreren HTTP/2-Implementierungen wurde während des koordinierten Offenlegungsverfahrens CVE-2023-44487 reserviert

Was Betreiber von HTTP/2-Diensten tun sollten

  • Dieser Angriff kann Dienste jeder Größenordnung erheblich beeinträchtigen
  • Alle Anbieter, die HTTP/2-Dienste bereitstellen, sollten ihre Exponierung gegenüber diesem Problem bewerten
  • Software-Patches und Updates für gängige Webserver und Programmiersprachen können jetzt oder in naher Zukunft verfügbar sein
  • Es wird empfohlen, bereitgestellte Korrekturen so schnell wie möglich einzuspielen
  • Google-Cloud-Kunden wird empfohlen, neben Software-Patches den Application Load Balancer und Google Cloud Armor zu verwenden
    • Google Cloud Armor hat Google und bestehende Nutzer von Google Cloud Application Load Balancing geschützt

1 Kommentare

 
GN⁺ 2023-10-11
Meinungen auf Hacker News
  • Verwandte laufende Threads:
    Der bisher größte DDoS-Angriff, mit einem Spitzenwert von über 398 Millionen Requests pro Sekunde - https://news.ycombinator.com/item?id=37831062
    HTTP/2-Zero-Day-Schwachstelle führt zu rekordverdächtigen DDoS-Angriffen - https://news.ycombinator.com/item?id=37830998

  • Schön zu sehen, dass das HAProxy-Team diese Art von Problem in HTTP/2 offenbar schon 2018 erkannt und entschärft hat: https://www.mail-archive.com/haproxy@formilux.org/msg44134.h...

  • Bei einer typischen HTTP/2-Serverimplementierung muss auch für abgebrochene Requests einiges erledigt werden: neue Stream-Datenstrukturen anlegen, die Anfrage parsen, Header dekomprimieren, die URL auf Ressourcen abbilden usw.
    In Reverse-Proxy-Implementierungen kann der Request sogar an den Backend-Server weitergeleitet werden, bevor der RST_STREAM-Frame verarbeitet wird. Der Client hat dagegen kaum Kosten, um den Request zu senden; dadurch entsteht zwischen Server und Client eine ausnutzbare Kostenasymmetrie
    Es ist erstaunlich, dass man das beim Design von HTTP/2 nicht vorhergesehen hat. Amplification-Angriffe waren aus anderen Protokollen bereits gut bekannt. Ebenso überraschend ist, dass dieser Angriff erst so spät ans Licht kam; möglicherweise war HTTP/2 bis vor Kurzem aber noch nicht breit genug ausgerollt, um ein lohnendes Ziel zu sein

    • Streng genommen ist das kein Amplification-Angriff. Es ist eher eine deutlich effizientere Nutzung einer TCP-Verbindung
    • Ich war auch überrascht, aber wenn man sich die Zeitleiste ansieht: RST_STREAM gab es schon in frühen Versionen von SPDY, und SPDY scheint im Wesentlichen um 2009 herum entworfen worden zu sein
      Angriffe wie Slowloris kamen ungefähr zur selben Zeit auf, waren damals aber nicht weithin bekannt. SYN-Cookies wurden dagegen schon 1996 eingeführt; historische Vorbilder für Angriffe, bei denen das Opfer Y zahlt und der Angreifer X, gibt es also eindeutig
    • Wie bei den meisten solcher Dinge haben es wahrscheinlich schon viele unbedeutende Leute gesehen und ausprobiert
      Das Besondere ist eher, dass jemand es ernsthaft gegen Google versucht hat
  • Im Grunde brauchte man HTTP/2, um Werbung, Tracker und aufgeblähte Frontend-Frameworks schneller auszuliefern. Jetzt liefert es auch Angriffe schneller aus

    • HTTP/2 macht das Surfen über Verbindungen mit hoher Latenz deutlich erträglicher. Im Allgemeinen lädt es Webseiten auch schneller
      Zum Glück funktioniert HTTP/1.1 weiterhin. Wenn dir dieses Protokoll nicht gefällt, kannst du HTTP/1.1 jederzeit in den Browser-Einstellungen und auf dem Webserver aktivieren
    • Heißt das, HTTP/2 sei nicht nötig gewesen? Wenn ja, was wäre eine realistische Alternative?
  • Noch ein Grund, das zugrunde liegende Protokoll klein zu halten. HTTP/2 existiert, wenn man SPDY mitzählt, seit über zehn Jahren, und diese Angriffsart kommt erst jetzt ans Licht
    Ich frage mich, welche Überraschungen in HTTP/3 und QUIC stecken

    • DNS ist ein kleines Protokoll und wird trotzdem von DDoS-Angreifern weltweit für Reflection-Angriffe missbraucht
    • QUIC hat Amplification-Angriffe im Design nicht richtig berücksichtigt, und Leute, die das früh problematisierten, wurden ignoriert
    • HTTP/2 ist ziemlich klein
  • „Abbrechen“ sollte ebenfalls auf die Liste der „schwierigen Probleme der Informatik“ gesetzt werden
    Wie die anderen Dinge auf dieser Liste, etwa Off-by-one-Fehler oder Cache-Invalidierung, ist es in der Praxis nicht übermäßig schwierig, wird aber leicht unterschätzt und übersehen. Wenn man nur halb so viel Zeit in das Design von Zerstörung, Aufräumen, Tear-down und Abbruch stecken würde wie in Erzeugung, Konstruktoren und Initialisierung, gäbe es wohl deutlich weniger Resource-Exhaustion-Bugs

    • Was Rusts Async-Modell großartig macht: Es kann an jedem await-Punkt ein Future sofort abbrechen und den gesamten Call Stack mit abbrechen, ohne dass einzelne Aufrufe kooperieren müssen
    • Für C-Libraries stimmt das definitiv. POSIX-Thread-Cancellation ist eine Funktion, deren bloße Existenz ihre Implikationen überall durchsickern lässt
  • Ich möchte alle daran erinnern, dass Google das Unternehmen ist, das HTTP/2 entwickelt hat
    Jetzt stellen sie es so dar, als würden sie uns heldenhaft vor einem Problem retten, das sie selbst geschaffen haben, erwähnen aber nicht, dass sie es selbst geschaffen haben. Diese Unverfrorenheit der Tech-Konzerne. Microsoft hat das jahrzehntelang genauso gemacht

    • Sie haben versucht, ein Problem zu lösen, das nicht existierte
  • Kann jemand erklären, was an diesem Angriff im Vergleich zu einer gewöhnlichen Request-Flood neu ist?

    • Es hängt davon ab, was du als „Request-Flood“-Angriff betrachtest
      Bei HTTP/1.1 konnte man einen Request pro Round-Trip-Time senden[0]. Mit HTTP/2-Multiplexing kann man 100 pro Round-Trip-Time senden. Bei diesem Angriff kann man praktisch unbegrenzt viele Requests pro Round-Trip-Time senden. Ich hoffe, die Diagramme im Artikel zeigen den Unterschied; vielleicht meinst du aber auch eine andere Art von Angriff als die oben beschriebene
      [0] Wenn man HTTP/1.1-Pipelining berücksichtigt, lässt sich zwar ein Round-Trip-Time-Faktor einsparen, aber echte Clients nutzen HTTP/1.1-Pipelining kaum, sodass dessen Nutzung selbst ein sehr klares Signal für bösartigen Traffic ist
    • Die beschriebene neue Technik umgeht die Obergrenze für die Anzahl von Requests pro Sekunde und Client, die ein Angreifer den Server verarbeiten lassen kann
      Wenn man innerhalb einer einzigen Verbindung Requests zusammen mit Stream-Resets sendet, kann man pro Verbindung/Client mehr Requests senden als früher; dadurch können die Angriffskosten sinken oder das Blockieren schwieriger werden
  • Der Blog-Header springt ständig hervor und macht die Seite unlesbar