-15% na nową książkę sekuraka: Wprowadzenie do bezpieczeństwa IT. Przy zamówieniu podaj kod: 10000

HTTP Response Splitting w google.com

14 marca 2014, 10:42 | Teksty | komentarzy 11

W tym artykule:

  • 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:

splitting001

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:

splitting002

Czerwonym kolorem wyróżniłem miejsce, w którym umieszczana jest zawartość parametru language.

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:

splitting003

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:

splitting004

Inne możliwości wykorzystania response splittingu można znaleźć na stronach OWASP-u.

Reasumując: z podatnością HTTP Response Splitting mamy do czynienia, gdy dane, które są umieszczane wewnątrz nagłówków HTTP nie są właściwie walidowane pod kątem znaków <CR><LF>, umożliwiając wstrzykiwanie nowych nagłówków lub własnej treści strony.

 

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:

split

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:

 

Błąd został zgłoszony do Google w ramach programu bug bounty i został dość szybko załatany: zgłoszenie podesłałem w miniony piątek, a już we wtorek po response splittingu nie było śladu.

 

Michał Bentkowski

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. Marcin

    Graty!

    Odpowiedz
  2. bl4de

    Brawo :)

    A mógłbyś coś napisać o samym procesie zgłaszania błędu i kontaktu z Tobą ze strony Google?

    Odpowiedz
    • Mnie osobiście rozbawił fragment komunikacji z Google zaczynający się od 'Nice catch’ – ale to pewnie Michał napisze ;-)

      Odpowiedz
    • Michał B

      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.

      Odpowiedz
      • Imie

        A jak rozliczasz w skarbówce w Polsce bounty?

        Odpowiedz
        • Na rozliczeniu rocznym PIT-36 dorzuciłem załącznik PIT/ZG i zaklasyfikowałem to jako „dochód z innych źródeł”.

          Odpowiedz
  3. Dobrze zarobiony hajs :)

    Odpowiedz
  4. Dzakus
    Odpowiedz
    • adrb

      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

      Odpowiedz
  5. Caroon

    lcamtuf śpi?

    Odpowiedz
  6. Marcin

    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

    Odpowiedz

Odpowiedz na Michał