10 ポイント 投稿者 outsideris 2021-04-07 | まだコメントはありません。 | WhatsAppで共有

高校3年生の学生がCovidで時間ができたためバグバウンティハンティングを行い、GitHubのprivate pagesのバグバウンティで35,000ドルを受け取った話。

GitHubのprivate pagesのバグバウンティとして報告され、2つのCTFボーナスがあった。

  • 10,000ドル: ユーザーインタラクションなしで flag.private-org.github.io からフラグを読む。private-org 組織の外にあるアカウントからこのフラグを読めれば5,000ドルの追加ボーナスがある。

  • 5,000ドル: ユーザーインタラクションを通じて flag.private-org.github.io からフラグを読む。

認証フロー

GitHub Pagesは別ドメイン github.io でホストされるため、github.com の認証Cookieはprivate pagesサーバーには送信されない。したがって、private pagesの認証は github.com との追加の統合なしにはユーザーの身元を判別できない。そこでGitHubはカスタム認証フローを作成した。

  • privateページにアクセスすると、サーバーは __Host-gh_pages_token Cookieの存在を確認する。

  • Cookieが存在しない、または正しくない場合、private pageサーバーは https://github.com/login へリダイレクトする。

  • このリダイレクトは __Host-gh_pages_session Cookieにnonceも設定する。

    • このCookieは __Host- Cookieプレフィックスを使用しているため、ホストドメイン以外からJavaScriptで設定されるのを防ぐ。
  • /login/pages/auth?nonce=&page_id=&path= にリダイレクトする。

  • ここでは token パラメータから https://pages-auth.github.com/redirect に渡す一時的な認証Cookieを生成する。

  • /redirecthttps://repo.org.github.io/__/auth に転送する。

  • この最終エンドポイントは repo.org.github.io ドメインで認証Cookieである __Host-gh_pages_token__Host-gh_pages_id を設定する。

  • ここで先ほど設定した __Host-gh_pages_sessionnonce も確認する。

元のリクエストパスとページIDはそれぞれクエリパラメータ pathpage_id に保存され、nonceも nonce パラメータに保存される。

悪用

CRLFリターン

  • 最初の脆弱性は https://repo.org.github.io/__/authpage_id パラメータにおけるCRLF注入だった。

  • page_id のパースが空白文字を無視し、この値が Set-Cookie ヘッダーにそのまま設定されることが分かった。

  • 従来のCRLF注入でパースを壊すことはできるが、それ以外の影響はない。

  • Location: ヘッダーが Set-Cookie ヘッダーの後に付くため、302リダイレクトであるにもかかわらずLocationヘッダーが無視され、本文がレンダリングされる。

攻撃

  • GitHub Enterpriseのコードを見て、private pageサーバーがopenresty nginxで実装されていることが分かった。

  • nullバイトを追加してXSSに成功した。このnull byteは本文の先頭に来る必要があるため、ヘッダー注入攻撃はできない。

  • これによりprivate pageドメイン上で任意のJavaScriptコードを実行できるようになった。

  • あとはnonceをバイパスする方法を見つけるだけだった。

nonceバイパス

  • 観察の結果、同じ組織のsibling privateページ同士は互いにCookieを設定できることを発見した。

  • private-org.github.io で設定されたCookieは private-page.private-org.github.io に送られる。

  • __Host- プレフィックス保護を回避できればnonceを簡単にバイパスできる。

  • ただし、これをサポートするのはすべてのブラウザではなく、IEは __Host- プレフィックスをサポートしていない。

  • しかし、より良い方法を探しているうちに面白いアイデアを思いついた。

  • Cookieが大文字小文字をどう扱うか確認したところ、__HOST__Host を別物として扱い、GitHub private pagesはCookieをパースする際に大文字を無視することが分かった。

  • JavaScriptでnonceを指定できるようになった。

  • 5,000ドルのボーナスを受け取ることになった。

キャッシュ汚染

  • /__/auth? エンドポイントのレスポンスは、フィッシングされた page_id の整数値でキャッシュされる。

  • これにより、XSSペイロードを使ってキャッシュ汚染に成功すれば、インタラクションしていないユーザーにも影響を与えられる。

  • 攻撃者が unprivileged.org.github.io を攻撃して認証を汚染すると、XSSペイロードがキャッシュされる。

  • Cookieが親ドメイン org.github.io で共有されるため、攻撃者は privileged.org.github.io も攻撃できる。

公開されたprivateページ

  • 15,000ドルのボーナスを得るには、組織に属さないユーザーにこの攻撃を実行させる必要があった。

  • publicリポジトリでprivate pagesを設定する誤設定により、この攻撃が可能だった。

    • privateリポジトリでページを作成した後、リポジトリをpublicに変更することを指す。
  • この誤設定されたprivateページでは、すべてのユーザーが認証フローに入るようになり、組織外のユーザーに読み取り権限を与えてしまう。

まだコメントはありません。

まだコメントはありません。