
Hochgradig konfigurierbares Tool zur Prüfung der Verwundbarkeit eines Servers gegen CVE-2023-44487, indem es schnell HEADERS- und RST_STREAM-Frames sendet und die Antworten des Servers dokumentiert.
CVE-2023-44487 ist ein Exploit gegen das HTTP2-Protokoll selbst. Bei HTTP2 werden Datenanforderungen durch das Senden eines HEADERS-Frames initiiert. Nachdem der Server diesen Frame empfangen hat, beginnt er mit der Verarbeitung deiner Anfrage und sendet anschließend DATA-Frames, bis alle Daten übertragen sind. HTTP2 spezifiziert außerdem einen RST_STREAM-Frame, mit dem ein Stream zu jedem beliebigen Zeitpunkt geschlossen werden kann. Um Angriffe zu verhindern, begrenzen Server normalerweise die maximale Anzahl gleichzeitig geöffneter Streams (standardmäßig auf 100). Wenn Clients tatsächlich darauf warten, dass alle Ressourcen verbraucht werden, wird dieses Limit selten erreicht. Der Angriff funktioniert aus einem einfachen Grund: Ein Client kann einen RST_STREAM-Frame zu jedem Zeitpunkt senden. Ein RST_STREAM-Frame schließt einen Stream, und geschlossene Streams werden nicht als gleichzeitige Streams gezählt. Das bedeutet, dass ein Client Anfragen schnell senden kann, ohne jemals dieses Limit zu erreichen, indem er einfach eine Verbindung direkt nach dem Senden einer Anfrage schließt. Der angegriffene Server beginnt in einigen Fällen weiterhin mit dem Laden der Daten, was eine übermäßige Last erzeugt.
Dieses Tool soll die Verwundbarkeit eines Servers gegenüber diesem Angriff prüfen. Es baut eine oder mehrere gleichzeitige HTTP2-Verbindungen auf und sendet anschließend die angegebene Anzahl von HEADER-Frames, gefolgt von RST_STREAM-Frames.
Es bietet außerdem zahlreiche weitere Konfigurationsoptionen, wie z. B. die Verzögerung zwischen HEADERS- und RST_STREAM-Frames, die Anzahl der zu öffnenden Streams, die Anzahl der pro Stream zu sendenden Frames usw. Nach Abschluss des Angriffs gibt es eine Zusammenfassung aus, die Informationen über die Anzahl der empfangenen Frames sowie die Anzahl der empfangenen Fehler und GOAWAY-Frames enthält. Dies kann dir dabei helfen, festzustellen, ob deine Dienste anfällig für CVE-2023-44487 sind.
Derzeit wird dieses Tool nur als Quellcode verteilt, das heißt, eine Go-Installation ist erforderlich. Das Tool kann mit go run main.go <options> ausgeführt werden. Es gibt außerdem ein Python-Skript, mit dem die in die Datei monitor.log geschriebenen Latenzinformationen grafisch dargestellt werden können.
Darüber hinaus habe ich eine neue Python-Werkzeugsammlung für genauere und umfangreichere Messungen erstellt. Die Datei runner.py im Ordner tooling liest die in deiner config.py definierten Werte (siehe config-sample.py für Details) und führt alle Tests für alle definierten Docker-Container aus. Anschließend führt es den erfolgreichsten Test (höchste Median- + mittlere Latenz) für alle im Array paths definierten Pfade aus. Es erzeugt Plots und Logdateien für jeden durchgeführten Test. Diese Werkzeugsammlung befindet sich noch in der Entwicklung. Ich habe sie nur erstellt, weil ich zu faul war, all diese Tests für unser Forschungspapier manuell durchzuführen. Du kannst gerne einen PR einreichen, um sie zu bereinigen oder sie tatsächlich für mehr als nur unseren Anwendungsfall nutzbar zu machen.
Derzeit sind die folgenden CLI-Optionen implementiert:
Das Tool gibt eine Menge Debug-Informationen sowie eine Zusammenfassung aus. Die Debug-Informationen enthalten Angaben darüber, wie die Verbindung aufgebaut wurde, über den aktuellen Fortschritt und die Art der aktuell gesendeten Frames.
Die Zusammenfassung sieht ungefähr so aus (abhängig von deiner Konfiguration)
####################SUMMARY####################
Packet types received:
PING: 2
HEADERS: 12
SETTINGS: 0
DATA: 11
GOAWAY: 3
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Attack ending reasons (per receiving thread):
GoAway events: 3
Timeout events: 0
Error events: 0
Summary for connection 2
PING: 1
HEADERS: 9
SETTINGS: 0
DATA: 6
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 1
PING: 1
HEADERS: 3
SETTINGS: 0
DATA: 5
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 0
PING: 0
HEADERS: 0
SETTINGS: 0
DATA: 0
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Wenn du denkst, dass weitere Statistiken erhoben werden müssen, zögere nicht, mich zu kontaktieren oder ein Issue zu erstellen!
Dieses Tool ist NUR für Forschungszwecke gedacht. Es ist nicht dafür gedacht, Angriffe gegen Server auszuführen, die dir nicht gehören oder nicht von dir verwaltet werden. Ich übernehme keine Verantwortung für die Richtigkeit der bereitgestellten Statistiken oder für Angriffe und deren Folgen für Server und Dienste.
| Flag | Default | Meaning |
|---|
| frames | 1 | die Anzahl der HEADERS- und RST_STREAM-Frames, die auf einem beliebigen Stream gesendet werden sollen |
| connections | 1 | die Anzahl der TLS-Verbindungen, auf denen der Angriff (gleichzeitig) ausgeführt werden soll |
| consecutiveSends | 1 | Anzahl der HEADERS-Frames, die vor dem Senden von RST_STREAM-Frames gesendet werden sollen (pro Flow) |
| connectAttempts | 1 | Anzahl der aufeinanderfolgenden Verbindungen, auf denen der Test ausgeführt werden soll (pro Verbindungsroutine) |
| delay | 0 | die Wartezeit (in ms) zwischen dem Senden von HEADERS- und RST_STREAM-Frames |
| ignoreGoAway | false | Wenn true, führen GOAWAY-Streams nicht dazu, dass die Empfangsroutine beendet wird. Stattdessen wird gewartet, bis länger als 10 Sekunden kein Frame empfangen wurde. |
| monitor | false | Leistungsüberwachung aktivieren |
| monitorDelay | 100 | die Wartezeit (in ms) zwischen den Tests der Antwortlatenz |
| monitorLog | ./monitor.log | die Datei, in die Monitor-Verzögerungsprotokolle geschrieben werden |
| routines | 1 | die Anzahl der anzugreifenden Streams |
| skipValidation | true | Wenn true, wird das Serverzertifikat nicht validiert (dies ist die Standardeinstellung – uns ist Sicherheit egal, da wir schließlich der Angreifer sind) |
| timeout | 1000 | Zeit, die auf neue Frames gewartet wird, bevor der Verbindungsversuch als ungültig betrachtet und gestoppt wird |
| url | https://localhost:433/ | die URL, gegen die der Angriff ausgeführt werden soll |