Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
HTTP3ONSTEROIDS — PoC e ambiente lab per CVE-2023-25950: HTTP request smuggling tramite campi header malformati nell'implementazione HTTP/3 di HAProxy, che consente DoS e furto di dati. | Kitploit
Strumenti/GitHubGitHub/dhmosfunk/http3onsteroids
Analisi delle VulnerabilitàSfruttamento di Applicazioni WebApprendimento e FormazioneLab e Pratica
GitHubdhmosfunk/http3onsteroids

HTTP3ONSTEROIDS

PoC e ambiente lab per CVE-2023-25950: HTTP request smuggling tramite campi header malformati nell'implementazione HTTP/3 di HAProxy, che consente DoS e furto di dati.

Vedi Repository
112111 anno faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Indice

  • Descrizione della vulnerabilità
    • Analisi del codice sorgente
  • Configurazione del laboratorio
    • Identificazione del problema
  • Riferimenti

Descrizione della vulnerabilità

L'implementazione HTTP/3 di HAProxy non riesce a bloccare un nome di campo header HTTP malformato, e quando implementato davanti a un server che elabora erroneamente questo header malformato, può essere utilizzato per condurre un attacco di smuggling di richieste/risposte HTTP. Un attaccante remoto può alterare una richiesta di un utente legittimo. Di conseguenza, l'attaccante può ottenere informazioni sensibili o causare una condizione di denial-of-service (DoS).

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

Analisi del codice sorgente

Un ottimo approccio prima di iniziare qualsiasi ricerca su CVE è iniziare leggendo la descrizione della vulnerabilità e poi verificare se i commit per la correzione sono disponibili.
Nel mio caso, il commit era disponibile, ed è evidente che gli sviluppatori di HAProxy hanno dimenticato di includere i controlli della RFC 9114 4.1.2. Richieste e Risposte Malformate durante l'analisi degli header standard nell'implementazione di HTTP3.

Fai riferimento al commit di patch qui sotto.

--- 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;

Repository - haproxy-2.7.git/commit

Di seguito, puoi trovare il codice che dimostra l'assenza di sanificazione dei nomi degli header nell'implementazione della gestione degli header standard su HAProxy 2.7.0.

/* 
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;
}

Di seguito, puoi trovare il codice che viene utilizzato per verificare se il nome dell'header è valido.

Il codice inizia con un ciclo for che itera attraverso ogni carattere di un nome di campo header. Il ciclo va da i = 0 a i < list[hdr_idx0.n.len], dove list è un array o struttura contenente informazioni sugli header, e hdr_idx è un indice che rappresenta l'header specifico che viene controllato.
All'interno del ciclo, il codice estrae il carattere corrente c dal nome del campo header. list[hdr_idx].n.ptr[i] accede al carattere alla posizione i-esima del nome del campo header. La parte successiva del codice contiene un'istruzione if. Controlla se il carattere corrente c soddisfa una delle due condizioni:

  • (uint8_t)(c - 'A') < 'Z' - 'A': Questo controlla se il carattere è una lettera maiuscola (da A a Z) sottraendo 'A' da c e convertendo il risultato in uint8_t. Se il risultato è minore della differenza tra 'Z' e 'A', allora il carattere è una lettera maiuscola.
  • !HTTP_IS_TOKEN(c): Questa condizione controlla se il carattere è un carattere token HTTP valido. HTTP_IS_TOKEN funziona controllando prima se il nome dell'header contiene token. Un token è una sequenza di caratteri che non è un carattere riservato nel protocollo HTTP. I caratteri riservati sono caratteri che hanno un significato speciale nel protocollo HTTP, ad esempio :, /, ? e #.
/* 
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;
    }
}

Configurazione del laboratorio

L'intero laboratorio è eseguito su Docker. Puoi avviare il laboratorio con i seguenti comandi:

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

Nota che la build Docker impiegherà 15-20 minuti per terminare.
Tuttavia, prima di eseguire il laboratorio, devi apportare alcune modifiche di configurazione:

/lab/haproxy/conf/haproxy.cfg

...
default_backend api_server

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

/etc/hosts

[YOUR-LOCAL-IPv4]   foo.com

/lab/docker-compose.yml
Puoi scegliere tra la versione vulnerabile e quella corretta cambiando il valore dell'argomento in 'vuln' o 'patched' per condurre il tuo test.

...
    args:
        - haproxy_version=patched || vuln
...

e infine importa il certificato minica.crt nel tuo browser.

⚠️ Esegui il laboratorio in un ambiente Linux.

Identificazione del problema

Inviando la seguente richiesta curl:

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

Risposta della versione vulnerabile:

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

Risposta della versione corretta:

curl: (56) HTTP/3 stream 0 reset by server
Scarica lo strumento