Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
HTTP Response Splitting w google.com
- Wyjaśnię czym jest podatność HTTP Response Splitting,
- Pokażę, dlaczego rzadko się ją spotyka w dzisiejszych aplikacjach…
- … ale udowodnię, że jednak się zdarza ;-)
Wstęp
Nim przejdę do tytułowej podatności, przypomnijmy sobie jak wygląda typowa odpowiedź HTTP. Weźmy na warsztat Sekuraka: po wpisaniu w przeglądarce adresu http://sekurak.pl/ przeglądarka wyśle zapytanie, na które serwer odpowie w sposób następujący:
Zasadniczo odpowiedź HTTP dzieli się na następujące części:
- kod odpowiedzi w pierwszej linii (zaznaczony kolorem czerwonym),
- nagłówki odpowiedzi (kolor zielony),
- pusta linia,
- treść odpowiedzi (body).
Zgodnie ze specyfikacją protokołu, kod odpowiedzi oraz nagłówki powinny kończyć się bajtami <CR><LF> (inaczej „\r\n”, zakończenie linii w stylu windowsowym). Pusta linia składa się wyłącznie zna znaków <CR><LF>.
Czym jest response splitting?
Wyobraźmy sobie, że mamy do czynienia z aplikacją, w której mamy bezpośrednią kontrolę nad jednym z nagłówków odpowiedzi. Przykładowo wykonujemy zapytanie pod adres http://example.com/?language=pl, w odpowiedzi zaś dostajemy:
Pamiętamy z opisu ze wstępu, że znaki <CR><LF> stanowią separator kolejnych nagłówków. Co więc stanie się, jeśli wstawimy te dwa znaki do parametru language i zamienimy nasz przykładowy request na http://example.com/?language=pl%0d%0aSet-Cookie:%20PHPSESSID=abcd?
Odpowiedź serwera mogłaby wyglądać następująco:
Jak widać, udało się wstrzyknąć nowy nagłówek http w odpowiedzi – nagłówek Set-Cookie, który tym samym pozwala na przeprowadzenie ataku session fixation.
Alternatywnie, zamiast wstrzykiwać nowe nagłówki, możemy po prostu zbudować jedną pustą linię i tym samym wstrzyknięcie przeniesie się do treści odpowiedzi. A tam można już przeprowadzać inny atak ;-).
http://example.com/?language=pl%0d%0a%0d%0aJestem%20w%20body:
Inne możliwości wykorzystania response splittingu można znaleźć na stronach OWASP-u.
Jak często spotyka się response splitting?
Właściwie… prawie nigdy. Praktycznie wszystkie powszechnie używane dziś frameworki są zabezpieczone przed tym atakiem. PHP nie pozwoli wykonać funkcji header („Test:\r\nTest”), odpowiadając ostrzeżeniem:
Warning: Header may not contain more than a single header, new line detected in /var/www/html/redirect.php on line 6
Podobne ostrzeżenia wyświetlą również takie środowiska jak .NET czy Java EE.
Czy zatem jest to podatność, o której można zapomnieć?
Niezupełnie… Poniżej zrzut ekranu jak udało mi się ostatnio wykorzystać response splitting do zrobienia XSS-a na stronie Google Doodle:
W tym przypadku możliwości ataku były jednak ograniczone – co prawda na zrzucie tego nie widać, ale aplikacja automatycznie zamieniała znak „–” (myślnik) na „_” (podkreślnik). Nie można więc było dodać większości ciekawych nagłówków, jak Set-Cookie (który zostałby zamieniony na Set_Cookie).
Nie stanowi to jednak dużego problemu, w XSS-ie w żaden sposób brak myślnika nie przeszkadza, a nawet – co za chwilę wyjaśnię – jest sprzymierzeńcem atakujących, gdyż umożliwia obejście filtra anti-XSS z przeglądarki Chrome.
Bez wchodzenia w szczegóły, ów filtr sprawdza, czy wykonywany kod javascriptowy znajduje się w zapytaniu http; jeśli tak, to jego wykonanie jest blokowane. Niemniej jednak, jeśli znajdziemy sposób na to, aby skrypt de facto różnił się od zapytania, wówczas Chrome nie rozpozna tego i nie zablokuje.
Wspominałem, że myślnik zamieniany jest na podkreślnik. Weźmy więc kod: <script>-=alert;-(1)</script>. Ten kod nie jest poprawny syntaktycznie, zostanie jednak zamieniony na <script>_=alert;_(1)</script> i wykonany na Chromie:
Michał Bentkowski
Graty!
Brawo :)
A mógłbyś coś napisać o samym procesie zgłaszania błędu i kontaktu z Tobą ze strony Google?
Mnie osobiście rozbawił fragment komunikacji z Google zaczynający się od 'Nice catch’ – ale to pewnie Michał napisze ;-)
Pewnie. Być może słyszałeś kiedyś opinie, jak wygląda komunikacja z Google, gdy ma się jakieś problemy np. z AdWords lub innymi usługami. W skrócie: jak rozmowa z botem. Tutaj było podobnie. Dotychczas zgłosiłem im sześć bugów i zawsze wyglądało to tak:
1. Zaczyna się od zgłoszenia błędu w formularzu pod adresem http://goo.gl/vulnz
2. Zaraz po zgłoszeniu otrzymuje się wiadomość potwierdzającą otrzymanie zgłoszenia, podpisaną jako „Google Security Bot”.
3. Zwykle po kilku dniach przychodzi kolejna odpowiedź – tym razem jest to już odpowiedź napisana przez kogoś z ichniego zespołu Security. Pomimo tego, wiadomość brzmi zawsze tak samo i ma treść „Nice catch! I’ve filed a bug and will update you once we’ve got more information.”. Tak czy owak, jest to potwierdzenie, że ktoś już przeczytał info o bugu i idzie ono gdzieś dalej
3,5. Potencjalnie tutaj może być etap, w którym ekipa pyta o dodatkowe kwestie związane z bugiem. Mnie jednak nigdy o nic nie dopytywali.
4. Mija kilka dni i przychodzi odpowiedź, czy bounty zostaje przyznane i w jakiej kwocie. Oczywiście wiadomość zaczyna się od uwagi „** NOTE: This is an automatically generated email **” ;-) Dodatkowo przesyłana jest informacja jak zarejestrować się w ich portalu, aby dostać płatność i jest prośba o wypełnienie formularza W8-BEN (aby uniknąć podwójnego opodatkowania).
5. Po 4-6 tygodniach (choć ja czekałem jeszcze dłużej) nagroda wpływa na konto.
A jak rozliczasz w skarbówce w Polsce bounty?
Na rozliczeniu rocznym PIT-36 dorzuciłem załącznik PIT/ZG i zaklasyfikowałem to jako „dochód z innych źródeł”.
Dobrze zarobiony hajs :)
Taka uwagą. Zablokowane jest dodawanie enterów w nagłówkach HTTP, ale można doklejać w funkcji mail
http://www.php.net/manual/en/function.mail.php
A przynajmniej w starych wersjach
Małe sprostowanie odnośnie specyfikacji i rozdzielania nagłówków na wiele linii:
” Historically, HTTP header field values could be extended over
multiple lines by preceding each extra line with at least one space
or horizontal tab (obs-fold). This specification deprecates such
line folding except within the message/http media type”
http://tools.ietf.org/html/rfc7230#section-3.2.4
lcamtuf śpi?
Witam, jest atak w stylu HTTP Cache Poisoning via Host Header Injection który podmienia w php zmienną http_host czy można użyć podobnej metody i podmienić np request_uri?
Jeżeli strona atakowana ma automatyczne przekierowanie na ze slasha na 'bez slasha’ i zostałby podmieniony request_uri to można byłoby zapętlić taką stronę.
Pytam bo chciałbym uniknąć tego typu problemu i nie czy się pisać na automatyczne przekierowanie