Skip to content
CyberXplore - Xplore the Unseen

Wir haben einen Monat lang GitHub gehackt: Das haben wir gefunden

cyberxploreVon cyberxplore14 Min. Lesezeit

Nach einer langen Pause melden wir uns mit einem neuen Write-up zurück. Obwohl wir aufgrund anderer Verpflichtungen normalerweise nicht an Bug-Bounty-Programmen teilnehmen, haben wir die Herausforderung angenommen, einen Monat lang GitHub zu hacken, und freuen uns darauf, unsere Ergebnisse zu teilen. Alles begann, als Shivam Singh (Mr. Rajput Hacker) im … Read more

Wir haben einen Monat lang GitHub gehackt: Das haben wir gefunden

Nach einer langen Pause melden wir uns mit einem neuen Write-up zurück. Obwohl wir aufgrund anderer Verpflichtungen normalerweise nicht an Bug-Bounty-Programmen teilnehmen, haben wir die Herausforderung angenommen, einen Monat lang GitHub zu hacken, und freuen uns darauf, unsere Ergebnisse zu teilen. Alles begann, als Shivam Singh (Mr. Rajput Hacker) im November auf mich zukam und mich ermutigte, Bug Bounty auszuprobieren. Wir entschieden uns, npmjs.com in den Fokus zu nehmen, eine Tochtergesellschaft von GitHub. Obwohl GitHub ein großes Unternehmen ist und das Bug-Bounty-Programm auf HackerOne öffentlich war, hielten wir es für einen Versuch wert.

Fokus auf die Business-Logik

Mr. Rajput Hacker und ich beschlossen, uns ausschließlich auf Fehler in der Business-Logik der Anwendung zu konzentrieren. Bevor wir mit der Suche begannen, sorgten wir dafür, die Anwendung vollständig zu verstehen. Das bedeutete einen minimalen Einsatz von Burp Suite und den Schwerpunkt darauf, die Kernfunktionen und Abläufe der Anwendung zu begreifen. Unser Ziel war es, Schwachstellen in der Business-Logik zu finden, die sich potenziell ausnutzen ließen. Indem wir unser Toolset bewusst begrenzten und uns auf das Verständnis der Anwendung konzentrierten, wollten wir einzigartige oder übersehene Schwachstellen aufdecken. Da npmjs.com eine vergleichsweise kleine Anwendung war, brauchten wir für unser Verständnis und unsere Notizen weniger als zwei Stunden.

Entdeckte Schwachstellen

Nr.H1-Report-TitelZielMeldedatum (TT/MM/JJ)SchweregradPrämie
1Das Beanspruchen eines gelöschten Kontonamens vor Ablauf von 90 Tagen kann zu mehreren Problemen führenhttps://github.com/11/12/22InformativNA
2Konto-Sitzungen bleiben nach einer Namensänderung aktiv und weiterhin an den alten Benutzernamen gebundenhttps://education.github.com/11/12/22Niedrig$2000
3Täuschung von Mitgliedern einer Opfer-Organisation durch eine Namensverwechslungs-Schwachstelle in der Mitglieder-Einladungsfunktion der Organisationhttps://npmjs.com/07/12/22MittelDuplikat
4Opfer kann den Benutzernamen eines gelöschten Kontos beanspruchen – führt zur Kontoübernahme durch Kontrolle der Sitzung des gelöschten Kontoshttps://npmjs.com/02/12/22Mittel$4000
5Löschen beliebiger Konten auf NPMJS durch Ausnutzung einer Fehlkonfiguration des Support-Systemshttps://npmjs/com/11/12/22NiedrigDuplikat ($200)
6Umgehung der Login-Verifizierung auf NPMJS.comhttps://npmjs.com/16/11/22Mittel$4000
Gesamtprämie$10000

An das GitHub Security Program gemeldete Schwachstellen

Obwohl wir erwähnt haben, dass insgesamt  9 Schwachstellen gemeldet wurden, schreiben wir heute hier über 3 davon, die unten aufgeführt sind:

  1. Umgehung der Login-Verifizierung auf npmjs.com
  2. Pre-Account-Takeover auf npmjs.com
  3. Zugriffskontroll-Problem auf education.github.com

Umgehung der Login-Verifizierung auf NPMJS

Beschreibung  –

Beim Durchgehen des Authentifizierungsbereichs von npmjs.com und gängiger Funktionen wie dem Aktualisieren der E-Mail-Adresse und des Profils fiel uns ein seltsames Verhalten der Anwendung auf, das unsere Aufmerksamkeit erregte: das Format des E-Mail-Verifizierungslinks, des Passwort-Reset-Links & des Links zum Aktualisieren der E-Mail-Adresse . 

Der Link hatte für alle Funktionen das Format https://npmjs.com/verify/{some_random_token_here} – egal ob Passwort-Reset, E-Mail-Verifizierungslink oder ein beliebiger anderer Link auf dieser Seite . Als Nächstes stellten wir fest, dass die Anwendung bei jeder Anmeldung einen Verifizierungscode an die registrierte E-Mail-Adresse sendet, den man im Rahmen der Login-Verifizierung eingeben muss (eine Art 2FA/MFA-Code per E-Mail), um sich erfolgreich am Konto anzumelden .  Wir versuchten daraufhin, diese Funktion zu umgehen, und waren erfolgreich – da wir die Anwendung in den letzten 2 Stunden vollständig durchgearbeitet hatten, kannten wir jede Funktion, konnten die Zusammenhänge herstellen und die Umgehung finden; lies die folgenden Schritte zur Reproduktion, um zu sehen, wie wir vorgegangen sind .

Bei unserer Untersuchung des Authentifizierungsprozesses und gängiger Funktionen von npmjs.com, etwa dem Aktualisieren von E-Mail-Adressen und Profilen, entdeckten wir ein eigenartiges Verhalten beim Format der E-Mail-Verifizierungslinks, Passwort-Reset-Links und der Links zum Aktualisieren von E-Mail-Adressen. Diese Links hatten das Format https://npmjs.com/verify/{random_token} und wurden für alle Funktionen verwendet, darunter Passwort-Reset, E-Mail-Verifizierung und weitere.

Uns fiel außerdem auf, dass bei jeder Anmeldung eines Nutzers ein Verifizierungscode an die registrierte E-Mail-Adresse gesendet wurde. Dieser Verifizierungscode war erforderlich, um den Anmeldevorgang abzuschließen, und fungierte als eine Form der Zwei-Faktor-Authentifizierung. Als Zweites fiel uns auf: Beim Aktualisieren einer E-Mail-Adresse auf npmjs erfolgte die Änderung, ohne dass eine Passwortbestätigung erforderlich war. Es wurde eine E-Mail sowohl an die alte als auch an die neue Adresse gesendet. Die an die alte Adresse gesendete E-Mail informierte den Empfänger darüber, dass er, falls er die Änderung nicht selbst vorgenommen hatte, auf einen Link (https://npmjs.com/verify/{some_random_token_here}) klicken kann, um die Änderung rückgängig zu machen und seine alte Adresse zur aktuellen zu machen. Die an die neue Adresse gesendete E-Mail enthielt einen Link, um die neue E-Mail zu verifizieren und sie mit dem soeben aktualisierten Konto zu verknüpfen.

Wir stießen auf ein überraschendes Verhalten, als wir versuchten, uns nach dem Aktualisieren der E-Mail-Adresse auf der Profilseite bei einem Konto anzumelden. Obwohl wir weder in der alten noch in der neuen E-Mail einen Link bestätigt oder angeklickt hatten, zeigte das System eine Meldung an, dass ein Verifizierungscode an die neue, unbestätigte Adresse gesendet worden sei. Das schien darauf hinzudeuten, dass wir uns nicht würden anmelden können.  Bei genauerem Hinsehen entdeckten wir jedoch eine E-Mail an unsere alte Adresse, die uns aufforderte, die Änderung rückgängig zu machen, um eine Kontosperrung zu vermeiden. Als wir auf den angegebenen Link (https://npmjs.com/verify/{random_token}) klickten, um die E-Mail zurückzusetzen, wurden wir zur Anmeldeseite geleitet. Zu unserer Überraschung fragte das System nach Eingabe unserer Zugangsdaten nicht nach dem Verifizierungscode, sondern ließ uns anmelden und die E-Mail-Änderung rückgängig machen.

Bei weiterer Untersuchung gelang es uns jedoch, diese Funktion erfolgreich zu umgehen. Unser tiefes Verständnis der Anwendung, das wir uns in zwei Stunden intensiver Beschäftigung mit ihren Funktionen angeeignet hatten, erlaubte es uns, verschiedene Funktionen miteinander in Beziehung zu setzen und die Umgehung zu finden. Die Schritte zur Reproduktion der Umgehung sind unten aufgeführt.

Schritte zur Reproduktion –

  1. Registrierung mit [email protected] (Benutzername attacker1)
  2. Bei attacker1 mit Login und Passwort anmelden (da der npmjs-Login nur mit Benutzername und Passwort funktioniert)
  3. Zu Account > Update Email > [email protected] gehen
  4. Den Posteingang von [email protected] prüfen – dort findest du eine E-Mail von npmjs.com

5.Link öffnen https://www.npmjs.com/verify/{some_random_token_here} Er leitet zum Login weiter > Versuche, dich mit dem Benutzernamen & Passwort des Opfers anzumelden
6.Du wirst zur 404-Seite weitergeleitet & ohne Verifizierungscode am Konto angemeldet! (Auch wenn die Seite eine Meldung anzeigt, die besagt, dass du nicht als der richtige Nutzer angemeldet bist)

POC –

https://youtube.com/watch?v=ox6np-b3nyI%3Ffeature%3Doembed

Auswirkung –

Ein Angreifer kann eine Schwachstelle in npmjs ausnutzen, um den Login-Verifizierungsprozess zu umgehen, der eigentlich vor Angriffen zum Abgreifen und Ausleiten von Zugangsdaten schützen soll. Damit kann der Angreifer unbefugten Zugriff auf das Konto erlangen, ohne die vorgesehenen Sicherheitsprüfungen zu durchlaufen. Diese Schwachstelle ist im Kern eine Umgehung des Login-Verifizierungsprozesses, der als vorübergehende Maßnahme dient, bis die Zwei-Faktor-Authentifizierung aktiviert ist.

Unser Fazit –

Zusammenfassend: Auch wenn es uns Freude bereitet hat, eine Schwachstelle bei GitHub zu entdecken, waren wir von der ausgezahlten Prämie enttäuscht. Obwohl wir die auf der Hackerone-Richtlinienseite von GitHub aufgeführten Kriterien für eine kritische Schwachstelle erfüllten – darunter die Umgehung des Anmeldevorgangs, den Zugriff auf sensible Nutzerdaten und den Zugriff auf die Daten eines anderen Nutzers -, wurden wir als mittel eingestuft und erhielten von GitHub keine klare Begründung. Auch unser Versuch, über H1 Mediation mit dem GitHub-Team ins Gespräch zu kommen, blieb vergeblich. Wir sind der Ansicht, dass diese Situation Fragen zur Fairness des Belohnungssystems von GitHub und zur Einhaltung ihrer eigenen Richtlinien aufwirft.

Kriterien für kritische Schwachstellen laut der Hackerone-Richtlinienseite von GitHub

  • beliebige Code-/Befehlsausführung auf einem Server in unserem Produktionsnetzwerk
  • beliebige SQL-Abfragen auf einer Produktionsdatenbank
  • Umgehung des Anmeldevorgangs, entweder Passwort oder 2FA
  • Zugriff auf sensible Produktions-Nutzerdaten oder Zugriff auf interne Produktionssysteme
  • Zugriff auf die Daten eines anderen Nutzers im GitHub-Actions-Dienst

SCREENSHOT DER GITHUB-RICHTLINIE

Bitte um Feedback vom GitHub-Team:

Falls ein Mitglied des GitHub-Teams eine Begründung für die Einstufung der Schwachstelle hat, würden wir uns über eine Antwort im Report oder über eine Kontaktaufnahme über unsere H1-Handles @th3pr0xyb0y und @mrrajputhacker2 freuen

Pre-Account-Takeover auf npmjs.com 

Beschreibung  –

Nachdem wir die Anwendung gründlich untersucht hatten, beschlossen wir, uns auf das Aufspüren von Logikfehlern zu konzentrieren. Dabei fiel uns auf, dass der Authentifizierungsprozess zur Anmeldung nur einen Benutzernamen verwendete und dass sich die E-Mail-Adresse problemlos ohne Passwortbestätigung ändern ließ. Das brachte uns zu der Annahme, dass der Benutzername ein zentraler Bestandteil des Backends von npmjs.com war.

Wir testeten die Funktion zum Löschen des Kontos und untersuchten die folgenden Szenarien:

  1. Konnten wir noch auf die Konto-Sitzung zugreifen, wenn sie in einem anderen Browser angemeldet war?
    Wir stellten fest, dass das Löschen des Kontos in einem Browser den Nutzer sofort aus allen anderen Sitzungen abmeldet.
  2. Konnten wir uns mit demselben Benutzernamen eines kürzlich gelöschten Kontos registrieren?
    Unsere Tests zeigten, dass eine Registrierung mit einem bestehenden oder zuvor gelöschten Benutzernamen nicht möglich war.
  3. Gab es eine Möglichkeit, den Benutzernamen zu ändern oder einen neuen/gelöschten Benutzernamen zu beanspruchen? Wir entdeckten eine Option, um in der Anwendung einen Benutzernamen zu beanspruchen oder zu ändern – indem man im npmjs-Konto eine Organisation erstellt. Damit konnten wir einen neuen Benutzernamen für die Organisation wählen oder unser Konto in eine Organisation umwandeln und so im Grunde unseren Benutzernamen ändern. Doch auch diese Option erlaubte es uns nicht, zu einem zuvor gelöschten Benutzernamen zu wechseln.

Obwohl wir bei allen drei Szenarien in Sackgassen gerieten, waren wir entschlossen, eine Lösung zu finden, und schafften es dank unserer Hartnäckigkeit, das System erfolgreich zu umgehen. Wir haben die Schritte in unserem Report dokumentiert, um zu zeigen, wie wir einen Pre-Account-Takeover erzeugen konnten.

Neue Beobachtungen in unserer Recherche –

Wir wussten bereits, dass wir die Löschung unseres Kontos durch das Einreichen eines Support-Tickets anfordern konnten. Also testeten wir diese Methode und löschten unser Konto. Nach Erhalt der Bestätigungs-E-Mail stellten wir fest, dass wir trotz des gelöschten Kontos weiterhin angemeldet waren und unser Benutzername oben rechts angezeigt wurde, wir aber keine Aktionen ausführen konnten.

Wir versuchten, den gelöschten Benutzernamen erneut zu beanspruchen, indem wir uns in einem anderen Browser registrierten, doch das war nicht möglich. Wir hatten jedoch einen Weg gefunden, unseren Benutzernamen zu ändern, also versuchten wir, ihn in einem anderen Browser erneut zu beanspruchen. Zu unserer Überraschung gelang es – und sobald wir den Benutzernamen beansprucht hatten, wurde die Sitzung auf unsere vorherige Sitzung übertragen, in der wir nur eine 404-Fehlerseite gesehen hatten. Auf diese Weise konnten wir das Konto einer Person übernehmen, die versuchte, ihren Benutzernamen auf ein gelöschtes Konto zu ändern – denn wir hatten die Cookies und die Sitzung wurde auf uns übertragen.

Falls die Erklärung verwirrend erscheint, sieh dir bitte die Schritte zur Reproduktion und den Proof of Concept an, um diese Schwachstelle besser zu verstehen.

Schritte zur Reproduktion –

  1. Registriere dich als Angreifer mit einem gängigen Benutzernamen (z. B. commonusername123) im Browser Google Chrome.
  2. Fordere beim Support die Löschung des Kontos an.
  3. Sobald der Support das Konto gelöscht hat, aktualisiere den Browser, in dem das Konto angemeldet war. Du wirst sehen, dass alle Seiten außer der Profilseite deinen Benutzernamen anzeigen (der Link der Seite wäre https://npmjs.com/~username).
  4. Versuche, https://www.npmjs.com/settings/commonusername123/profile aufzurufen. Du wirst eine 404-Seite sehen.
  5. Registriere dich als Opfer mit einem anderen Benutzernamen (z. B. victimusername123) im Browser Firefox.
  6. Wandle das Opfer-Konto in eine Organisation um. Dadurch erhält die Organisation den Benutzernamen victimusername123 und du wirst aufgefordert, einen neuen Benutzernamen zu wählen. Wähle commonusername123 als neuen Benutzernamen für das Konto.
  7. Aktualisiere im Browser Google Chrome die Seite der Angreifer-Sitzung https://npmjs.com/~username.
  8. Versuche, https://www.npmjs.com/settings/commonusername123/profile aufzurufen. Du wirst nun die E-Mail-Adresse des Opfers sehen (z. B. [email protected]) und hast Zugriff auf das Opfer-Konto und die von ihm erstellte Organisation.

POC –

https://youtube.com/watch?v=5039T3y8yFw%3Ffeature%3Doembed

Auswirkung –

Ein böswilliger Akteur kann auf npmjs.com mehrere Konten mit gängigen Benutzernamen anlegen, sie durch das Einreichen eines Support-Tickets löschen und die Cookies behalten. Dadurch hat er die Möglichkeit, ein Konto zu übernehmen, falls jemand anderes diese Benutzernamen beansprucht.

Unser Fazit – 

Zusammenfassend: Auch wenn wir begeistert waren, eine Schwachstelle bei GitHub aufzudecken, waren wir von der erhaltenen Prämie enttäuscht. Es handelte sich um eine komplexe, aber durchführbare Kontoübernahme, die eine große Organisation hätte treffen können. Um die Auswirkung zu verdeutlichen: Wir hatten immer noch ein Konto mit gespeicherten Cookies und aktiven Sitzungen, die seit über drei Monaten liefen, denn die Sitzung eines gelöschten Kontos läuft auf npmjs nie ab. GitHub stufte diese Schwachstelle jedoch als “mittel” ein und gewährte uns lediglich eine $4000 Prämie.

Zugriffskontroll-Problem auf education.github.com

Beschreibung  –

Da wir mit GitHubs Reaktion auf unsere zuvor auf npmjs gemeldeten Schwachstellen und mit der Prämie unzufrieden waren, beschlossen wir, uns auf andere GitHub-Subdomains zu konzentrieren. Wir stellten fest, dass education.github.com für den Anmeldevorgang GitHub Single Sign-On (SSO) verwendete. Inspiriert von den auf npmjs gefundenen Fehlern experimentierten wir mit einem ähnlichen Ansatz unter Verwendung von Benutzernamen gelöschter Konten.

Zu unserer Überraschung stellten wir fest, dass das Löschen eines GitHub-Kontos nicht dazu führte, dass die Sitzung auf education.github.com ablief, und dass jede Seite einen 404-Fehler anzeigte, selbst wenn man noch angemeldet war. In einem anderen Browser versuchten wir, ein neues GitHub-Konto mit demselben gelöschten Benutzernamen zu erstellen, doch gemäß der Richtlinie von GitHub können Benutzernamen für 90 Tage nach der Löschung nicht beansprucht werden .

Doch trotz dieser Sackgassen gelang es uns, das Problem zu umgehen und Zugriffskontrolle zu erlangen . 

Umgehung der Zugriffskontrolle –

Wir beobachteten, dass der Benutzername gleich blieb, selbst nachdem wir einen Benutzernamen in GitHub geändert und unsere Sitzung von education.github.com aktualisiert hatten – er änderte sich nicht, obwohl wir ihn in unserem GitHub-Profil geändert hatten. Das liegt daran, dass das Sitzungstoken an den Benutzernamen gebunden ist und SSO es nur dann aktualisiert, wenn wir uns erneut über GitHub anmelden. Also beanspruchten wir schnell das gelöschte GitHub-Konto und dann den alten Benutzernamen, der bei https://education.github.com  noch mit diesem Konto verknüpft war, mit einem neuen GitHub-Konto in einem anderen Browser, und meldeten uns bei https://education.github.com in einem neuen Browser an.  Nun beobachteten wir, dass beide Konten denselben Benutzernamen, aber unterschiedliche zugehörige E-Mail-Adressen hatten und vollständig funktionsfähig waren. Wenn wir also ein Bildungsformular abschickten oder Funktionen auslösten, konnte das auf beiden Seiten die Datenintegrität beschädigen. Wir meldeten dies daher als Problem, und es wurde als gültiges Problem akzeptiert .

Uns fiel auf, dass die Sitzung auf education.github.com selbst nach dem Ändern unseres GitHub-Benutzernamens unverändert blieb. Das lag daran, dass das Sitzungstoken an den Benutzernamen gebunden war und das SSO es nur beim Anmelden über GitHub aktualisierte. Um dies auszunutzen, beanspruchten wir schnell ein gelöschtes GitHub-Konto und dann den alten Benutzernamen, der noch mit dem education.github.com-Konto verknüpft war. Anschließend meldeten wir uns mit einem neuen GitHub-Konto in einem anderen Browser bei education.github.com an und stellten fest, dass beide Konten nun denselben Benutzernamen, aber unterschiedliche E-Mail-Adressen hatten und voll funktionsfähig waren.

Das bedeutete: Wenn wir ein Bildungsformular abschickten oder Funktionen auslösten, konnte dies auf beiden Seiten die Datenintegrität beschädigen. Wir meldeten dies umgehend als Problem, und es wurde als gültige Schwachstelle akzeptiert.

Schritte zur Reproduktion – 

  1. Melde dich bei deinem GitHub-Konto an
  2. Rufe https://education.github.com/schools auf
  3. Ändere den Benutzernamen in deinem GitHub-Konto
  4. Aktualisiere die Seite oder rufe https://education.github.com/schools erneut auf und überprüfe den Benutzernamen über das Profilsymbol rechts
  5. Du wirst sehen, dass der alte Benutzername auf education.github.com noch aktiv ist
  6. Da der alte Benutzername beanspruchbar ist, scheint eine Kontoübernahme auf education.github.com möglich zu sein, indem man ihn beansprucht.
  7. Wenn du keine College-E-Mail-Adresse hast, kannst du nicht überprüfen, ob die in der alten Sitzung durchgeführten Aktionen ein neues, mit dem alten Benutzernamen registriertes Konto beeinflussen.
  8. Melde dich in einem neuen Chrome-Fenster bei education.github.com mit einem neu erstellten Konto an, das denselben Benutzernamen wie die alte Sitzung hat.
  9. Du wirst sehen, dass du nun zwei aktive Sitzungen mit demselben Benutzernamen hast.

Auswirkung –

Die Auswirkung dieses Problems sollte vom GitHub-Team bewertet werden. Es hat das Potenzial, sensible Informationen neuer Nutzer zu gefährden, etwa ihre Schule oder E-Mail-Adresse und personenbezogene Daten (PII), falls sie sich mit dem Benutzernamen registrieren, für den eine aktive Sitzung besteht. Dies könnte zu einer Kontoübernahme und zum Abfluss von PII führen.

Unser Fazit – 

Wir freuten uns, diese Schwachstelle bei GitHub zu entdecken, auch wenn sie dem ähnelte, was wir auf npmjs gefunden hatten. Diesmal konnten wir die volle Auswirkung des Problems nicht einschätzen. Dennoch waren wir mit der gewährten Prämie zufrieden.

Hast du etwas von uns gelernt?

Unterstütze uns, indem du diesen Artikel mit deinen Freunden, deiner Familie und deinen Kollegen teilst und uns in unseren Social-Media-Kanälen folgst. Du kannst dich auch in unsere Mailingliste eintragen, um weitere informative Write-ups über unsere Ergebnisse zu erhalten. Zeig deine Unterstützung, indem du über diesen Artikel twitterst und ihn so weit wie möglich mit der Community teilst.

Wirf einen Blick auf unser neues Produkt Blind XSS Hunter, das die Community unterstützen soll – nur unter https://bxsshunter.com.

Mach dich bereit für einen spannenden Launch von CyberXplore! Wir haben in den vergangenen zwei Jahren hart daran gearbeitet, ein Produkt zu perfektionieren, das wir kaum erwarten können, mit dir zu teilen. Sei einer der Ersten, der es erlebt, indem du mit uns in Verbindung bleibst oder uns auf unserer Reise folgst. Und damit du alle Neuigkeiten erhältst, abonniere unbedingt unseren Newsletter! Diesen Launch willst du nicht verpassen!

Ähnliche Artikel

Machen Sie aus diesen Insights ein Projekt

Erhalten Sie einen von Senior-Experten geführten Penetrationstest, zugeschnitten auf Ihren Stack - umsetzbare Ergebnisse statt Checkliste.

  • Kostenloser Nachtest für jeden Fix
  • Scope und Angebot innerhalb von 24 Stunden
  • Ausschließlich Senior-Tester
  • ISO 27001
  • ISO 9001
  • OSCP
  • CRTP
  • CREST
Angebot anfordern