1. クラウドネイティブセキュリティとは#
クラウドコンピューティング -> クラウドネイティブ -> クラウドネイティブセキュリティ
クラウドネイティブセキュリティを理解する前に、まずクラウドコンピューティングとクラウドネイティブについて理解する必要があります。
クラウドコンピューティング:
クラウドコンピューティングが登場する前は、ソフトウェアのユーザー数やデータ量が少なく、直接会社のデータセンターに配置することができました。しかし、現在のビッグデータ環境では、従来のソフトウェアアーキテクチャは適切ではありません。ソフトウェアの再構築やデータの移行は困難です。そのため、クラウドコンピューティングが生まれました。
クラウドコンピューティングでは、ユーザーは必要に応じてリソースを取得できます。
クラウドネイティブ:
クラウドネイティブには明確な定義はありません。クラウドネイティブは常に進化しており、説明権は特定の個人や組織に帰属していません。
クラウドネイティブ(CloudNative)は、アプリケーションを構築および実行するための方法であり、技術スタックと方法論のセットです。
クラウドネイティブアーキテクチャに準拠したアプリケーションは、オープンソーススタック(K8S+Docker)を使用してコンテナ化され、マイクロサービスアーキテクチャを採用して柔軟性と保守性を向上させ、アジャイルな方法と DevOps を活用して継続的なイテレーションと自動化された運用をサポートし、クラウドプラットフォームのインフラストラクチャを活用して弾力性のあるスケーリング、ダイナミックなスケジューリング、リソースの最適化を実現します。
クラウドネイティブの 4 つの要素:
- マイクロサービス
- コンテナ化
- DevOps
- 継続的デリバリー
クラウドネイティブを簡単に理解すると、クラウド上でのソフトウェアアプリケーションの展開における一種の技術アーキテクチャです。
クラウドネイティブセキュリティ:
クラウドネイティブには、従来のセキュリティの問題(DDoS 攻撃、Web 侵入など)がまだ存在します。
さらに、クラウドネイティブには以下の問題があります:
- API セキュリティ
- コンテナセキュリティ
- 中央管理の不足
- トラブルシューティングの困難さ
2. コンテナセキュリティとは#
クラウドネイティブエコシステムでは、さまざまな種類のコンテナが存在します。ここでは Docker を例に分析します。
2.1 Docker のセキュリティの脆弱性#
- CVE 公式レコードによると、Docker の過去のバージョンには 20 以上の脆弱性が存在します。これには、コードの実行、権限の昇格、情報の漏洩などが含まれます。
- Docker のソースコードのセキュリティ
- Docker Hub のセキュリティ
2.2 Docker のアーキテクチャの欠陥#
- コンテナ間のローカルネットワーク攻撃
- リソースの枯渇による DDoS 攻撃
- 脆弱なシステムコール
- 共有された root ユーザー権限
3. コンテナセキュリティ#
3.1 コンテナ化された開発テストプロセスへの攻撃に対する対策#
背景
- docker cp コマンド
docker cp コマンドは、Docker で作成されたコンテナとホストファイルシステム間でファイルやディレクトリをコピーするために使用されます。
- シンボリックリンク
シンボリックリンク(ショートカット)は、Windows のショートカットに似ています。
CVE-2018-15664 - シンボリックリンクの置換の脆弱性
影響を受けるバージョン:Docker 17.06.0-ce~17.12.1-ce:rc2
,18.01.0-ce~18.06.1-ce:rc2
脆弱性の原理:CVE-2018-15664 は、実際には TOCTOU(time-of-check to time-of-use)の問題であり、競合状態の脆弱性です。
簡単に言えば、プログラムが特定のオブジェクトに対してセキュリティチェック(たとえば、ユーザーが docker cp コマンドを実行した後、Docker デーモンは指定されたコピー先パスをチェックします)とそのオブジェクトを使用するステップの間にギャップがあるため、攻撃者はセキュリティチェックをパスするオブジェクトを作成し、すぐに正当なオブジェクトを悪意のあるオブジェクトで置き換えることができます。その結果、ターゲットプログラムは置換後の悪意のあるオブジェクトを実際に使用します(docker cp コマンドを使用する際にシンボリックリンクを置換すると、ディレクトリトラバーサルが発生する可能性があります)。
脆弱性の再現:metargetを使用して、CVE-2018-15664 環境を迅速に構築します。
CVE-2019-14271 - 信頼されていないダイナミックリンクライブラリのロード
影響を受けるバージョン:Docker 19.03.x before 19.03.1
脆弱性の原理:docker cp コマンドは、docker-tar コンポーネントに依存してコンテナ内部の nsswitch ダイナミックリンクライブラリをロードします。攻撃者は、コンテナ内部の nsswitch をハイジャックしてコードインジェクションを実現し、ホスト上の root 権限でコードを実行する能力を取得することができます。
脆弱性の利用手順は以下の通りです:
- docker-tar がコンテナ内のどのダイナミックリンクライブラリをロードするかを特定します。
- 対応するダイナミックリンクライブラリのソースコードをダウンロードし、
__attribute
__属性の関数 run_at_link を追加します(この関数はダイナミックリンクライブラリがロードされるときに最初に実行されます)。 - docker cp が脆弱性をトリガーするのを待ちます。
3.2 コンテナソフトウェアサプライチェーンへの攻撃#
コンテナ技術の普及に伴い、コンテナイメージはソフトウェアサプライチェーンの非常に重要な部分となりました。パブリックリポジトリからイメージを取得したり、プライベートリポジトリからイメージを取得したりすることができます。
パブリックリポジトリからイメージを取得する場合、次の 2 つの脆弱性の問題があります:
- イメージ内のソフトウェアのセキュリティの脆弱性
- イメージ内のマイニングプログラム、バックドアプログラム、ウイルスなどのマルウェア
イメージの脆弱性の利用
イメージの脆弱性の利用は、イメージにローカルの脆弱性が存在する場合、通常、イメージを作成して実行するコンテナにも同じ脆弱性が存在することを意味します。
例えば、Alpine は、musl libc と busybox に基づいた軽量な Linux ディストリビューションです。そのサイズの小ささから、Alpine をベースにしたイメージを構築することは非常に一般的です。しかし、Alpine イメージには CVE-2019-5021 という脆弱性がありました。Alpine 3.3〜3.9 のバージョンでは、root ユーザーのパスワードが空に設定されており、攻撃者はコンテナに侵入した後、コンテナ内の root 権限に昇格することができます。
イメージの汚染
イメージの汚染は、攻撃者が公開リポジトリに悪意のあるイメージをアップロードしたり、システムを侵害して被害者のローカルリポジトリにイメージをアップロードしたり、イメージの名前を変更して正規のイメージを偽装したりするなど、攻撃者が指定した悪意のあるイメージを使用してコンテナを作成および実行することで、侵入や被害者のホストを悪用する行為を指します。
目的に応じて、一般的なイメージの汚染には次の 3 つのタイプがあります:
- 悪意のあるマイニングイメージの投入
- 悪意のあるバックドアイメージの投入
- 悪意のあるエクスプロイトイメージの投入
3.3 コンテナランタイムへの攻撃#
不安全な設定によるコンテナの脱出
これらの年月の間、コンテナコミュニティは、深層防御、最小特権などの原則を実現するための努力を続けてきました。
Docker は、コンテナランタイムの Capabilities ブラックリストメカニズムをデフォルトですべての Capabilities を禁止するモードに変更し、コンテナの実行に必要な最小限の Capabilities のみをホワイトリスト方式で付与するようにしました。Docker はデフォルトでコンテナに 14 の Capabilities を付与します。
func DefaultCapabilities() []string {
return []string{
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE",
}
}
細粒度の権限制御やその他のセキュリティメカニズムに関しては、ユーザーはコンテナ環境の設定を変更したり、コンテナの実行時にパラメータを指定したりすることで制約を縮小または拡大することができます。制御されていないコンテナに危険な設定パラメータを提供すると、攻撃者に一定の脱出の可能性を提供することになります。
危険なマウントによるコンテナの脱出
仮想化ソリューションは、ホストマシンと仮想マシン間でデータの交換を容易にするために、ホストマシンのディレクトリを仮想マシンにマウントする機能を提供しています。コンテナも同様です。ただし、ホストマシン上の機密ファイルやディレクトリをコンテナ内部にマウントすると、制御されていないコンテナにより重大な問題が発生します。
3.4 プログラムの脆弱性によるコンテナの脱出#
CVE-2019-5736
影響を受けるバージョン:Docker version <= 18.09.2
& RunC version <= 1.0-rc6
脆弱性の原理:CVE-2019-5736 は、コンテナからホストマシンの runc プログラムを上書きすることができるコンテナの脱出脆弱性です。たとえば、docker exec
などのコマンドを実行する際に、実際にはコンテナランタイムが操作を実行しています。たとえば、runc exec
コマンドが実行されます。これにより、コンテナ内部でユーザーが指定したプログラムを実行することができます。さらに言えば、これは各種の名前空間内で、さまざまな制約(Cgroups など)の下でプロセスを起動することです。したがって、これはホストマシン上でプログラムを実行するのと同じです。
攻撃手順:
- コンテナ内の
/bin/sh
プログラムを#!/proc/self/exe
に上書きします。 - コンテナ内の
/proc
ディレクトリを繰り返しスキャンし、各/proc/[PID]/cmdline
を読み取り、runc を文字列マッチングします。runc プロセス ID が見つかるまで続けます。 - 読み取り専用で
/proc/[runc-PID]/exe
を開き、ファイルディスクリプタを取得します。 - 取得した読み取り専用のファイルディスクリプタ(
/proc/self/fd/[fd]
)を書き込みモードで開くために繰り返し試行します。最初は常に失敗しますが、runc が使用を終了して書き込みモードで開くことができるとすぐに成功します。その後、このファイルディスクリプタを使用してホストマシン上の/usr/bin/runc
(または/usr/bin/docker/runc
)に攻撃ペイロードを書き込みます。 - runc は最後に、
docker exec
で指定された/bin/sh
を実行しますが、最初のステップで#/proc/self/exe
に置き換えられているため、実際にはホストマシン上の runc が実行されます。また、4 番目のステップで runc も上書きされています。
3.5 カーネルの脆弱性によるコンテナの脱出#
オペレーティングシステムのレベルでは、コンテナプロセスはさまざまなセキュリティメカニズムによって制約されたプロセスの一種です。したがって、攻撃と防御の両方において、コンテナの脱出は従来の特権昇格フローに従います。攻撃者はこの特性を利用してコンテナの脱出のアイデアを拡張することができます。新しいカーネルの脆弱性が発生した場合、それがコンテナの脱出に使用できるかどうかを検討することができます。一方、防御側はこの特性に基づいて保護と検出を行うことができます。たとえば、ホストカーネルのパッチを適用したり、そのカーネルの脆弱性の利用にどのような特徴があるかを調査したりすることができます。
CVE-2016-5195
影響を受けるバージョン:Linux カーネル >= 2.6.22(2007 年リリース、2016 年 10 月 18 日に修正)
脆弱性の原理:Linux カーネルのメモリサブシステムには、書き込み時コピー(Copy-on-Write)の処理中に競合状態の脆弱性が存在し、プライベート読み取り専用メモリマッピングを破壊することができます。
この脆弱性を利用するために、PoCを使用します。この利用の核心的なアイデアは、vDSO にシェルコードを書き込み、通常の関数呼び出しプロセスを乗っ取ることです。
4. 参考文献#
- 《クラウドネイティブセキュリティ - 攻撃と防御の実践と体系構築》
- https://github.com/Metarget/cloud-native-security-book
- https://www.cnblogs.com/buchiyexiao/p/14702051.html