This post is also available in: English (英語)
概要
2019年9月から12月にかけ、Unit 42のリサーチャーは、(主に不注意なユーザーエラーにより)インターネットに公開されたDockerホストから、メタデータを定期的にスキャンして収集しました。この結果、攻撃者がDockerエンジンを侵害するさいに利用する戦術とテクニックの一部が明らかになりました。合計では、1,400台のセキュアでないDockerホスト、8,673個のアクティブなコンテナ、および17,927個のDockerイメージが本調査で発見されました。Unit 42チームからこうしたオペレーションに関する警告を受けたDockerチームは、弊チームと連携して悪意のあるイメージの削除を迅速に行いました。
コンテナテクノロジはここ数年非常に人気が高く、現代のアプリケーションのパッケージ化、配信、デプロイのデファクトスタンダード的方法となりつつあります。そして急速に進化、採用の進むコンテナテクノロジは、攻撃者にとっても格好の標的となってきています。
これら悪意のある活動の大部分はクリプトジャッキング(主にMoneroのマイニング)に関連していましたが、侵害されたDockerエンジンのなかには、他の攻撃を開始したり、ホストにルートキットをインストールするために使用されているものもありました。またインターネットに公開されているログからは、アプリケーションの資格情報やインフラ構成などの機密情報も見つかりました。そこでよく見られた興味深い戦術のひとつに、攻撃者がホストファイルシステム全体をコンテナにマウントし、コンテナからホストオペレーティングシステム(OS)にアクセスして、そこから読み取り/書き込みを行う、というものがありました。
そこで私たちは、観測した悪意のある活動を以下の4カテゴリに分類し、各カテゴリの概要と実際のサンプルを本稿で提供することにしました。
- 悪意のあるコードでコンテナイメージをデプロイする
悪意のあるイメージはまず公開レジストリにプッシュされます。その後、イメージがプルされ、セキュアでないDockerホストにデプロイされます。 - 悪意のないコンテナイメージをデプロイし、実行時に悪意のあるペイロードをダウンロードする
まず悪意のないイメージがDockerホストにデプロイされ、その後、悪意のあるペイロードがダウンロードされて悪意のないコンテナ内で実行されます。 - ホストに悪意のあるペイロードを展開する
攻撃者は、ホストファイルシステム全体をコンテナにマウントし、コンテナからホストファイルシステムにアクセスします。 - Dockerログから機密情報を取得する
攻撃者はDockerログをスクレイピングして資格情報や構成などの機密情報を見つけます。
図1 Unit 42 が観測した悪意のある活動の4つのカテゴリ
Dockerデーモン
Dockerデーモンはバックグラウンド常駐プロセスで、1台のホスト上のコンテナを管理しています。これはイメージ、コンテナ、ネットワーク、ストレージなど、Dockerオブジェクトを独立的に管理しているランタイムで、REST API リクエストをリッスンし、リクエストに応じてコンテナ関連の一連の操作を実行してくれます。通常、アプリケーションやユーザーは、Dockerクライアントを使ってDockerデーモンとの認証や対話を行います。Dockerデーモンは、複数のホストがサービスないしクラスタとして管理されている場合は、他のDockerデーモンとも通信することができます。
デフォルトでは、Dockerデーモンは/var/run/docker.sockにネットワークには接続しないUnixドメインソケットを作成します。またDockerデーモンにアクセスできるのは、root権限またはDockerグループメンバーシップを持つプロセスのみです。クライアントからDockerデーモンにリモートでアクセスする必要がある場合、DockerデーモンはTCPソケットを開き、ポート2375でREST APIリクエストをリッスンすることができます。このときデフォルトのTCPソケットは、暗号化や認証なしでDockerデーモンに対するアクセスを提供します。ただし、TLSを利用して相互認証するように構成してクライアント・リモートデーモン間の通信を保護することもできます。Portainer、Kitematic、RancherなどのDocker管理ツールを使いたければ、通常はユーザーがTCPソケットを有効にしてDockerホストのクラスタをリモート管理可能にしなければなりません。ところが、このTLSの構成は複雑になることが多く、そのさいユーザーが誤ってインターネット全体に認証なしのデーモンを公開してしまうことが生じます。
インターネットに公開されているDockerデーモンを探索する
TLS構成は複雑なので、構成を誤ってインターネット上に公開されているセキュアでないDockerデーモンは多数見つかりました。そのなかには、暗号化や認証を行っていないDockerデーモンも見うけられました。このほか、TLSは構成されていても、クライアント証明書の検証に失敗するDockerデーモンもありました。この場合誰もが、クライアント証明書の検証なしで、暗号化されてはいるが認証は行わないデーモンへの接続を確立できてしまいます。悪意のある攻撃者がこうしたセキュアでないDockerデーモンを見つけた場合、Dockerプラットフォームを完全に制御下に置き、新しいコンテナのデプロイ、アクティブなコンテナへのログイン、コンテナイメージのダウンロードなどを実行できます。Dockerデーモンはホスト上でrootプロセスとして実行されるため、攻撃者がホストを完全に自身の制御下に置いてしまう可能性があります。
これらのセキュアでないDockerホストで攻撃者が悪用する戦術やテクニックを理解するため、私たちは2019年9月から12月にかけ、インターネット上に公開されているDockerデーモンを定期的にスキャンし、メタデータを収集しました。私たちの関心は、侵害ホストにデプロイされた悪意のあるイメージ、コンテナ、プロセスを確認することにありました。IoT検索エンジンであるShodanやCensysで検索すると、約5,000個のDockerデーモンがインターネット上に公開されており、うち10%〜15%のデーモンは、認証なしでアクセスできることがわかりました。標準のDocker Daemon APIを使用し、いくつかの読み取り専用リクエストを行うことで、セキュアでないホストからメタデータを収集しました(表1参照)。
API | 説明 |
GET /info | システム全般の情報を表示 |
GET /containers/json | コンテナを一覧表示 |
GET /images/json | Dockerイメージを一覧表示 |
GET /volumes | マウント/バインドされたボリュームを一覧表示 |
GET /swarm | Swarmの構成を検査 |
GET /events | Dockerからコンテナイベントを取得 |
表1 メタデータ収集に使用したDocker Daemon API
全体では、重複を含めずに1,400台を超えるセキュアでないDockerホスト、8,673個のアクティブなコンテナ、17,927個のDockerイメージ、15,229個のボリュームを特定することができました。図2は、Dockerデーモンの地理的な分布を示したものです。また図3は、DockerのバージョンとOSの種類を示しています。以降では、これら侵害されたDockerホストで観測された悪意のある活動についてまとめます。
図2 インターネット上に公開されているセキュアでないDockerホストの地理的分布 (日本は全体を100%として3.7%)
図3 セキュアでないDockerホストのバージョン(左)とOSの種類(右)
インターネット上に公開されているDockerデーモンでの悪意のある活動
セキュアでないDockerデーモンを発見した攻撃者は、そのDockerプラットフォームを完全に制御下に置き、ホスト全体を侵害してしまいかねません。私たちの調査では、侵害されたプラットフォームの大部分はクリプトジャッキング(主にMoneroのマイニング)に関連していましたが、一部は他の攻撃を開始するための踏み台としても使用されていました。私たちは、攻撃者たちがシステムから互いを排除することで「無料のリソース」を奪い合う様子も観測しています。とりわけ攻撃的な者たちは、ホストをさらに侵害し、マルウェアを直接ホストOSにインストールすることもあります。こうして観測された悪意のある行動は4つのカテゴリに分類されます。これらについて各項で詳しく説明します。
悪意のあるコードでコンテナイメージをデプロイする
Dockerイメージは、アプリケーション実行に必要な依存関係をすべてパッケージ化しています。このおかげで、どんなプラットフォーム、オペレーティングシステム、インフラストラクチャ上であっても、そのアプリケーションの動作は変わりません。同じ方法を使えば、悪意のあるアプリケーションにも高い信頼性をもたせて配信することができます。攻撃者は、パブリックコンテナレジストリのDocker HubやQuayを利用して、悪意のあるコンテナイメージの保存・配信を行います。Docker Hubは、ほとんどのDockerホストが信頼しているデフォルトのレジストリなので、悪意のあるイメージの保存・提供に頻繁に利用されています。この手のマルウェアは、侵害ホスト上に直接コンテナとしてプルされ、実行されます。典型的なケースだと、同じホスト上の他のコンテナやプロセスは侵害せず、CPUやメモリ、ネットワークリソースなどを盗むだけです。この場合、悪意のあるコードはコンテナイメージに組み込まれています。ですから、Prisma Cloudのような構成分析ツールを使えば、通常はイメージがデプロイされる前に悪意のあるファイルを識別することができます。表2に示すように、私たちの調査でもDocker Hub上の悪意のあるコードを含む多数のイメージが見つかりました。なお、これらのイメージは、Docker Hubに報告された後、アクティブでなくなっていますのでその点はご承知おきください。
リポジトリ/イメージ | 悪意のあるコンテンツ | プルされた数 | SHA256値 |
abailey000/debian | xmrig moneroマイナー マイニングプール: mine.c3pool[.]com マイニングアドレス: 4453uAxM3ej4p4DWJBV8v1QpdA9vZB7j1cocTXcbjpoSaxXdBC5SxDrgxU6JmV8ePhL95kwHTtZwcP5zENXNSJwUHN5hFza |
10K | 38d53ce7deed9ce26b2771d489fa3ea742ccabbf8ad62e478701998ab060e6c1 |
challengerd/challengerd | xmrig moneroマイナー マイニングプール: monerohash[.]com マイニングアドレス: 89mvBaUVy4r6A2rNBVdatMBaLP27zPYGyivmDbJFqFPvUxEwVB4v4V52wgnpH6BWvjHkyzZLMJso7YUgsNwY15y9UD6A6az |
10K | 6bd3627b038170cd20b7b2562ff2f6d7bff1e86262f452ab88178fa97cec5e3e |
tanchao2014/mytest | xmrig moneroマイナー マイニングプール: pool.supportxmr[.]com マイニングアドレス: 45TwKEr1LjoEPuxnbfuPhaXCf138AoQvtSJ3jdqg1gPxNjkSNbQpzZrGDaFHGLrVT7AzM7tU9QY8NVdr4H1C3r2d3XN9Cty |
7.4K | 6862548eb601a65389a93b65bd942c8ffd0197dc956c0702c0fa1ca42a798382 |
freetouse3/accumulo | xmrig moneroマイナー
マイニングプール: xmr.f2pool[.]com マイニングアドレス: 43U3d1PBg4Gi2BaeMx7nH2dQsyZhAdMRATkJmbvr3kFuEMvU93f4H5geqjnru7SjLA3q81xCnUWr9PdFJRKDB5131fbC8pE.x |
4K | a999783625563cb9436628dcaa4f6bac3ae4b511618771d1aaabb6ffc3db0e1e |
shaylsholmes/myubuntu | xmrig moneroマイナー IPv4のアドレス空間内でランダムにIPアドレスをチェックし、インターネット上に公開されているDockerホストが存在するかどうかを探す。 マイニングプール: pool.minexmr[.]com マイニングアドレス: 46H5FPmG5x8NCXTTLMWcTzezHR5CqkQeg41XnbfK1Ujh1sw4xx29WmM15rEVaXMrUWN8SutBnGe21XvWg3T69B5ENfuUymp |
250 | 929ff615f6510f4618f5537b63d3499dc1ebc1f6e841bea9f2f28f2c6ec8eeef |
pocosow/centos | ワーム機能を備えたクリプトジェッキングマルウェア。
イメージ自体にクリプトジャッキングのコードは含まれていないが、xmrig moneroマイナーを使用して、別の2つの悪意のあるコンテナをデプロイする。 マイニングアドレス: 45TwKEr1LjoEPuxnbfuPhaXCf138AoQvtSJ3jdqg1gPxNjkSNbQpzZrGDaFHGLrVT7AzM7tU9QY8NVdr4H1C3r2d3XN9Cty 詳しくはUnit 42による Graboidのブログを参照のこと |
6.5K | 6560ddfd4b9af2c87b48ad98d93c56fbf1d7c507763e99b3d25a4d998c3f77cf |
heybb/theimg1 | コンテナはTorネットワーク経由でSlowlorisによるDoS攻撃を開始する。Torネットワーク上のコマンド&コントロール(C2)サーバーから定期的に新しいペイロードとターゲットをプルする | 610 | 7779b83d97bf8a17c24540c5aefba542f9cab6c9b729afe8ab73c78a245948e8 |
表2 悪意のあるコードを含むDockerイメージ
悪意のないコンテナイメージをデプロイし、実行時に悪意のあるペイロードをダウンロードする
コンテナは、それだけで独立して実行できるように設計されていますので、通常はコンテナがいったん起動するとファイルシステムやアクティブなプロセスは変更されません。ただし、ファイルシステムへのアクセスを制限するセキュリティポリシー(AppArmorやSELinuxなど)がなければ、攻撃者は実行時(ランタイム)にコンテナ内に悪意のあるペイロードをインストールして実行することができます。構成分析ツールは、コンテナイメージ内の悪意のあるコードを識別することは得意ですが、実行時にインストールされた悪意のあるペイロードを確認することはできません。そこで攻撃者は、検証済みの公式イメージをDocker Hubからデプロイし、後から悪意のあるプロセスをコンテナに挿入することがあります。そのため、この手の攻撃検出には、Prisma Cloud Computeのように、より高度なコンテナのランタイム保護が必要となります。
図4は、悪意のあるスクリプトがダウンロードされ、公式Ubuntuイメージ内で実行された様子を示しています。図5は、2つの悪意のあるスクリプトがダウンロードされ、公式Alpineイメージ経由でホストファイルシステムで実行された様子を示しています。図6は、base64でエンコードされたスクリプトが公式Busyboxイメージ経由でホストのcrontabに追加された様子を示しています。
図4 悪意のあるコマンドが公式Ubuntuイメージ内で実行されたところ
図5 悪意のあるコマンドが公式Alpineイメージ内で実行されたところ
図6 悪意のあるコマンドが公式Busyboxイメージ内で実行されたところ
ホストに悪意のあるペイロードを展開する
セキュアでないDockerデーモンは、悪意のある攻撃者に対し、すべてのコンテナとイメージへの完全なアクセスを提供してしまいます。ただし、デーモンはホストOSへのアクセスを直接提供するわけではありません。そこでよく見られる攻撃者の手口が、ホストファイルシステム全体をコンテナにマウントし、コンテナからホストOSにアクセスしてしまうというトリックです。ホストファイルシステム全体がマウントされた場合、ホスト上のほぼすべてのファイルをコンテナから読み書きできるようになります。
図7は、攻撃者がホストファイルシステム(/)全体をコンテナファイルシステム(/mnt)にマウントするコンテナを作成した様子を示しています。図8は、攻撃者がどのようにしてコンテナからホストファイルシステムに対して悪意のあるペイロードを実行したかを示しています。 chroot コマンドは、呼び出し側プロセスのルートディレクトリを/mntに変更します。これにより、/mntはホストファイルシステムのルートを指すことになります。つまりいったんchrootしてしまえば、悪意のあるプロセスは実質上ホストファイルシステムで実行されているのと同じことになります。
図9から図11は、観測するなかで見つかった、マウントされたファイルシステムを使いホストを侵害するさまざまな手法を示したものです。図9の攻撃者は、コンテナ内のホストマウントポイント(/mnt)に悪意のあるペイロードを送信することによってホスト上に悪意のあるcronジョブを作成しています。図10の攻撃者は、ホスト上のrootのホームディレクトリに新しい公開鍵を追加しています。この公開鍵を使うと、ホストOSに直接ssh接続できるようになります。図11では、マウントポイントを介して悪意のあるコードがダウンロードされ、ホストのブートプロシージャディレクトリrc3.dにドロップされています。
図7 ホストファイルシステムのルートがコンテナにマウントされている
図8 コンテナ内でコマンドを実行
図9 コンテナ内でコマンドを実行
図10 コンテナ内でコマンドを実行
図11 コンテナ内でコマンドを実行
Dockerログから機密情報を取得する
コンテナが生成されてから終了されるまでの間、Dockerデーモンはデフォルトではすべてのコンテナのイベントとログを保持しています。ログはデバッグや監査に不可欠なものですが、構成や資格情報などの機密情報もこのログから漏洩する可能性があります。
図12および図13では、コマンドログからアプリケーションのパスワードが明らかになりました。図14では、etcdサーバーのIPアドレスとキーファイルの場所がコマンドログから明らかになっています。こうした資格情報を使うことで横展開がしやすくなり、侵害に一層拍車がかかるおそれがあります。
図12 containerコマンドからリークされたredisの資格情報
図13 containerコマンドからリークされたportainerの資格情報
図14 containerコマンドからリークされたキーファイル
今回の調査では、ある一連のwebサイトが悪意のあるペイロードの配信や侵害ホストからの窃取データ受信に頻繁に利用されていることも確認できました。これらwebサイトのドメインのほとんどは、ユーザーが匿名でファイルをアップロード・ダウンロードできます。表3に、繰り返し観測されたwebサイト9つを示します。
webサイト | webサイトに関する情報 |
bigbotpein[.]cf | ユーザーは匿名でファイルをアップロード・ダウンロードできる |
mediafire[.]com | ユーザーは匿名でファイルをアップロード・ダウンロードできる |
transfer[.]sh | ユーザーは匿名でファイルをアップロード・ダウンロードできる |
ix[.]io | ユーザーはREST APIを使用してプレーンテキストファイルをペースト、表示、削除できる |
gyazo[.]nl | ユーザーは画像や動画をアップロードし、ダウンロードリンクを受け取れる |
onion[.]ly | ユーザーが通常のwebブラウザ経由でTorサービスにアクセスできるようにするTor webプロキシ |
onion[.]ws | ユーザーが通常のwebブラウザ経由でTorサービスにアクセスできるようにするTor webプロキシ |
tor2web[.]su | ユーザーが通常のwebブラウザ経由でTorサービスにアクセスできるようにするTor webプロキシ |
ngrok[.]io | ローカルwebサーバーをインターネットに公開するサービスで、C2をサービスの背後に隠すことができる |
表3 頻繁にC2として使用されているwebサイト
結論
今回の調査は、攻撃者がコンテナプラットフォームを侵害するさいに使う戦術とテクニックについて、初めて実地レベルの概要を提供するものです。本稿では、コンテナプラットフォームでの悪意のある活動についてだけでなく、これらの活動を検出・防止するために必要な対策がどのようなものかについても学習しました。ほとんどの脆弱性は、セキュアでないDockerデーモンを誤ってインターネットに公開することによって引き起こされています。そこで、こうしたミスを軽減する防御戦略として、以下をあげることができるでしょう。
- DockerデーモンソケットでTLSを構成する場合は、常に相互認証の実施を強制する
- Unixソケット を使ってDockerデーモンとローカル上で通信するか、SSH 経由でリモートDockerデーモンに接続する
- DockerサーバーにアクセスできるIPアドレスは、ホワイトリストに登録されたクライアントのIPアドレスに限定する
- Docker Content Trust を有効にし、署名・検証済みのイメージのみをプルする
- すべてのコンテナイメージをスキャンし、脆弱性と悪意のあるコードを探す
- ランタイム保護ツールをデプロイし、実行中のコンテナを監視する
パロアルトネットワークスのお客様は、次の方法でこの脅威から保護されています。
- Prisma Cloud 脆弱性スキャナは脆弱性のあるコードや悪意のあるコードをビルド時に検出してブロックします。
- Prisma Cloud Compute はコンテナやホストをランタイムに常時監視します。