Brute-Force-Angriff auf Google-Nutzertelefonnummern
(brutecat.com)- Googles No-JS-Formular zur Wiederherstellung des Nutzernamens bestätigte die Kombination aus Telefonnummer und Anzeigename und ermöglichte so eine Angriffskette, mit der sich die vollständige Telefonnummer eines bestimmten Google-Nutzers ermitteln ließ
- Der Kern lag in den Redirect-Unterschieden von
/signin/usernamerecoveryund/signin/usernamerecovery/lookup, wodurch sich zwischen „Konto existiert nicht“ und „Konto existiert“ unterscheiden ließ - Es gab zwar IP-basiertes Rate Limiting und CAPTCHA, doch wenn man den BotGuard-Token aus dem JS-Formular in
bgresponsedes No-JS-Formulars einsetzte, funktionierte es ohne Begrenzung; kombiniert wurde das mit IPv6-Rotation - Angreifer konnten über Looker Studio den Google-Konto-Anzeigenamen erhalten und durch die Kombination mit der maskierten Telefonnummer aus dem Passwort-zurücksetzen-Ablauf sowie länderspezifischen Nummernformaten die Kandidatenzahl stark reduzieren
- Auf einem Server mit 16 vCPU für 0,30 US-Dollar pro Stunde waren etwa 40.000 Prüfungen pro Sekunde möglich; Google stellte das No-JS-Formular zur Wiederherstellung des Nutzernamens am 6. Juni 2025 vollständig ein und zahlte insgesamt 5.000 US-Dollar
Schwachstelle, die mit dem No-JS-Formular zur Wiederherstellung des Nutzernamens begann
- Beim Prüfen, wie Google-Dienste im Browser mit deaktiviertem JavaScript funktionieren, wurde entdeckt, dass das Formular zur Wiederherstellung des Nutzernamens weiterhin funktionierte
- Es galt bislang als selbstverständlich, dass das Konto-Wiederherstellungsformular JavaScript benötigt, da es seit Langem auf BotGuard-ähnliche Schutzmechanismen setzt, die von verschleiertem Proof-of-Work-JavaScript-Code erzeugt werden
- Das No-JS-Formular bot jedoch einen Ablauf, mit dem sich prüfen ließ, ob eine Wiederherstellungs-E-Mail oder Telefonnummer mit einem bestimmten Anzeigenamen verknüpft ist
Kontenexistenz mit zwei Anfragen prüfen
- Die erste Anfrage sendete die Telefonnummer an
/signin/usernamerecoveryund erhielt ausLocationder Antwort deness-Wert, der mit dieser Telefonnummer verknüpft war- Cookies und der
gxf-Wert wurden aus dem HTML der Startseite entnommen
- Cookies und der
- Danach wurde an
/signin/usernamerecovery/lookupmitess, Vorname, Nachname undbgresponse=js_disabledgesendet - Der Antwort-Redirect fiel unterschiedlich aus, sodass festgestellt werden konnte, ob ein Google-Konto mit dieser Telefonnummer und diesem Anzeigenamen existierte
- Kein Konto:
usernamerecovery/noaccountsfound - Konto vorhanden:
usernamerecovery/challenge
- Kein Konto:
IP-Limits, IPv6 und Umgehung von BotGuard
- Bei ersten Versuchen griff nach einigen Anfragen ein Rate Limit für die IP-Adresse, und es erschien ein CAPTCHA
- Im Beispiel mit einer niederländischen Mobilnummer lieferte der Passwort-zurücksetzen-Ablauf Hinweise wie
•• ••••••03- Da niederländische Mobilnummern mit
06beginnen, mussten die verbleibenden 6 Ziffern brute-forced werden, also10^6 = 1.000.000Kandidaten
- Da niederländische Mobilnummern mit
- Anbieter wie Vultr stellen einen
/64-IPv6-Bereich bereit, in dem sich theoretisch18,446,744,073,709,551,616Adressen nutzen lassen - Es wurde ein PoC erstellt, der mit
reqwestundClientBuilder.local_addressfür jede Anfrage eine zufällige IPv6-Adresse aus dem Subnetz setzte - Mit deaktiviertem JS-Formular auf Rechenzentrums-IP-Adressen erschien weiterhin CAPTCHA; setzte man jedoch den BotGuard-Token aus dem JS-aktivierten Konto-Wiederherstellungsformular in
bgresponsedes No-JS-Formulars ein, gingen die Anfragen durch- Für diesen BotGuard-Token schien es im No-JS-Formular kein Rate Limiting zu geben
Falsche Treffer herausfiltern
- Erste Ergebnisse enthielten viele Konten mit dem Namen
Henry, leerem Nachnamen und Telefonnummern mit den letzten beiden Ziffern03 - In diesem Fall lieferte
usernamerecovery/challengebei VornamenHenryunabhängig vom Nachnamen ein positives Ergebnis - Zur Verifikation möglicher Treffer wurde mit demselben Vornamen und einem zufälligen Nachnamen wie
0fasfk1AFko1wferneut geprüft- Kam weiterhin ein Treffer zurück, wurde dieser als False Positive herausgefiltert
- Die Wahrscheinlichkeit, dass andere Google-Nutzer denselben vollständigen Anzeigenamen, denselben Ländercode und dieselben letzten beiden Ziffern der Telefonnummer haben, wurde als gering eingeschätzt
Ländercode und Anzeigename beschaffen
- Die Maskierung der Telefonnummer im Passwort-zurücksetzen-Ablauf ließ sich zur Schätzung des Ländercodes nutzen
- Google verwendet für das nationale Format jeder Nummer libphonenumber
- Es wurden maskierte nationale Formate pro Land gesammelt und in mask.json abgelegt
- Russland, die Niederlande, das Vereinigte Königreich und die USA haben unterschiedliche Maskierungsmuster
- Google änderte 2023 seine Richtlinie so, dass Namen nur noch angezeigt werden, wenn es eine direkte Interaktion mit der Zielperson gibt; im April 2024 stellte die Internal People API die Rückgabe von Anzeigenamen für nicht authentifizierte Konten vollständig ein
- Überträgt man jedoch ein in Looker Studio erstelltes Dokument an das Opfer, wird auf dem Startbildschirm der Anzeigename des Opfers auch ohne Interaktion offengelegt
Optimierung des Suchraums und Werkzeuge
- Mithilfe der Nummernvalidierung von libphonenumber wurde format.json erzeugt, das je Land mobile Präfixe, bekannte Ortsvorwahlen und Ziffernlängen enthält
- Das Beispiel Niederlande enthält den Ländercode
31, die Ortsvorwahlen61,62,63,64,65,68und die Ziffernlängen[7]
- Das Beispiel Niederlande enthält den Ländercode
- Durch Libphonenumber-Validierung in Echtzeit wurden Google-API-Abfragen für ungültige Nummern reduziert
- Zur Erzeugung von BotGuard-Tokens wurde ein Go-Skript mit chromedp geschrieben
- Über den Aufruf von
http://localhost:7912/api/generate_bgtokenlässt sichbgTokenabrufen
- Über den Aufruf von
- Der gesamte Angriff lief in drei Schritten ab
- Leck des Google-Konto-Anzeigenamens über Looker Studio
- Ermittlung der maskierten Telefonnummer über den Passwort-zurücksetzen-Ablauf
- Brute Force der vollständigen Telefonnummer mit
gpbanhand von Anzeigename und maskierter Telefonnummer
Brute-Force-Leistung und erwartete Dauer
- Auf einem 16-vCPU-Server der Consumer-Klasse für 0,30 US-Dollar pro Stunde waren etwa 40.000 Prüfungen pro Sekunde möglich
- Geschätzte Dauer, wenn im Passwort-zurücksetzen-Ablauf nur die letzten zwei Ziffern gegeben sind:
- USA
+1: 20 Minuten - Vereinigtes Königreich
+44: 4 Minuten - Niederlande
+31: 15 Sekunden - Singapur
+65: 5 Sekunden
- USA
- Wenn Passwort-Reset-Abläufe anderer Dienste wie PayPal mehr Ziffernhinweise liefern, kann sich die Zeit deutlich verkürzen
- Beispiel:
+14•••••1779
- Beispiel:
Zeitlinie zu Meldung und Maßnahmen bei Google
- 2025-04-14: Bericht an den Anbieter gesendet
- 2025-04-15: Anbieter bestätigte Eingang und klassifizierte den Bericht
- 2025-04-25: Antwort „Nice catch!“
- 2025-05-15: Das Panel setzte eine Belohnung von 1.337 US-Dollar + Swag fest
- Begründet wurde dies mit einer als gering eingeschätzten Ausnutzbarkeit; das Problem wurde als Abuse-bezogene Methodik mit hoher Auswirkung anerkannt
- 2025-05-15: Einspruch gegen die Begründung der Belohnung eingelegt
- Laut Abuse-VRP-Tabelle hängen Wahrscheinlichkeit und Ausnutzbarkeit von den Voraussetzungen des Angriffs und davon ab, ob das Opfer den Missbrauch erkennen kann
- Es wurde argumentiert, dass dieser Angriff keine Voraussetzungen hat und vom Opfer nicht erkannt werden kann
- 2025-05-22: Das Panel zahlte zusätzliche 3.663 US-Dollar und erhöhte die Gesamtprämie auf 5.000 US-Dollar
- Die Einschätzung der Wahrscheinlichkeit wurde auf mittel angehoben
- 2025-05-22: Der Anbieter bestätigte, laufende Gegenmaßnahmen ausgerollt zu haben, bis der Endpoint weltweit abgeschaltet wird
- 2025-05-22: Veröffentlichung für den 2025-06-09 abgestimmt
- 2025-06-06: Der Anbieter bestätigte die vollständige Abschaltung des No-JS-Formulars zur Wiederherstellung des Nutzernamens
- 2025-06-09: Bericht veröffentlicht
Noch keine Kommentare.