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

Błąd bezpieczeństwa w aplikacji desktopowej Google Hangouts Chat – czyli jak uczynić Open Redirect znów wielkim

23 lipca 2018, 08:15 | Teksty | komentarzy 13

Kilka miesięcy temu Google wydało nowy produkt – aplikację Hangouts Chat, która miała z pewnością być odpowiedzią amerykańskiego giganta na wszędobylskiego Slacka. W największym skrócie, jest to platforma komunikacyjna dla zespołów, w której można po prostu czatować, jak również wymieniać pliki, prezentacje itp.

Z Chata można skorzystać zarówno w przeglądarce (pod adresem https://chat.google.com/, niezbędne jest jednak posiadanie konta G Suite), jak również w postaci aplikacji desktopowej oraz mobilnej – które z kolei można pobrać z https://get.google.com/chat/. Google najwyraźniej mocno zależało na bezpieczeństwie tej aplikacji, bo przyznali swego czasu szereg research grantów. Też postanowiłem z niego skorzystać – i wziąłem na warsztat aplikację desktopową. Albowiem nie samymi aplikacjami webowymi żyje człowiek :)

Hangouts Chat – jak wygląda aplikacja desktopowa

Okazało się, że aplikacja desktopowa jest napisana z użyciem Electrona, frameworka pozwalającego pisać aplikacje dla systemów desktopowych (Windows, Linux, macOS) z użyciem technologii webowych, czyli HTML, CSS czy JavaScript. Od strony technicznej zrealizowano to w taki sposób, że okno z widokiem aplikacji jest w rzeczywistości instancją przeglądarki Chromium, a pod spodem działa jeszcze Node.js.

W przypadku Hangouts Chat, aplikacja desktopowa właściwie nie różni się niczym od jej wersji webowej. Tak naprawdę, w okienku Electrona po prostu wyświetlana jest ta sama strona, która zahostowana jest pod adresem https://chat.google.com. Widać to na Rys. 1.

Rys 1. Porównanie Hangouts Chat - wersja webowa (po lewej) i desktopowa (po prawej)

Rys 1. Porównanie Hangouts Chat – wersja webowa (po lewej) i desktopowa (po prawej)

Może się zatem wydawać, że poszukiwanie błędów w wersji desktopowej nie będzie się niczym różnić od poszukiwania błędów w wersji webowej. Jest to prawda, ale z jednym istotnym zastrzeżeniem. Wersja webowa, wyświetlana w tradycyjnej przeglądarce, posiada oczywiście pasek adresu. Pasek adresu jest w istocie jedynym miejscem, dzięki któremu użytkownik może stwierdzić, czy może danej domenie zaufać, czy też nie. Poniżej cytat, potwierdzający tę opinię, z książki Tangled Web Michała Zalewskiego:

In essence, the domain name in the URL shown in the browser’s address bar is one of the most important security indicators on the Web, as it allows users to quickly differentiate sites they trust and have done business with from the rest of the Internet.

W aplikacji desktopowej paska adresu jednak nie ma. Oznacza to, że użytkownik musi zaufać aplikacji samej w sobie, że serwuje treść z domeny https://chat.google.com, ale nie ma żadnej wiarygodnej metody, żadnego wiarygodnego wskaźnika, który pozwoli to potwierdzić.

Nasunęła mi się zatem myśl, że może uda mi się znaleźć sposób, by przekonać aplikację do przekierowania pod inną niż chat.google.com, co w konsekwencji pozwoliłoby na bardzo wiarygodny phishing, wyciągający dane logujące użytkownika. W aplikacji Chat nastąpiłoby przekierowanie do domeny kontrolowanej przeze mnie, na której znajdowałby się panel logowania podobny do tego oryginalnego z Google. Użytkownik nie mógłby zweryfikować, że panel jest fałszywy (brakuje paska adresu), więc podałby tam swoje dane, które następnie mogłyby trafić na mój serwer.

Poszukiwanie przekierowania

Zacząłem więc zastanawiać się nad możliwymi sposobami przekierowania użytkownika do innej domeny. Najprostszy pomysł… to prostu dodanie linka do zewnętrznej domeny na czacie. Użytkownik klika linka i w efekcie przechodzi na zewnętrzną domenę.

Rzeczywistość? Linki do zewnętrznych domen są otwierane w domyślnej systemowej przeglądarce.

Jak widać na powyższym filmie, link do Sekuraka nie otwiera się w samej aplikacji Chat, tylko w zewnętrznej przeglądarce. Trudno więc w ten sposób przekonać użytkownika do przekazania nam danych do Google’a, skoro będzie mógł zobaczyć na jakiej domenie pracuje.

Testując temat dalej, zauważyłem, że linki prowadzące do domeny chat.google.com otwierają się jednak w aplikacji. Odkryłem przy okazji, że jeśli użytkownik kliknie na linka, który odpowie np. kodem 400 czy 404 (np. ten: https://chat.google.com/webchannel/events), to musi zrestartować aplikację, by móc z niej dalej korzystać, bo nie ma w niej przycisku „Wstecz” ?.

Z doświadczeń pracy z różnymi aplikacjami, można było nieraz zauważyć, że dobrym sposobem na obejście reguł związanych z adresami URL (np. takich jak powyżej, tj. tylko linki pod konkretną domenę są dopuszczalne) jest użycie przekierowań, czyli odpowiedzi HTTP o kodach 3xx.

Domena chat.google.com domyślnie odpowiada przekierowaniem, jeśli odwołamy się pod nieistniejący URL w niej, np. https://chat.google.com/test123. To przekierowanie prowadzi do: https://chat.google.com/u/0/?hasBeenRedirected=true.

Zatem w celu przetestowania, czy faktycznie przekierowania pozwolą odwołać się do dowolnej domeny:

  1. Uruchomię w tle Burpa (to narzędzie typu webproxy),
  2. Ustawię, by Chat współpracował z proxy,
  3. Ustawię w Burpie regułę, by treść nagłówka odpowiedzi „https://chat.google.com/u/0/?hasBeenRedirected=true” podmieniał na „https://sekurak.pl”. Dzięki temu, przekierowania będą podmienione na takie, by prowadziły do Sekuraka.

Odpowiednia opcja w Burpie znajduje się w menu Proxy->Options->Match and replace->Add. Wartości jakie ustawiłem widać na Rys 2.

Rys 2. Podmiana treści nagłówków odpowiedzi

Rys 2. Podmiana treści nagłówków odpowiedzi

Zobaczmy poniżej jak zareagowała aplikacja na tak podmienione przekierowanie:

Fantastycznie! Myślę, że już w tym momencie można było mówić o podatności w tej aplikacji, tj. niesprawdzanie dokąd prowadzą przekierowania. Brakowało mi jednak jeszcze jednego kamyczka. Póki co, atak nie jest możliwy do wykorzystania praktycznie; trudno bowiem liczyć, że będziemy w stanie podpiąć użytkownikowi proxy, które będzie mu podmieniało zawartość przekierowań.

Potrzebna będzie podatność, która pozwoli przekierować użytkownika do dowolnej innej strony. A taką podatnością jest open redirect.

Open redirect

Open redirect jest podatnością dość powszechną w aplikacjach webowych. Sprowadza się ona do tego, że mamy np. adres URL typu: https://sekurak.pl/?redir=https://zlosliwa-domena.pl, po którego odwiedzeniu, użytkownik zostanie przekierowany do https://zlosliwa-domena.pl. Teoria (jak jest też wspominane na zalinkowanym przed chwilą OWASP-ie) jest taka, że jeśli użytkownik został do tej domeny przekierowany z domeny, której ufa, to będzie też mocniej ufał tej domenie docelowej. Ma to ułatwiać ataki phishingowe. Moim zdaniem jest to dość naciągana interpretacja; a podobne zdanie ma zespół bezpieczeństwa Google. W tradycyjnym modelu webowym, użytkownik i tak może polegać na pasku adresu, jako miejscu mówiącym, czy dana domena jest zaufana.

W przypadku aplikacji desktopowej Chat sytuacja jest jednak zgoła inna. Tutaj open redirect rzeczywiście jest poważną podatnością, ponieważ użytkownik paska adresu nie widzi; nie wie więc na jakiej domenie wpisuje dane logujące.

Postanowiłem więc poszukać takiej podatności w domenie https://chat.google.com. Okazało się to dużo prostsze niż początkowo sądziłem; wystarczyło tylko przejrzeć jakie zapytania generuje aplikacja sama w sobie.

A generuje zapytanie do wnętrza katalogu https://chat.google.com/accounts. Okazuje się, że wszystkie takie URL-e przekierowują do domeny https://accounts.google.com. Sprawdźcie sami: https://chat.google.com/accounts/dowolny-url: po kliknięciu powinniście się znaleźć na https://accounts.google.com/dowolny-url. Przekierowanie do accounts.google.com jest dopiero pierwszym elementem układanki, ale najważniejszym, bo okazało się, że istnieje publicznie znany open redirect w tej domenie!

Nie musiałem już więc dalej szukać, tylko skorzystać z rozwiązania opisanego na blogu Vag Mour {Labs}. Po szczegółowy opis błędu zapraszam na linka z poprzedniego zdania, ale atak sprowadza się do tego, że mogę dokonać przekierowania do swojej domeny; muszę tylko w niej zahostować coś pod URL-em: /_ah/conflogin. Adres URL z tym redirectem wyglądał następująco:

https://chat.google.com/accounts/ServiceLogin?continue=https://appengine.google.com/_ah/conflogin?continue=http://bentkowski.info/&service=ah

Przygotowałem więc na swojej domenie panel logowania przypominający ten z Google’a – i tym razem mamy w pełni wiarygodny phishing :)

Ten sam atak nie zadziała w przypadku przeglądarki webowej, bo pasek adresu wyraźnie będzie wskazywał, że domena nie powinna być zaufana (Rys 3.).

Rys 3. W pasku adresu przeglądarki widać, że panel logowania jest fałszywy

Rys 3. W pasku adresu przeglądarki widać, że panel logowania jest fałszywy

Podsumowanie

Myślę, że pierwszy wniosek, jaki należy wyciągnąć z powyższego opisu, jest taki, żeby zawsze przyglądać się temu, co widzimy w pasku adresu. W szczególności jeśli mamy za chwilę na stronie wpisać swoje dane uwierzytelniające lub jakiekolwiek inne dane poufne.

Drugi wniosek: aplikacje napisane w Electronie sprawiają, że open redirect jest o wiele poważniejszą podatnością niż w tradycyjnym modelu webowym, ze względu na fakt, że użytkownik nie może potwierdzić autentyczności witryny. Musi więc zaufać, że aplikacja sama dobrze weryfikuje, dokąd przekierowuje.

Ostatni wniosek: jeśli korzystacie z Hangouts Chat, aktualizujcie! Google wydało poprawkę kilka dni temu.

W odpowiedzi na często zadawane pytanie pod postami o znaleziskach w bug bounty: Google było zaskakująco hojne, jeśli chodzi o bounty za ten błąd, bo wypłacili 7500 USD. Najwyraźniej chcą mocniej zmotywować do poszukiwania kolejnych błędów.

Aktualizacja: ten tweet autorstwa Eduardo Vela Navy, że kwota bounty była związana z możliwością wykonania kodu systemu operacyjnego po stronie użytkownika. Zanim zgłosiłem tę podatność, to próbowałem ją też eskalować w taki sposób, choć nie udało mi się tego dokonać. Trudno powiedzieć, czy Google zna konkretny sposób takiego wykorzystania podatności, czy po prostu zakładają, że jest to możliwe (wiele innych aplikacji electronowych pokazuje, że to często jest możliwe).

 — Michał Bentkowski, hakuje i szkoli w ramach Securitum

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



Komentarze

  1. Jerico

    Ciekawy i przystępnie napisany artykuł.

    Odpowiedz
  2. Itar

    Michał, gratuluję pomysłu w poszukiwaniach. Fajny artykuł, pokazuje krok po kroku pracę badacza :-).

    BTW. Zastanawia mnie dlaczego Google mając taki potencjał korzysta z gotowego framworka, o którym wiadomo, że „nie jest idealny”. Elektron jest użyty w Slacku, Signalu i kilku równie znanych aplikacjach.

    I.

    Odpowiedz
    • Co do frameworków – to pewnie support. W makroskali to pewnie podobnie robią twórcy skrzynek sieciowych migrujący się docelowo na Linuksa / *BSD.

      Odpowiedz
  3. Tomasz21.

    Witam;Szczegółowo i krok po kroku opisane. Czyli każdy może zrozumieć, nawet ten najmniej wtajemniczony w arkana sztuki. Ciekawie i interesująco. Pozdrawiam.

    Odpowiedz
  4. Marcin

    Jak zawsze genialny opis Michała, krok po kroku co i jak, no i kapitalne poczucie humoru:
    „…bo przyznali swego czasu szereg research grantów. Też postanowiłem z niego skorzystać – i wziąłem na warsztat…” – żeby każdy tak potrafił :)

    Odpowiedz
  5. Anon

    Czyli tak naprawdę $7.5k za to, że zauważyłeś, że chat.google.com otwiera się w apce? Nieźle.

    W jaki sposób Google poprawiło ten błąd?

    Odpowiedz
    • cd_s

      Pewnie załatają open redirect i problem się rozwiąże.

      Odpowiedz
    • Michał Bentkowski

      Zmodyfikowali sposób weryfikacji, czy linki otwierać w aplikacji, czy w zewnętrznej przeglądarce. Obecnie jest znacznie silniejszy.

      Open redirect – jako taki – nadal istnieje, tyle że w appce nie da się go już wykorzystać.

      Odpowiedz
  6. wddr

    nie tylko doniczka z kwiatkiem staje sie problemem
    hxxps://hackaday.com/2018/07/24/3d-printing-cybersecurity-and-audio-fingerprinting/

    Odpowiedz
  7. Mrttt

    Michal czesto (zawsze?) te apki na elektronie maja wylaczany sandbox, moze to?

    Odpowiedz
    • Michał Bentkowski
      Odpowiedz
  8. Muflon

    Przeciez kazda przegladarka posiada obsluge w postaci skrótów klawiaturowych nie chce mi sie tego sprawdzac ale w chromium napewno tez sa wiec brak przycisku wstecz wcale nie zmusza nas do restartowania aplikacji. Zgadza sie?

    Odpowiedz
  9. Muflon

    Dokladnie Alt+ strzalka prawo/lewo i nie trzeba resetowac

    Odpowiedz

Odpowiedz na Anon