Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
HTTP3ONSTEROIDS — HTTP3ONSTEROIDS - A research on CVE-2023-25950 where HAProxy's HTTP/3 implementation fails to block a malformed HTTP header field name. | Kitploit
Tools/GitHubGitHub/dhmosfunk/http3onsteroids
Vulnerability AnalysisWeb Application ExploitationLearning & EducationLabs & Practice
GitHubdhmosfunk/http3onsteroids

HTTP3ONSTEROIDS

HTTP3ONSTEROIDS - A research on CVE-2023-25950 where HAProxy's HTTP/3 implementation fails to block a malformed HTTP header field name.

Repository anzeigen
112vor 1 JahrNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Inhaltsverzeichnis

  • Beschreibung der Sicherheitslücke
    • Quellcode-Überprüfung
  • Lab-Einrichtung
    • Identifizierung des Problems
  • Referenzen

Beschreibung der Sicherheitslücke

Die HTTP/3-Implementierung von HAProxy blockiert einen fehlerhaften HTTP-Header-Feldnamen nicht, und wenn sie vor einem Server eingesetzt wird, der diesen fehlerhaften Header falsch verarbeitet, kann sie für einen HTTP-Request/Response-Smuggling-Angriff verwendet werden. Ein entfernter Angreifer kann eine legitime Benutzeranfrage verändern. Infolgedessen kann der Angreifer vertrauliche Informationen erlangen oder einen Denial-of-Service (DoS)-Zustand verursachen.

https://jvn.jp/en/jp/JVN38170084/

Quellcode-Überprüfung

Ein sehr guter Ansatz vor Beginn einer Forschung zu CVEs ist, die Beschreibung der Sicherheitslücke zu lesen und dann zu prüfen, ob der oder die Commits für den Patch verfügbar sind.
In meinem Fall war der Commit verfügbar, und es ist offensichtlich, dass die Entwickler von HAProxy vergessen haben, die Prüfungen aus RFC 9114 4.1.2. Fehlerhafte Anfragen und Antworten beim Parsen der Standard-Header in der HTTP3-Implementierung zu berücksichtigen.

Siehe den folgenden Patch-Commit.

root@kitploit:~
--- a/src/h3.c
+++ b/src/h3.c
@@ -352,7 +352,27 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
        //struct ist scheme = IST_NULL, authority = IST_NULL;
        struct ist authority = IST_NULL;
        int hdr_idx, ret;
-       int cookie = -1, last_cookie = -1;
+       int cookie = -1, last_cookie = -1, i;
+
+       /* RFC 9114 4.1.2. Malformed Requests and Responses
+        *
+        * A malformed request or response is one that is an otherwise valid
+        * sequence of frames but is invalid due to:
+        * - the presence of prohibited fields or pseudo-header fields,
+        * - the absence of mandatory pseudo-header fields,
+        * - invalid values for pseudo-header fields,
+        * - pseudo-header fields after fields,
+        * - an invalid sequence of HTTP messages,
+        * - the inclusion of uppercase field names, or
+        * - the inclusion of invalid characters in field names or values.
+        *
+        * [...]
+        *
+        * Intermediaries that process HTTP requests or responses (i.e., any
+        * intermediary not acting as a tunnel) MUST NOT forward a malformed
+        * request or response. Malformed requests or responses that are
+        * detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.
+        */
 
        TRACE_ENTER(H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
 
@@ -416,6 +436,14 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                if (isteq(list[hdr_idx].n, ist("")))
                        break;
 
+               for (i = 0; i < list[hdr_idx].n.len; ++i) {
+                       const char c = list[hdr_idx].n.ptr[i];
+                       if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
+                               TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
+                               return -1;
+                       }
+               }
+
                if (isteq(list[hdr_idx].n, ist("cookie"))) {
                        http_cookie_register(list, hdr_idx, &cookie, &last_cookie);
                        continue;

Repositories - haproxy-2.7.git/commit

Unten finden Sie den Code, der das Fehlen der Bereinigung von Header-Namen in der Implementierung zur Behandlung von Standard-Headern in HAProxy 2.7.0 zeigt.

root@kitploit:~
/* 
src/h3.c 
lines: 413 - 428
*/

/* now treat standard headers */
hdr_idx = 0;
while (1) {
    if (isteq(list[hdr_idx].n, ist("")))
        break;
    if (isteq(list[hdr_idx].n, ist("cookie"))) {
        http_cookie_register(list, hdr_idx, & cookie, & last_cookie);
        continue;
    }
    if (!istmatch(list[hdr_idx].n, ist(":")))
        htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v);
    ++hdr_idx;
}

Unten finden Sie den Code, der verwendet wird, um zu prüfen, ob der Header-Name gültig ist.

Der Code beginnt mit einer for-Schleife, die jedes Zeichen eines Header-Feldnamens durchläuft. Die Schleife läuft von i = 0 bis i < list[hdr_idx0.n.len], wobei list ein Array oder eine Struktur ist, die Header-Informationen enthält, und hdr_idx ein Index, der den überprüften bestimmten Header darstellt.
Innerhalb der Schleife extrahiert der Code das aktuelle Zeichen c aus dem Header-Feldnamen. list[hdr_idx].n.ptr[i] greift auf das Zeichen an der i-ten Position im Header-Feldnamen zu. Der nächste Teil des Codes enthält eine if-Anweisung. Sie prüft, ob das aktuelle Zeichen c eine der beiden Bedingungen erfüllt:

  • (uint8_t)(c - 'A') < 'Z' - 'A': Dies prüft, ob das Zeichen ein Großbuchstabe (A bis Z) ist, indem 'A' von c subtrahiert und das Ergebnis in uint8_t umgewandelt wird. Wenn das Ergebnis kleiner als die Differenz zwischen 'Z' und 'A' ist, ist das Zeichen ein Großbuchstabe.
  • !HTTP_IS_TOKEN(c): Diese Bedingung prüft, ob das Zeichen ein gültiges HTTP-Token-Zeichen ist. HTTP_IS_TOKEN funktioniert, indem zuerst geprüft wird, ob der Header-Name Token enthält. Ein Token ist eine Zeichenfolge, die kein reserviertes Zeichen im HTTP-Protokoll ist. Reservierte Zeichen sind Zeichen mit besonderer Bedeutung im HTTP-Protokoll, z.B. :, /, ? und #.
root@kitploit:~
/* 
src/h3.c 
lines: 439 - 445
*/
for (i = 0; i < list[hdr_idx].n.len; ++i) {
    const char c = list[hdr_idx].n.ptr[i];
    if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
        TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME | H3_EV_RX_HDR, qcs -> qcc -> conn, qcs);
        return -1;
    }
}

Lab-Einrichtung

Das gesamte Lab läuft auf Docker. Sie können das Lab mit den folgenden Befehlen ausführen:

  1. cd /lab
  2. docker-compose up --build

Bitte beachten Sie, dass der Docker-Build 15–20 Minuten dauert.
Bevor Sie das Lab ausführen, müssen Sie jedoch einige Konfigurationsänderungen vornehmen:

/lab/haproxy/conf/haproxy.cfg

root@kitploit:~
...
default_backend api_server

backend api_server
  balance roundrobin
  server api_server [YOUR-LOCAL-IPv4]:8080 # replace with local IPv4

/etc/hosts

root@kitploit:~
[YOUR-LOCAL-IPv4]   foo.com

/lab/docker-compose.yml
Sie können zwischen der anfälligen Version und der gepatchten Version wählen, indem Sie den Wert des Arguments auf 'vuln' oder 'patched' ändern, um Ihren Test darauf durchzuführen.

root@kitploit:~
...
    args:
        - haproxy_version=patched || vuln
...

und importieren Sie schließlich das minica.crt-Zertifikat in Ihren Browser.

⚠️ Bitte führen Sie das Lab in einer Linux-Umgebung aus.

Identifizierung des Problems

Senden der folgenden curl-Anfrage:

  • curl --http3 -H "foooooo\r\n: barr" -iL -k https://192.168.1.104/

Antwort der anfälligen Version:

root@kitploit:~
HTTP/3 200 
server: Werkzeug/2.3.6 Python/3.8.17  
date: Sat, 12 Aug 2023 13:10:52 GMT   
content-type: text/html; charset=utf-8
content-length: 76
alt-svc: h3=":443";ma=900;

Host: 192.168.1.104
User-Agent: curl/8.1.2-DEV
Accept: */*
Foooooo\R\N: barr <-- Malformed header

Antwort der gepatchten Version:

root@kitploit:~
curl: (56) HTTP/3 stream 0 reset by server

Basierend auf den obigen Erkenntnissen zeigen die entsprechenden Antworten, dass die anfällige Version von HAProxy das \r\n-Präfix zum Backend-Server durchgelassen hat, während die gepatchte Version die Verbindung zwischen Client und HAProxy abgebrochen hat.


Ein Angreifer kann einen HTTP-Request-Smuggling-Angriff basierend auf dem Backend-Verhalten und der Art und Weise, wie der Backend-Server den fehlerhaften Header behandelt, durchführen. Meiner Ansicht nach besteht die größte Sorge darin, dass ein Angreifer die oben genannte CVE ausnutzen könnte, um einen Denial-of-Service (DoS)-Angriff durchzuführen.

Referenzen:

https://jvn.jp/en/jp/JVN38170084/
https://github.com/haproxytechblog/haproxy-2.6-http3
https://www.haproxy.com/blog/how-to-enable-quic-load-balancing-on-haproxy
https://git.haproxy.org/
https://github.com/jsha/minica
https://curl.se/docs/http3.html

Tool herunterladen