10 points par outsideris 2021-04-07 | Aucun commentaire pour le moment. | Partager sur WhatsApp

L’histoire d’un élève de terminale qui, ayant du temps libre à cause du Covid, s’est lancé dans la chasse aux bug bounty et a touché 35 000 dollars grâce à un bug bounty sur des pages pirvates de GitHub.

Il a signalé le bug bounty des pages pirvates de GitHub, avec deux bonus CTF.

  • 10 000 dollars : lire le flag depuis flag.private-org.github.io sans interaction utilisateur. Si ce flag peut être lu depuis un compte situé hors de l’organisation private-org, un bonus supplémentaire de 5 000 dollars est accordé.

  • 5 000 dollars : lire le flag depuis flag.private-org.github.io avec interaction utilisateur.

Flux d’authentification

GitHub Pages étant hébergé sur un domaine distinct, github.io, les cookies d’authentification de github.com ne sont pas envoyés au serveur des private pages. L’authentification des private pages ne peut donc pas identifier l’utilisateur sans intégration supplémentaire avec github.com. GitHub a donc conçu un flux d’authentification personnalisé.

  • Lorsqu’on visite une private page, le serveur vérifie la présence du cookie __Host-gh_pages_token.

  • Si le cookie est absent ou invalide, le serveur de private pages redirige vers https://github.com/login.

  • Cette redirection définit aussi un nonce dans le cookie __Host-gh_pages_session.

    • Ce cookie utilise le préfixe __Host-, ce qui empêche sa définition en JavaScript depuis un autre domaine hôte.
  • /login redirige vers /pages/auth?nonce=&page_id=&path=.

  • À cet endroit, un cookie d’authentification temporaire est créé à partir du paramètre token, puis transmis à https://pages-auth.github.com/redirect.

  • /redirect transfère ensuite vers https://repo.org.github.io/__/auth.

  • Ce point de terminaison final définit les cookies d’authentification __Host-gh_pages_token et __Host-gh_pages_id sur le domaine repo.org.github.io.

  • Le nonce précédemment défini dans __Host-gh_pages_session y est également vérifié.

Le chemin de la requête d’origine et l’ID de la page sont stockés respectivement dans les paramètres de requête path et page_id, et le nonce est stocké dans le paramètre nonce.

Exploitation

Retour CRLF

  • La première vulnérabilité était une injection CRLF dans le paramètre page_id de https://repo.org.github.io/__/auth.

  • Il a découvert que l’analyse de page_id ignorait les espaces et que cette valeur était directement placée dans l’en-tête Set-Cookie.

  • Une injection CRLF traditionnelle permet de casser l’analyse, mais n’a pas d’autre effet.

  • Comme l’en-tête Location: est ajouté après l’en-tête Set-Cookie, l’en-tête Location est ignoré malgré la redirection 302, et le corps de la réponse est rendu.

Attaque

  • En consultant le code GitHub Enterprise, il a appris que le serveur de private pages était implémenté avec openresty nginx.

  • Il a réussi une XSS en ajoutant un octet nul. Cet octet nul doit se trouver au début du body, ce qui empêche une attaque par injection d’en-têtes.

  • Il était alors possible d’exécuter du JavaScript arbitraire sur le domaine des private pages.

  • Il ne restait plus qu’à trouver un moyen de contourner le nonce.

Contournement du nonce

  • En observant le comportement, il a découvert que des private pages sœurs d’une même organisation pouvaient définir des cookies les unes pour les autres.

  • Un cookie défini sur private-org.github.io est transmis à private-page.private-org.github.io.

  • Si l’on peut contourner la protection du préfixe __Host-, il devient facile de contourner le nonce.

  • Tous les navigateurs ne le prennent pas en charge, et IE ne prend pas en charge le préfixe __Host-.

  • Mais en cherchant une meilleure approche, une idée intéressante lui est venue.

  • En vérifiant comment les cookies traitent la casse, il a constaté que __HOST et __Host étaient considérés différemment, tandis que GitHub private pages ignore les majuscules lors de l’analyse des cookies.

  • Il a ainsi pu définir le nonce en JavaScript.

  • Il a reçu le bonus de 5 000 dollars.

Empoisonnement du cache

  • La réponse du point de terminaison /__/auth? est mise en cache selon la valeur entière du page_id falsifié.

  • Cela permet d’affecter aussi des utilisateurs sans interaction si l’on réussit un empoisonnement du cache via la charge utile XSS.

  • Si un attaquant vise unprivileged.org.github.io pour corrompre l’authentification, la charge utile XSS est mise en cache.

  • Comme les cookies sont partagés sur le domaine parent org.github.io, l’attaquant peut aussi viser privileged.org.github.io.

Pages privées publiques

  • Pour obtenir le bonus de 15 000 dollars, il fallait qu’un utilisateur non membre de l’organisation puisse mener cette attaque.

  • Cela a été possible grâce à une mauvaise configuration consistant à activer des private pages sur un dépôt public.

    • Il s’agit de créer des pages à partir d’un dépôt privé, puis de rendre le dépôt public.
  • Avec cette mauvaise configuration, la private page fait passer tous les utilisateurs par le flux d’authentification et accorde des droits de lecture à des utilisateurs extérieurs à l’organisation.

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.