Harborコンテナレジストリに管理者に特権昇格が可能な深刻な脆弱性 (CVE-2019-16097)

By

Category: Cloud, Unit 42

Tags: , , ,

This post is also available in: English (英語)

エグゼクティブサマリー

パロアルトネットワークス脅威インテリジェンスリサーチチームUnit 42のクラウド部門のリサーチャーAviv Sassonが、広く利用されているクラウド ネイティブ コンテナ レジストリ「Harbor」に重大な脆弱性があることを発見しました。本脆弱性を使って攻撃者が悪意のあるリクエストを送信するとHarborレジストリを乗っ取ることが可能です。

Harborのメンテナは、この重要なセキュリティ問題に対応するためのパッチをリリースしました。バージョン1.7.6および1.8.3にこの修正が含まれています。

Unit 42では、脆弱なデフォルトの設定でインターネットに公開されているHarborレジストリが1,300件に及ぶことを確認しています。これらは修正版に更新されるまで危険な状態にあります。

背景

Cloud Native Computing Foundation(CNCF)プロジェクトに貢献し、改善するイニシアチブの一環として、ここのところ私はHarbourプロジェクトに着目していました。その結果、デフォルト設定で、誰でも管理者権限を取得できる重大な権限昇格の脆弱性があることを発見しました。当該脆弱性にはCVE-2019-16097が割り当てられ、9月10日に公開されました。

Harborは、オープンソースのクラウド ネイティブ コンテナ レジストリで、コンテナ イメージを保存し、署名し、脆弱性のスキャンをすることができます。Harborは、Docker Hub、Docker Registry、Google Container Registryなどのレジストリとの統合が可能です。Harbor を利用すると、ユーザーはシンプルなGUIを使って、パーミッションに基づき、コンテナ イメージをダウンロード、アップロード、スキャンできようになります。

Harborプロジェクトはここ4年ほどで徐々に人気を集め、2018年の11月にCNCFの支援を受けるプロジェクトになりました。Harborには著名なスポンサーや企業が多数ついており、採用企業の一覧がこちらのページにあります

図1 Harbor 公式認定ユーザーとパートナー

脆弱性の影響度

この脆弱性の影響度は深刻です。管理者権限を取得後に開始可能な攻撃ベクトルは多数存在します。攻撃者は、いかなるプライベート プロジェクトであれダウンロードして検査することができます。レジストリ内のすべてのコンテナ イメージを削除することもでき、もっと悪ければコンテナ レジストリ内のイメージを自分たちのイメージに置き換えることでレジストリを汚染することもできます。攻撃者は新しいユーザーを作成し、作成したユーザーを管理者に設定することができます。その後、Dockerコマンドライン ツールで新しい資格情報を使用し、Harborコンテナ レジストリに接続して、現在のイメージをどのようなイメージにでも置き換えることができます。そのなかにはマルウェア、暗号通貨のマイナー プログラム、そのほかのさまざまな悪意のあるプログラムを含めることができます。

               

ビデオ1 脆弱性の概念実証のためのエクスプロイト

オンライン インスタンス

この問題が深刻であることがわかったのでオンラインにあるHarborのインスタンス数を確認することにしました。スキャンした結果から、オンラインにはHarborレジストリが2,500あることがわかりました。これらのなかから脆弱なインスタンス数を評価するため、私はそれ専用に書いたスクリプトを実行して結果的に脆弱なインスタンスが1,300件存在することを突き止めました。

脆弱性

以下、脆弱性の内容を具体的に見ていきます。最初に「User」構造体を調べます。

図2 HarborソースコードのUser構造体

ここで標的とするパラメータはHasAdminRoleです。というのも、このパラメータあるユーザに管理者権限があるかどうかを示すものだからです。このパラメータをTrueに設定できれば攻撃側の勝ちです。

それにはどうすればよいでしょうか。

API呼び出しを眺めてみます。すると誰かが「/api/users」へアクセス試行したさいに起こる、ある興味深い呼び出しが見つかります。

図3 /api/users ルーティング

その誰かがPOSTリクエストを送信した場合、結果として以下のコードにたどり着くことになります。以下コードでは新しいユーザの登録を行っています。

図4 POSTリクエストの処理ロジック

問題はuser.goの317行目に存在します。

このコード行は、POSTリクエストからデータを取得し、それを1つのユーザーオブジェクトにデコードしています。

通常のリクエスト ペイロードは次のようになります。

ここで問題になるのは、このリクエストを送信するさい、パラメータhas_admin_roleを追加できてしまうことです。

has_admin_roletrueに設定して同じリクエストを送信すると、作成されるユーザーは管理者になります。つまり、悪用は非常に容易です。

エクスプロイト

リクエスト ボディのhas_admin_roleパラメーターをtrueに設定して管理者権限を持つ新しいユーザーを作成するため、/api/users にPOSTリクエストを送る簡単なPythonスクリプトを作成しました。スクリプトを実行後はブラウザでHarborを開き、作成したユーザーとしてサインインするだけでエクスプロイトは完了します。

開示にいたる過程

私はこの脆弱性の影響を評価し、責任ある開示を行う準備を整えました。その間にもHarborのメンテナ一同は、同脆弱性の修正を含むコミットをGitHubのmasterブランチにリリースしてくれました。私はHarborチームにこれが重大なセキュリティ上の脆弱性であることを知らせ、CVEの割り当てを行う支援を行いました。またできるだけ早く新しいリリースを公開するよう助言し、同チームはそれに応える形で迅速に公開をしてくれました。

緩和・回避策

Harborチームは、この問題に対処するパッチをリリース済みです。同パッチは、メンテナの1人によるプルリクエストにより公開され、9月18日にリリースされたHarborバージョン1.7.6および1.8.3にのみ含まれています。リリースノートには、「Disallow creating an admin user when registration(登録時に管理ユーザーの作成を許可しない)」という説明がされ、この問題が解決されたことが説明されています。

同チームのメンテナは、管理者ではないユーザーが新しく管理者ユーザーを作成できないようにするチェックを追加しています。

この脆弱性はHarborのバージョン1.7.0から1.8.2に存在します。当該脆弱性は緊急レベルのもので、誰であってもレジストリに完全にアクセスできるため、すべてのユーザーが自身のインストールしたHarborをただちに更新することをお勧めします。

自分のレジストリが影響を受けるかどうかを調べるには

バージョン1.7.0から1.8.2の古いバージョンのHarborインスタンスをお持ちの場合、同脆弱性による影響を受けます。ただちにパッチを適用して更新するか、少なくともインターネットへの接続を遮断する必要があります。自身の環境がハッキングされたかどうかを確認するには、Harborインスタンス上の管理者権限を持つ見覚えのないユーザーの有無を確認してください。ただし、攻撃者がすでに攻撃に使用したユーザーを削除済みの可能性はあります。その場合は侵害の有無を検出するのは難しくなります。ですが、少なくともスポットチェックは行うことをお勧めします。