1 Punkte von GN⁺ 2025-06-10 | Noch keine Kommentare. | Auf WhatsApp teilen
  • 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/usernamerecovery und /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 bgresponse des 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/usernamerecovery und erhielt aus Location der Antwort den ess-Wert, der mit dieser Telefonnummer verknüpft war
    • Cookies und der gxf-Wert wurden aus dem HTML der Startseite entnommen
  • Danach wurde an /signin/usernamerecovery/lookup mit ess, Vorname, Nachname und bgresponse=js_disabled gesendet
  • 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

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 06 beginnen, mussten die verbleibenden 6 Ziffern brute-forced werden, also 10^6 = 1.000.000 Kandidaten
  • Anbieter wie Vultr stellen einen /64-IPv6-Bereich bereit, in dem sich theoretisch 18,446,744,073,709,551,616 Adressen nutzen lassen
  • Es wurde ein PoC erstellt, der mit reqwest und ClientBuilder.local_address fü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 bgresponse des 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 Ziffern 03
  • In diesem Fall lieferte usernamerecovery/challenge bei Vornamen Henry unabhängig vom Nachnamen ein positives Ergebnis
  • Zur Verifikation möglicher Treffer wurde mit demselben Vornamen und einem zufälligen Nachnamen wie 0fasfk1AFko1wf erneut 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 Ortsvorwahlen 61, 62, 63, 64, 65, 68 und die Ziffernlängen [7]
  • 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
  • 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 gpb anhand 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
  • Wenn Passwort-Reset-Abläufe anderer Dienste wie PayPal mehr Ziffernhinweise liefern, kann sich die Zeit deutlich verkürzen
    • Beispiel: +14•••••1779

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.

Noch keine Kommentare.