10 Punkte von outsideris 2021-04-07 | Noch keine Kommentare. | Auf WhatsApp teilen

Die Geschichte eines Schülers in der 12. Klasse, der während Covid mehr Zeit hatte, auf Bug-Bounty-Jagd ging und für einen Bug Bounty in privaten GitHub Pages 35.000 Dollar erhielt.

Er meldete den Bug Bounty für private GitHub Pages, und es gab zwei CTF-Boni.

  • 10.000 Dollar: Die Flag von flag.private-org.github.io ohne Benutzerinteraktion lesen. Wenn diese Flag von einem Account außerhalb der Organisation private-org gelesen werden kann, gibt es einen zusätzlichen Bonus von 5.000 Dollar.

  • 5.000 Dollar: Die Flag von flag.private-org.github.io mit Benutzerinteraktion lesen.

Authentifizierungsablauf

GitHub Pages wird auf der separaten Domain github.io gehostet, daher werden die Authentifizierungs-Cookies von github.com nicht an den Server für private Pages gesendet. Deshalb kann die Authentifizierung privater Pages die Identität eines Nutzers ohne zusätzliche Integration mit github.com nicht feststellen. Deshalb hat GitHub einen eigenen Authentifizierungsablauf gebaut.

  • Beim Besuch einer privaten Page prüft der Server, ob das Cookie __Host-gh_pages_token vorhanden ist.

  • Wenn das Cookie fehlt oder ungültig ist, leitet der Server der privaten Page auf https://github.com/login weiter.

  • Diese Weiterleitung setzt außerdem eine Nonce im Cookie __Host-gh_pages_session.

    • Dieses Cookie verwendet das Cookie-Präfix __Host-, wodurch verhindert wird, dass es per JavaScript außerhalb der Host-Domain gesetzt wird.
  • /login leitet auf /pages/auth?nonce=&page_id=&path= weiter.

  • Dort wird über den Parameter token ein temporäres Authentifizierungs-Cookie erzeugt, das an https://pages-auth.github.com/redirect weitergegeben wird.

  • /redirect leitet an https://repo.org.github.io/__/auth weiter.

  • Dieser letzte Endpunkt setzt auf der Domain repo.org.github.io die Authentifizierungs-Cookies __Host-gh_pages_token und __Host-gh_pages_id.

  • Dabei wird auch die zuvor gesetzte nonce aus __Host-gh_pages_session geprüft.

Der ursprüngliche Anfragepfad und die Page-ID werden jeweils in den Query-Parametern path und page_id gespeichert, und die Nonce wird im Parameter nonce gespeichert.

Ausnutzung

CRLF-Rückgabe

  • Die erste Schwachstelle war eine CRLF-Injektion im Parameter page_id von https://repo.org.github.io/__/auth.

  • Dabei wurde festgestellt, dass das Parsing von page_id Leerraum ignoriert und dieser Wert direkt im Header Set-Cookie gesetzt wird.

  • Mit klassischer CRLF-Injektion lässt sich das Parsing zwar brechen, aber es hat sonst keine weiteren Auswirkungen.

  • Da der Header Location: hinter dem Header Set-Cookie angehängt wird, wird der Location-Header trotz 302-Redirect ignoriert und der Body gerendert.

Angriff

  • Durch Einsicht in den GitHub-Enterprise-Code wurde klar, dass der Server für private Pages mit openresty nginx implementiert ist.

  • Durch Hinzufügen eines Null-Bytes gelang eine XSS; dieses Null-Byte muss am Anfang des Bodys stehen, daher ist kein Header-Injection-Angriff möglich.

  • Damit konnte nun beliebiger JavaScript-Code auf der Domain der privaten Page ausgeführt werden.

  • Es blieb nur noch, einen Weg zu finden, die Nonce zu umgehen.

Umgehung der Nonce

  • Beobachtungen zeigten, dass private Sibling-Pages derselben Organisation gegenseitig Cookies setzen können.

  • Ein auf private-org.github.io gesetztes Cookie wird an private-page.private-org.github.io weitergegeben.

  • Wenn sich der Schutz des Präfixes __Host- umgehen lässt, kann die Nonce leicht umgangen werden.

  • Das wird nicht von allen Browsern unterstützt; IE unterstützt das Präfix __Host- nicht.

  • Auf der Suche nach einer besseren Methode kam dann eine interessante Idee auf.

  • Beim Prüfen der Groß-/Kleinschreibung von Cookies stellte sich heraus, dass __HOST und __Host unterschiedlich behandelt werden und GitHub private Pages beim Parsen von Cookies Großbuchstaben ignoriert.

  • Dadurch ließ sich die Nonce per JavaScript festlegen.

  • Dafür gab es den Bonus von 5.000 Dollar.

Cache Poisoning

  • Die Antwort des Endpunkts /__/auth? wird anhand des ganzzahligen Werts der gefälschten page_id gecacht.

  • Dadurch sind auch Nutzer ohne Interaktion betroffen, wenn es gelingt, per XSS-Payload den Cache zu vergiften.

  • Wenn ein Angreifer unprivileged.org.github.io angreift und die Authentifizierung vergiftet, wird die XSS-Payload gecacht.

  • Da Cookies auf der Parent-Domain org.github.io geteilt werden, kann der Angreifer auch privileged.org.github.io angreifen.

Öffentliche private Pages

  • Um den Bonus von 15.000 Dollar zu erhalten, musste ein Nutzer außerhalb der Organisation diesen Angriff ausführen können.

  • Möglich wurde das durch eine Fehlkonfiguration, bei der private Pages für ein öffentliches Repository eingerichtet waren.

    • Gemeint ist, dass Pages in einem privaten Repository erstellt und das Repository anschließend auf public umgestellt wird.
  • Diese fehlkonfigurierten privaten Pages durchlaufen für alle Nutzer den Authentifizierungsablauf und gewähren auch Nutzern außerhalb der Organisation Leserechte.

Noch keine Kommentare.

Noch keine Kommentare.