Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2021年6月30日にStefano Chiericiが投稿したブログ(https://sysdig.com/blog/crypto-mining-kubeflow-tensorflow-falco)を元に日本語に翻訳・再構成した内容となっております。
マイクロソフトは、Kubeflowインスタンスを標的とした新たな大規模攻撃を発見し、悪意のあるTensorFlowポッドをデプロイして、Kubernetesクラスター環境でMonero暗号通貨のマイニングに使用していることを明らかにしました。
Kubeflowは、Kubernetesで機械学習タスクを実行するためによく使われる人気の高いオープンソースのフレームワークです。一方、TensorFlowは、Kubernetes環境で機械学習を実装するために使用される、オープンソースの機械学習プラットフォームです。
機械学習のワークロードは膨大な処理能力を必要とし、GPUを利用できる仕組みもあります。これらは、クリプトマイニングリグ(暗号通貨のマイニングを行う装置)の要件と同じであるため、KubeflowやTensorFlowを実行しているクラスターは、これらの攻撃の完璧にターゲットとなります。
クリオプトマイニングの価値が暴落しているのだから、クリプトマイニング攻撃の頻度は下がるはずだと思うかもしれません。しかし、このような攻撃を見続けているだけでなく、特に機械学習のワークロードをターゲットにした新しい亜種も発見されています。
この攻撃は最近発生したものであり、おそらく現在も継続中であるため、Kubeflowを実行している新しいKubernetesクラスターはすでに危険にさらされている可能性があります。
影響を受けたユーザーは、パフォーマンスの低下や、集中的なクリプトマイニングプロセスによるインフラ費用の増加に気づくかもしれません。
この記事では、KubeflowとTensorFlowについて紹介し、この攻撃がどのように機能するかを追跡し、影響を受けているかどうかを検出し、その影響を軽減するための手順を取り上げます。
Kubeflowは、MLライフサイクルの各ステージにおけるインフラストラクチャーコンポーネントを提供するエンドツーエンドの機械学習(ML)プロジェクトです。Kubernetesの上に構築されており、k8sのコアコンポーネントを再利用し、特定の機械学習のユースケースに適応させています。
Kubeflowは、Kubernetesクラスターにおける機械学習のデプロイメントをサポートするさまざまなコンポーネントを提供します。特に、Kubeflow Pipelinesというコンポーネントは、完全な機械学習のワークフローを作成するために使用されます。KubeflowパイプラインがKubernetesにデプロイされた小さなコンテナで構成されていることを説明する図
Kubeflowパイプラインの解明 - Ubuntuブログ
パイプラインは一連のステップであり、各ステップは独立したコンテナです。各ステップは、入力と出力を含み、特定の機械学習タスクを実行するイメージとしてパッケージ化されたコードの一部となります。これらをまとめてMLワークフローと呼びます。
Kubeflowパイプラインを使用すると、Kubernetes環境でTensorFlowモデルをデプロイすることができます。
Tensorflow(TF)は、汎用的なグラフベースの計算エンジンです。TFは、機械学習モデルの構築とトレーニングのための抽象化を実現します。さらに、TFはモデルのリリースを簡素化するために完全なプロダクションMLパイプラインを提供し、フレームワークはGPUハードウェアアクセラレーションもサポートしています。
KubeflowとTensorFlowの概要がわかったところで、攻撃シナリオとセキュリティ問題に進みましょう。
Microsoftは、さまざまなKubernetesクラスターにデプロイされたTensorFlowポッドが一貫して増加しているのを観測しました。同様の攻撃で時々起こることとは異なり、使用されているポッドは、Docker Hubの公式アカウントからの正規のTensorFlowイメージです。
使用された2種類のTensorFlowイメージは次の通りです:
マイクロソフトが報告した攻撃シナリオでは、攻撃者は以下のことができました:
この悪意のあるコードは、Kubernetesクラスター内で有名なMoneroマイナーをダウンロードして実行し、マイニングを開始しました。
Kubeflowダッシュボードは、Istioのingressゲートウェイによって公開されており、デフォルトでは内部でのみアクセス可能です。ポートフォワードの仕組みを使って、ユーザーはダッシュボードにアクセスし、Kubernetes APIサーバーを経由してトラフィックをトンネリングすることができます。
ユーザーは、手間をかけずにサービスにアクセスできる、より柔軟で即時性のある方法を好みます。この場合、Istio ServiceをLoad-Balancerに設定することで、サービスがインターネット上に公開され、ユーザーはUIに直接アクセスできるようになります。ダッシュボードが何の制限もなくインターネット上に直接公開されるため、この柔軟で使いやすい設定は、大きなセキュリティ問題を引き起こす可能性があります。
この設定と脆弱な認証情報を組み合わせると、環境全体が危険にさらされることになります。
これは、攻撃者が悪意のあるコードを実行するために正規のイメージを使用する、よくあるパターンです。このケースでは、会社が機械学習の目的でクラスター内のTensorFlowイメージを使用している場合、新しいパイプラインは完全に正当なものに見えるかもしれません。
今回報告された攻撃では、セキュリティの仕組みが導入されているにもかかわらず、攻撃者が完全な正規のイメージを使用しているため、悪意のあるデプロイメントがまったく検出されません。さらに、TensorFlowのイメージは、膨大な計算資源を必要とする機械学習タスクを効率的に実行するように最適化されています。
これはまさに攻撃者が求めているものです。このようなインフラやイメージを侵害するチャンスは、攻撃者にとって絶対に貴重なものであり、攻撃者はホストから得られるマイニングの利益を最大化することができます。
このシナリオでは、Kuberflow の集中型ダッシュボードをインターネット上に公開するように設定を変更したことで攻撃が可能になりました。これは大きなセキュリティ問題です。
この問題を軽減するために:
マイクロソフト社が報告した内容は、ここ数年の傾向を強調しており、暗号通貨のマイニングは依然として攻撃者が行う主な攻撃の一つです。ブルーチームは、このような種類の侵害や悪質な行動をできるだけ早く特定するために、効率的で強力な検知メカニズムを持つ必要があります。
幸いなことに、この特定の攻撃シナリオの検知は、さまざまな方法とツールで行うことができます。クリプトマイナーは非常に特徴的なパターンに従うため、その挙動を利用して強力な検知を行うことができます。
1つの方法は、インフラ監視ツールを使用して、使用されているポッドリソースをスキャンし、CPUやGPUの使用率が高い場合に警告を出すことです。
もう1つの方法は、「セキュリティ」のやり方で、ポッド内での不審な接続や悪意のあるバイナリの実行を検出することです。
ここでは、この2つの方法について説明します。
Falcoは、コンテナとKubernetesのランタイム脅威検出のためのCNCFオープンソースプロジェクトです。
Falcoの利点の1つは、その強力で柔軟なルール言語を活用することにあります。その結果、Falcoは、カスタマイズ可能なルールセットで定義された異常な動作を発見すると、セキュリティイベントを生成します。一方、Falcoには、アウトオブボックスの検知ルールがいくつか用意されています。
以下のルールは、クリプトマイナーのプロセスと、マイニングプールへの接続の両方を検出します:
# Note: falco will send DNS request to resolve miner pool domain which may trigger alerts in your environment. - rule: Detect outbound connections to common miner pool ports desc: Miners typically connect to miner pools on common ports. condition: net_miner_pool and not trusted_images_query_miner_domain_dns enabled: false output: Outbound connection to IP/Port flagged by cryptoioc.ch (command=%proc.cmdline port=%fd.rport ip=%fd.rip container=%container.info image=%container.image.repository) priority: CRITICAL tags: [network, mitre_execution] - rule: Detect crypto miners using the Stratum protocol desc: Miners typically specify the mining pool to connect to with a URI that begins with 'stratum+tcp' condition: spawned_process and proc.cmdline contains "stratum+tcp" output: Possible miner running (command=%proc.cmdline container=%container.info image=%container.image.repository) priority: CRITICAL tags: [process, mitre_execution] - rule: Container Drift Detected (chmod) desc: New executable created in a container due to chmod condition: > chmod and consider_all_chmods and container and not runc_writing_var_lib_docker and not user_known_container_drift_activities and evt.rawres>=0 and ((evt.arg.mode contains "S_IXUSR") or (evt.arg.mode contains "S_IXGRP") or (evt.arg.mode contains "S_IXOTH")) exceptions: - name: proc_name_image_suffix fields: [proc.name, container.image.repository] comps: [in, endswith] - name: cmdline_file fields: [proc.cmdline, fd.name] comps: [in, in] values: - [["runc:[1:CHILD] init"], [/exec.fifo]] output: Drift detected (chmod), new executable created in a container (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode event=%evt.type) priority: ERROR - rule: Outbound Connection to C2 Servers desc: Detect outbound connection to command & control servers condition: outbound and fd.sip in (c2_server_ip_list) exceptions: - name: proc_proto_sport fields: [proc.name, fd.l4proto, fd.sport] output: Outbound connection to C2 server (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository) priority: WARNING tags: [network]
敵の主な目的は、インフラストラクチャーでクリプトマイニングを実行し、リソースを暗号通貨のために使用することなので、インフラストラクチャー内で何かが高い割合でCPUを使用している場合には、任意の監視ツールを使用してチェックし、警告を受けることができます。
ポッドの大幅な増加を発見するには、ネームスペースごとの現在のポッドと、1日前の同じ時間帯に存在していたポッドを比較します。これは、特にkubeflowがポッドを作成したり廃棄したりしている場合、ノイズが発生する可能性があるメトリクスです。ノイズを除去するには、過去1時間の平均を取ることができます。
このようなデータをPromQLでクエリーすることができます:
100 * avg_over_time(sum by (namespace) (kube_pod_info)[1h:1h]) / avg_over_time(sum by (namespace) (kube_pod_info)[1h:1h] offset 5m)
このクエリーの結果は、昨日の同じ時間に稼働していたポッドの数と比較して、現在稼働している異なるネームスペースのポッドが1時間あたりの平均で追加された割合を示します。
監視対象クラスターの2つのネームスペースでポッドが140%増加していることを示しています。
このPromQLクエリーでアラートを設定し、例えば125という閾値を設定することができます。これは、昨日よりもポッドが25%増加した場合に、アラートを受け取ることを意味します。
100 * avg_over_time(sum by (namespace) (kube_pod_info)[1h:1h]) / avg_over_time(sum by (namespace) (kube_pod_info)[1h:1h] offset 5m) > 125
同様のことを、ネームスペースごとのCPU使用量についても行うことができます。クエリーは次のようになります。
100 * avg_over_time(sum by (namespace)(rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[5m]))[1h:1h]) / avg_over_time(sum by (namespace)(rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[5m]))[1h:1h] offset 1d)
監視対象クラスターの2つのネームスペースで、CPUが200%と300%増加している様子
同様に、ネームスペースごとのCPUが、昨日の同じ時間帯に使用されたCPUよりも50%増加したことを検知するアラートを設定することができます。
100 * avg_over_time(sum by (namespace)(rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[5m]))[1h:1h]) / avg_over_time(sum by (namespace)(rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[5m]))[1h:1h] offset 1d)
暗号通貨の価値が大きく下がっていますが、いまだにインフラは攻撃者にとって無料で獲得できるお金のネタです。機械学習のワークロードを実行するのに十分な性能を持つクラスターであれば、なおさらです。
管理ツールを非公開にしたり、強力な認証メカニズムを使用したりするなど、セキュリティのベストプラクティスを実践することで、こうした攻撃を軽減することができます。
幸いなことに、これらの攻撃は簡単に検出できます。Falcoのようなセキュリティツールは、クリプトマイニングプロセスやマイニングプールへの接続を検出することができますし、モニタリングソリューションを使えば、リソース使用量の増加を検出することができます。
Falcoの詳細を知りたい方は:
Sysdig Secureは、他のオープンソースプロジェクトとともに、アウトオブボックスのルールでFalcoを拡張し、Kubernetesのセキュリティとの連携と管理をさらに容易にします。30日間の無料トライアルに登録して、ご自身の目で確かめてください。