Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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 — HTTP3ONSTEROIDS - Una ricerca su CVE-2023-25950 dove l'implementazione HTTP/3 di HAProxy non riesce a bloccare un nome di campo header HTTP malformato. | Kitploit
Strumenti/GitHubGitHub/dhmosfunk/http3onsteroids
Analisi delle VulnerabilitàSfruttamento di Applicazioni WebApprendimento e FormazioneLab e Pratica
GitHubdhmosfunk/http3onsteroids

HTTP3ONSTEROIDS

HTTP3ONSTEROIDS - Una ricerca su CVE-2023-25950 dove l'implementazione HTTP/3 di HAProxy non riesce a bloccare un nome di campo header HTTP malformato.

Vedi Repository
1121 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.

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;

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.

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

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 #.
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;
    }
}

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

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
Puoi scegliere tra la versione vulnerabile e quella corretta cambiando il valore dell'argomento in 'vuln' o 'patched' per condurre il tuo test.

root@kitploit:~
...
    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:

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

Risposta della versione corretta:

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

Sulla base dei risultati sopra, le corrispondenti risposte indicano che la versione vulnerabile di HAProxy ha permesso al prefisso \r\n di passare al server backend, mentre la versione corretta ha interrotto la connessione tra il client e HAProxy.


Un attaccante può condurre un attacco di HTTP Request Smuggling basato sul comportamento del backend e su come il server backend tratterà l'header malformato. A mio avviso, la preoccupazione più significativa è che un attaccante potrebbe sfruttare il suddetto CVE per effettuare un attacco Denial of Service (DoS).

Riferimenti:

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

Scarica lo strumento