Request Smuggling in HTTP/2 Downgrades

Reading time: 6 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

HTTP/2 jest ogólnie uważany za odporny na klasyczne request-smuggling, ponieważ długość każdej ramki DATA jest jawna. Ta ochrona znika, gdy front-end proxy „downgraduje” żądanie do HTTP/1.x przed przesłaniem go do back-endu. W momencie, gdy dwa różne parsery (front-end HTTP/2 i back-end HTTP/1) próbują ustalić, gdzie kończy się jedno żądanie, a zaczyna następne, wszystkie stare sztuczki desynchronizacji wracają – plus kilka nowych.


Dlaczego dochodzi do downgrade'ów

  1. Przeglądarki już obsługują HTTP/2, ale wiele starszych infrastruktur źródłowych wciąż rozumie tylko HTTP/1.1.
  2. Reverse-proxy (CDN, WAF, load-balancery) zatem kończą TLS + HTTP/2 na krawędzi i przepisywują każde żądanie jako HTTP/1.1 dla źródła.
  3. Krok tłumaczenia musi stworzyć oba nagłówki Content-Length i/lub Transfer-Encoding: chunked, aby źródło mogło określić długość ciała.

Kiedy front-end ufa długości ramki HTTP/2 ale back-end ufa CL lub TE, atakujący może zmusić je do niezgodności.


Dwie dominujące klasy prymitywów

WariantDługość front-enduDługość back-enduTypowy ładunek
H2.TEramka HTTP/2Transfer-Encoding: chunkedOsadź dodatkowe ciało wiadomości chunked, którego końcowe 0\r\n\r\n nie jest wysyłane, więc back-end czeka na „następne” żądanie dostarczone przez atakującego.
H2.CLramka HTTP/2Content-LengthWyślij mniejszy CL niż rzeczywiste ciało, aby back-end czytał poza granicą do następnego żądania.

Te są identyczne w duchu z klasycznymi TE.CL / CL.TE, tylko z HTTP/2 zastępującym jeden z parserów.


Identyfikacja łańcucha downgrade'ów

  1. Użyj ALPN w handshake TLS (openssl s_client -alpn h2 -connect host:443) lub curl:
bash
curl -v --http2 https://target

Jeśli pojawi się * Using HTTP2, krawędź obsługuje H2. 2. Wyślij celowo źle sformułowane żądanie CL/TE przez HTTP/2 (Burp Repeater ma teraz rozwijane menu, aby wymusić HTTP/2). Jeśli odpowiedź to błąd HTTP/1.1, taki jak 400 Bad chunk, masz dowód, że krawędź przekształciła ruch dla parsera HTTP/1 w dół.


Workflow eksploatacji (przykład H2.TE)

http
:method: POST
:path: /login
:scheme: https
:authority: example.com
content-length: 13      # ignored by the edge
transfer-encoding: chunked

5;ext=1\r\nHELLO\r\n
0\r\n\r\nGET /admin HTTP/1.1\r\nHost: internal\r\nX: X
  1. Front-end odczytuje dokładnie 13 bajtów (HELLO\r\n0\r\n\r\nGE), myśli, że żądanie jest zakończone i przesyła tyle do źródła.
  2. Back-end ufa nagłówkowi TE, kontynuuje odczyt, aż zobaczy drugie 0\r\n\r\n, tym samym konsumując prefiks drugiego żądania atakującego (GET /admin …).
  3. Reszta (GET /admin …) jest traktowana jako nowe żądanie w kolejce za żądaniem ofiary.

Zamień przemycone żądanie na:

  • POST /api/logout, aby wymusić utrwalenie sesji
  • GET /users/1234, aby ukraść zasób specyficzny dla ofiary

h2c smuggling (aktualizacje w czystym tekście)

Badanie z 2023 roku wykazało, że jeśli front-end przekazuje nagłówek HTTP/1.1 Upgrade: h2c do back-endu, który obsługuje HTTP/2 w czystym tekście, atakujący może tunelować surowe ramki HTTP/2 przez krawędź, która tylko walidowała HTTP/1.1. To omija normalizację nagłówków, zasady WAF i nawet zakończenie TLS.

Kluczowe wymagania:

  • Krawędź przesyła oba nagłówki Connection: Upgrade i Upgrade: h2c bez zmian.
  • Źródło przechodzi na HTTP/2 i zachowuje semantykę ponownego użycia połączenia, co umożliwia kolejkowanie żądań.

Łagodzenie jest proste – usuń lub twardo zakoduj nagłówek Upgrade na krawędzi, z wyjątkiem WebSocketów.


Znaczące CVE w rzeczywistym świecie (2022-2025)

  • CVE-2023-25690 – zasady mod_proxy Apache HTTP Server mogły być łączone w celu rozdzielania i przemycania żądań. (naprawione w 2.4.56)
  • CVE-2023-25950 – przemycanie żądań/odpowiedzi w HAProxy 2.7/2.6, gdy parser HTX niewłaściwie obsługiwał żądania w potoku.
  • CVE-2022-41721 – Go MaxBytesHandler spowodował, że pozostałe bajty ciała były analizowane jako HTTP/2 ramki, co umożliwiło przemycanie między protokołami.

Narzędzia

  • Burp Request Smuggler – od wersji v1.26 automatycznie testuje H2.TE/H2.CL i ukrytą obsługę ALPN. Włącz „HTTP/2 probing” w opcjach rozszerzenia.
  • h2cSmuggler – PoC w Pythonie od Bishop Fox do automatyzacji ataku aktualizacji w czystym tekście:
bash
python3 h2csmuggler.py -u https://target -x 'GET /admin HTTP/1.1\r\nHost: target\r\n\r\n'
  • curl/hyper – tworzenie ręcznych ładunków: curl --http2-prior-knowledge -X POST --data-binary @payload.raw https://target.

Środki obronne

  1. End-to-end HTTP/2 – całkowicie wyeliminuj tłumaczenie downgrade.
  2. Jedno źródło prawdy o długości – podczas downgrade'u zawsze generuj ważny Content-Length i usuń wszelkie nagłówki Content-Length/Transfer-Encoding dostarczone przez użytkownika.
  3. Normalizuj przed trasą – stosuj sanitację nagłówków przed logiką trasowania/przepisania.
  4. Izolacja połączeń – nie używaj ponownie połączeń TCP back-endu między użytkownikami; „jedno żądanie na połączenie” pokonuje exploity oparte na kolejce.
  5. Usuń Upgrade, chyba że WebSocket – zapobiega tunelowaniu h2c.

Odniesienia

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks