Recent vond ik een kwetsbaarheid die gebruikt kan worden om zonder autorisatie toegang te verkrijgen tot een Apple iCloud account van andere gebruikers. Dit was mogelijk door de nieuwe TouchID-feature voor het inloggen op websites te misbruiken.
Inloggen met behulp van TouchID/FaceID in Safari - geen 2FA?
Met de introductie van iOS 13 en macOS 10.15 heeft Apple een nieuwe feature gelanceerd waarmee gebruikers kunnen inloggen op Apple-websites door middel van TouchID/FaceID in Safari op apparaten die de benodigde biometrische hardware bevatten.
Wanneer je op je iPhone een pagina (welke dan ook) bezoekt met een login formulier voor een Apple-account, wordt een bericht getoond om toegang te krijgen via TouchID. Na het authenticeren ben je direct ingelogd. De 2-factor authenticatie die normaal gesproken wordt gevraagd wanneer je inlogt met je wachtwoord wordt hierbij overgeslagen. Dit is logisch gezien het feit dat je in dit proces ook 2 factoren hebt gebruikt; je biometrische gegevens en je device. Je kunt het bericht afbreken om normaal in te loggen, bijvoorbeeld wanneer je een ander AppleID wilt gebruiken dan de ID waarmee is ingelogd op je telefoon.
Ik verwacht dat deze feature niet is ontwikkeld om in te loggen op iCloud (aangezien het vrij zeldzaam is om icloud.com te gebruiken in Safari op een telefoon). De voornaamste reden voor deze feature zal zijn om de nieuwe ‘Sign in met Apple’ te gebruiken, waarvoor deze feature ook werkt. Voor die websites worden extra opties getoond wanneer je bijvoorbeeld een nieuw account creëert of wanneer je je mailadres wilt verbergen.
Impact breder dan alleen iCloud.com
Ondanks het feit dat dit alles werkt op zowel macOS en iOS, met TouchID en FaceID en voor alle websites die AppleID logins gebruiken, gebruik ik iOS, TouchID en https://icloud.com om de kwetsbaarheid uit te leggen. Houd in gedachten dat de impact dus groter is dan dit.
Inloggen op Apple domeinen met OAuth2
Inloggen op Apple domeinen gebeurt met het gebruik van OAuth2. Op https://icloud.com, wordt hier de “web_message” mode voor gebruikt. Dit werkt als volgt wanneer je op normale wijze inlogt:
- https://icloud.com opent een iframe naar
https://idmsa.apple.com/appleauth/auth/authorize/signin
?client_id=d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d
&redirect_uri=https%3A%2F%2Fwww.icloud.com
&response_mode=web_message
&response_type=code. - De gebruiker logt in (gebruikmakend van de stappen waarbij een 2FA token moet worden ingevuld) binnen het iframe.
- Wanneer de authenticatie lukt, stuurt de iframe een bericht terug naar de parent window met een grant_code voor de gebruiker door window.parent.postMessage(<token>, "https://icloud.com") in JavaScript te gebruiken.
- De grant_code wordt gebruikt door de icloud.com pagina om het login proces verder te kunnen vervolgen.
Correcte validatie van redirect URI essentieel voor bewaken van grant code van gebruiker
Er zijn 2 belangrijke parameters in de URL van de iframe: de client_id en de redirect_uri. De idmsa.apple.com server houdt een lijst bij van alle websites die de OAuth2 login voor Apple accounts mogen gebruiken en de redirect URI’s die zijn toegestaan per site. In het geval van de web_message flow wordt de redirect URI niet gebruikt als een werkelijke redirect, maar in plaats daarvan wordt deze gebruikt als de verplichte page origin voor het bericht met daarin de grand code (het tweede argument van postMessage).
Voor alle OAuth2 modes is het zeer belangrijk dat de authenticatie server de redirect URI correct valideert. Als dit niet gebeurt dan kan de grant_code van de gebruiker naar een onvertrouwde webpagina worden verstuurd. Als je inlogt via de website voert idmsa.apple.com die check correct uit: het wijzigen van de redirect_uri leidt direct tot een foutmelding.
Gebruik van nep-response door Safari
Wanneer de gebruiker inlogt via TouchID wordt de iframe op een andere manier verwerkt, maar de parent pagina blijft hetzelfde. Zodra Safari een nieuwe pagina ontdekt met een URL die overeenkomt met de voorbeeld URL van hierboven, dan downloadt het de pagina niet, maar in plaats daarvan roept het het proces AKAppSSOExtension aan. Dit proces communiceert met de AuthKit-daemon (akd) om de biometrische authenticatie uit te voeren en een toegangscode te verkrijgen.
Wanneer de gebruiker zichzelf succesvol authentiseert, dan injecteert Safari een nep-response voor het wachtende iframe, die het bericht zal sturen net zoals een normale pagina zou doen wanneer de authenticatie was geslaagd. akd communiceert met een API op gsa.apple.com, hier stuurt het de details van het request naartoe en ontvangt het de grant_code van.
Impact kwetsbaarheid: kwaadwillenden kunnen inloggen op iCloud account van andere gebruikers
Ik vond de bug in de gsa.apple.com API: ondanks dat de client_id en de redirect_uri bij de data zaten die werden opgestuurd door akd naar de API, werd er niet gecheckt of de redirect URI overeenkomt met de client ID. In plaats daarvan werd er enkel een whitelist toegepast door AKAppSSOExtension op het domein van de redirect URI. Alle domeinen die eindigen op apple.com, icloud.com en icloud.com.cn werden toegestaan. Dat klinkt wellicht veilig genoeg, maar bedenk je dat apple.com honderden (of zelfs duizenden) subdomeinen heeft. Wanneer ook maar één van deze subdomeinen kan worden misbruikt voor het draaien van kwaadwillende JavaScript, dan kan deze worden gebruikt om het aanmeldproces te starten, waardoor het de grant_code van de gebruiker op kan halen wanneer deze zich authentiseert. De pagina kan deze dan terug sturen aan een aanvaller die hem kan gebruiken om een sessie op icloud.com te verkrijgen.
Hoe zouden kwaadwillenden dit kunnen doen?
Een aantal voorbeelden van hoe kwaadwillenden konden inloggen op iCloud accounts van andere gebruikers:
- Een cross-site scripting kwetsbaarheid op een van de 3 subdomeinen. Deze worden vrij regelmatig gevonden, op https://support.apple.com/en-us/HT201536 vind je een lijst met minstens 30 kandidaten uit 2019. En deze dekken enkel de domeinen die belangrijk genoeg zijn om te onderzoeken.
- Een dangling subdomein dat kan worden overgenomen door een aanvaller. Hoewel ik niet bekend ben met een dergelijk geval bij Apple, heeft iemand recent 670 subdomeinen gevonden van microsoft.com die overgenomen konden worden: https://nakedsecurity.sophos.com/2020/03/06/researcher-finds-670-microsoft-subdomains-vulnerable-to-takeover/
- Een gebruiker die een pagina bezoekt op een van de subdomeinen via HTTP. De belangrijkste subdomeinen hebben een HSTS-header, maar veel hebben dit niet. Het apple.com domein is niet beschermd middels de includeSubdomains-optie van HSTS.
Gebruik van captive portal van Apple
De eerste twee voorbeelden hebben als voorwaarde dat de aanvaller de gebruiker moet misleiden om de geïnfecteerde pagina te bezoeken. Bij het derde voorbeeld moet de aanvaller toegang hebben tot het lokale netwerk van de gebruiker. Hoewel een dergelijke aanval over het algemeen lastiger is, laat het tegelijk ook een heel interessant voorbeeld zien: captive.apple.com. Wanneer een Apple apparaat verbinding maakt met een Wi-Fi-netwerk, zal het proberen toegang te verkrijgen tot http://captive.apple.com/hotspot-detect.html. Als de response niet overeenkomt met de gebruikelijke response, dan zal het systeem aannemen dat er een captive portal is waar de gebruiker eerst iets dient te doen. Om de gebruiker dit te laten doen wordt de respons pagina geopend en getoond.
Normaal gesproken is er dan een redirect waarbij de gebruiker naar een andere pagina wordt gestuurd waar hij moet inloggen, voorwaarden moet accepteren, betalen, etc. Echter, dit is geen must. In plaats daarvan kan de pagina ook JavaScript bevatten die de TouchID login aanspreekt, die zal worden toegestaan omdat het een apple.com subdomein betreft. Wanneer de gebruiker zich identificeert, ontvangt het JavaScript op de onvertrouwde site de gebruikers grant_code.
'Sign in with Apple'
De pagina kan alle soorten content bevatten die de kans vergroot dat de gebruiker zich zal identificeren. Dit kan bijvoorbeeld door de pagina er uit te laten zien alsof het onderdeel is van iOS zelf of door te doen alsof het ‘Sign in met Apple’ gebruikt. ‘Sign in met Apple’ is nog vrij nieuw, dus het zal gebruikers misschien niet direct opvallen dat het bericht er net iets anders uitziet dan normaal. Bovendien, veel gebruikers zullen waarschijnlijk zichzelf automatisch identificeren wanneer ze de TouchID prompt zien, omdat deze eigenlijk altijd wordt getoond wanneer zij zichzelf moeten authentiseren op hun telefoon. Het feit dat gebruikers in dit geval ook moeten beslissen of zij zich willen authentiseren op een bepaalde pagina is visueel niet direct duidelijk.
Fake hotspot
Door het opzetten van een fake hotspot op een locatie waar gebruikers een captive portal verwachten (denk aan een vliegveld, hotel of treinstation), zou het mogelijk zijn geweest om toegang te verkrijgen tot een significant aantal iCloud accounts. Deze accounts hadden toegang gegeven tot backups van foto’s, locaties van de telefoon, bestanden en nog veel meer. Zoals ik eerder aangaf, omzeilt dit de gebruikelijke 2FA van een 6-cijferige code.
Responsible disclosure response van Apple
Ik heb deze kwetsbaarheid bekend gemaakt bij Apple via hun responsible disclosure procedure. Zij hebben het oplossen van deze kwetsbaarheid direct een hoge prioriteit gegeven waardoor Apple het in korte tijd heeft kunnen fixen. De gsa.apple.com API checkt nu correct of de redirect_uri overeenkomt met de client_id. Dit kon dus volledig aan de server-kant worden opgelost.
Het is begrijpelijk hoe deze kwetsbaarheid over het hoofd is gezien: testers hebben zich waarschijnlijk gefocust op niet-betrouwbare domeinen voor de redirect_uri. Het werkt soms om bijvoorbeeld https://www.icloud.com.attacker.com of https://attacker.com/https://www.icloud.com te gebruiken. In dit geval mislukken beide, maar wanneer je enkel die twee probeert, dan mis je de mogelijkheid om een onbedoeld subdomein te gebruiken.