fbpx

脅威:コンテナへの攻撃に使われる高度な持続的標的型攻撃技術 #aqua #コンテナ #セキュリティ

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本ブログは「Aqua Security」社の技術ブログで2021年8月26日に公開された「 Advanced Persistent Threat Techniques Used in Container Attacks 」の日本語翻訳です。

コンテナへの攻撃に使われる高度な持続的標的型攻撃技術


Aqua のセキュリティ研究チームである Team Nautilus は、クラウド環境を標的とした集中的なキャンペーンを検知しました。このキャンペーンでは、通常は国家レベルの脅威で利用される手法である、 APT(Advanced Persistent Threat = 持続的標的型攻撃)の手法が用いられています。このキャンペーンの一環として、攻撃者は2種類のルートキットを使用して自分たちの存在を隠し、被害者のシステムに対する持続的アクセスを可能にしていました。このブログでは、これらの高度な技術を詳しく分析し、ルートキットがどのように機能するか、そして攻撃者がクラウドネイティブ環境を攻撃するためにルートキットをどのように利用しているかについて説明します。

ルートキットの紹介

国家が支援する攻撃者は、目的を達成するために最先端のマルウェアや APT 技術を開発して使用することが知られています。例えば、ロシアの諜報機関(GRU)が Linux システムを標的として開発したマルウェア「Drovorub」は、ルートキット「Drovorub-kernel module」を使用して、自分自身やその他のファイル、ディレクトリ、ネットワークコンポーネントを隠します。また、「TunnelSnake」キャンペーンにおいて、中国語を話す攻撃者が組織のネットワークを密かにコントロールするために採用したルートキット「Moriya」もその一例です。

では、ルートキットとは何でしょうか。また、何に使われるのでしょうか。

ルートキットとは、「root」と「kit」を合成した言葉で、その存在を隠しながら、システムへの継続的な特権的アクセスを提供するプログラムのことを指します。一般的に、ルートキットには大きく分けて「ユーザ空間ルートキット」と「カーネル空間ルートキット」の2種類があります。前者はユーザ空間で動作し、バイナリからライブラリへの呼び出しを傍受・変更します。後者は最も広範なユーザ特権を提供し、システムの全プロセスを制御できるため、より危険です。

クラウドネイティブ環境では、攻撃者は通常ホスト上でルートキットを実行して悪意のあるプロセスを隠し、コンテナ化された環境から抜け出した後に発見される可能性を低くします。また、ルートキットは、ユーザ空間の関数(LD_PRELOAD の使用など)やバイナリを上書きするためにも使用されます。

パブリックに横行しているルートキット

TeamTNT が最近行った、数十台のホストを対象としたキャンペーンでは、通常 APT が利用する高度な技術が使われています。このキャンペーンは、クラウドネイティブ環境を対象としており、特に悪意のあるコンテナを実行しています。攻撃量は日ごとに増加していて、感染したホストには数百件の攻撃、全体平均では1日20件の攻撃があり、1日平均 20 回の攻撃が行われ、キャンペーンは現在も継続中です。

1日の攻撃量(2021年5月~2021年8月)

系列1-攻撃の量、系列2-1日あたりの新規感染ホスト数

それぞれの攻撃において、次のようなステップが見られます。

  1. バニラコンテナイメージを使用していること:攻撃者は Alpine コンテナイメージを実行します。
  2. ホストへのエスケープ:攻撃者は、コンテナからエスケープするためにホストのファイルシステムをマウントし、ホストへのアクセスを行います。
  3. 悪意のあるスクリプトをダウンロード:ホストに脱出した後、リモートソースから悪意のあるシェルスクリプト(cronb.sh)をダウンロードして実行するためのコマンドをcronスケジューラシステムに書き込みます。
  4. マルウェアのロードと実行:cronb.sh というスクリプトがペイロードとなり、攻撃を実行します。

このスクリプトでは、自分たちの存在を隠すために、カーネル空間のルートキットである Diamorphine と、ユーザ空間のルートキットとされるバイナリを変更する手法の 2 種類のルートキットを使用しています。

このキャンペーンでは、攻撃者は対象となるクラウド環境への初期アクセスを獲得し、ホストに対する持続性を高めることを目的としています。この種の攻撃で分かりやすいものは、クリプトマイナーを実行することでリソースをハイジャックすることです。しかし、これではホストの CPU 使用率が上がり、セキュリティ監視ソリューションに捕捉される可能性が高くなります。ですが、ルートキットを使用することで、攻撃者は CPU の使用率の高さを隠すことができ、検知される可能性を低くできます。

攻撃フローの分析

攻撃がどのように行われているのか、詳しく見ていきます。

プランA:カーネル空間のルートキット「Diamorphine」を読み込む

攻撃の際には、cronb.sh スクリプトが installdia() と securethesystem() という 2 つの関数を実行します。下図では、installdia に base64 で暗号化された tar ファイルが含まれており、これが Diamorphine ルートキットのソースコードとなっています。また、攻撃者は、できるだけ多くの Linux ディストリビューション(Ubuntu、Debian、Red Hat、Fedora、CentOS など)を網羅しようと、システムのテストを行っています。

Diamorphine は、Linux カーネル用の LKM(loadable kernel module)ルートキットです。カーネル空間内に存在し、プロセスの高い権限を取得して悪意ある活動を隠蔽するよう設計されています。LKM ベースのルートキットは非常に強力で、攻撃者はシステム内でほぼすべてのことを行うことができます。例えば、プロセスの動作を変更したり、プロセスを開始前に終了することもできます。しかし、LKM ルートキットは、攻撃者がそれをロードするために、root 権限または CAP_SYS_MODULE capability を必要とするため、使用するのはより困難です。

今回のケースでは、Diamorphine は getdents()、getdents64()、kill()の各システムコールをフックすることで、Linux プロセスの追跡に使用される ps や top などのプログラムで確認できる高い CPU 使用率を隠しています。

cronb.sh というスクリプトの中で、Diamorphine は変数としてエンコードされています。その後、攻撃者はこれをデコードして tar ファイル(dia.tar.gz)を作成し、3つのファイル(diamorphine.c、diamorphine.h、Makefile)を抽出します。これらが Diamorphine のソースコードです。これらのファイルを、元の GitHub リポジトリに掲載されているものと比較したところ、違いは見られず、攻撃者が Diamorphine に何の変更も加えていないことが分かりました。次のステップでは、Diamorphine のコードがコンパイルされ、カーネルオブジェクト「diamorphine.ko」になります。

Diamorphine の準備ができたので、攻撃者がどのようにそれを利用し、Diamorphine のビルドが失敗した場合の代替ルートキットに切り替えるのかを見てみましょう。

cronb.sh スクリプトの 2 番目の関数は securethesystem() です。

最初の行では、攻撃者はユーザが root 権限であることを確認しようとしています。Diamorphine は LKM ルートキットであるため、root ユーザでなければ実行できません。攻撃者が root 権限を持っていると仮定して、「setup_dia」を実行して Diamorphine をロードします。

上のコードからわかるように、攻撃者が設定した特定のパスに「diamorphine.ko」(カーネルオブジェクト、マルウェアを含むロード可能なカーネルモジュール)が存在すれば、insmod diamorphine.ko で Diamorphine がロードされます(insmod はカーネルモジュールを挿入するコマンド)。

プランB(プランA失敗時):ユーザー空間ルートキットのインストール

プランAが失敗した場合、攻撃者は Diamorphine の代わりに、ユーザー空間に存在し、ユーザー行動をカーネルに仲介するユーザ空間ルートキットを導入します。この種のルートキットは、実行ファイルやシステムライブラリを置き換えて、プロセスの動作を変更したり、偽の情報を表示したりするために頻繁に使用されます。

今回のケースでは、攻撃者はこれを使って top、ps、pstree のプログラムを変更しています。例えば、上図では、バイナリ ps の名前を ps.original に置き換えています。次に、攻撃者は同じライブラリに、元の名前(ps)で、ext4 や scan を表示しないという例外を持つ新しいファイルを追加します(ps.original $@ | grep -v "ext4|scan")。こうすることで、エンドユーザが ps を呼び出しても、ext4 関連のプロセスはすべて表示されません。

しかし、なぜ ext4 がそんなに重要なのか、という疑問が残ります。下図は、この点を明らかにしています。

ext4 の下に、攻撃者はコード内の他の悪意のある要素の中に、クリプトマイナー(XMRIG)とその設定を隠していることが判明しました。

ext4 とは、ファイルシステムの名称です。また、脅威の主体は、これを systemd サービスとしてカモフラージュしているため、悪意のないものに見え、ルートキットは関連するすべての悪意のあるアイテムを ext4 の下に容易に隠すことができるのです。

Diamorphineルートキットの分析

Diamorphine のソースコードを深く掘り下げると、その手法の詳細が明らかになります。すでに述べたように、Diamorphine ルートキットはカーネル空間で動作します。ここでは、その目的を達成するために使用される2つのコア技術に焦点を当てます。

システムコールと内部関数のフック

このルートキットは、カーネルを操作する最も一般的な手法の1つを使用しています。具体的には、カーネルが使用する関数をフックすることで、プログラムの流れを変更します。このケースでは、マルウェアは、システムコールのアドレスを保持する syscall テーブルをロードして変更しています。下図では、syscall テーブルをロードする関数を見ることができます。

下図では、コードの中でこの関数が呼び出されている部分を確認できます。

Diamorphine は、syscall テーブルのロードに成功した後、いくつかのシステムコールを操作して、そのアドレスが本来の関数ではなくカスタムされた関数を指すようにします。これらのシステムコールの元のアドレスは脇に保存されます。

下記で Diamorphine は getdents に代わる新しい機能を定義しています。

そして最後に、この2つのアドレスが入れ替わることで、新しいユーザ空間のプロセスがシステムコール(つまり getdents)を呼び出すと、調整された syscall テーブルが新しい関数(つまり hacked_getdents)を指すようになります。今回のケースでは、Diamorphine は getdents、getdents64、kill の 3 つのシステムコールを対象としています。

問題は、なぜ誰もが getdents と getdents64 をフックするのか、ということです。その答えは、TheXcellerator によるこの素晴らしいブログに記載されています。簡単に言うと、プロセスに関する情報を提供するほとんどすべてのユーザ空間のツールは、/proc/ ファイルシステムの内容を読みます。つまり、実行中のプロセスに関する情報を反映する ps や top などのプログラムを呼び出すと、getdents や getdents64 関数を使って特定の疑似ファイルシステム(/proc)を列挙します。このルートキット(基本的にほとんどのルートキット)は、これらの関数をフックして、隠したいプロセスに関連する情報を削除して返される値を変更することで、プロセスを隠します。

Direct kernel object manipulation(DKOM)

Diamorphine は、カーネルのデータ構造を変更することでプログラムの動作を変えるルートキットです。特に、ロードされたすべてのモジュールをリストアップするコマンドである lsmod から自分自身を隠すことができます。Diamorphine が自分自身をロードする際には、カーネル空間内のモジュールのリンクリストを変更するため、隠れたままでいることができるのです。

また、DKOM の手法はユーザの権限を昇格させるための「give root」という関数にも見られます。

まとめ


このブログでは、クラウドネイティブ環境を標的としたキャンペーンの一環として、攻撃者が APT 級の技術を使用したルートキットを、どのように使用したのかを分析しました。攻撃者は、攻撃を隠すためにカーネル空間のルートキット「Diamorphine」を使用し、Diamorphine マルウェアの実行がうまくいかない場合の予備としてユーザ空間のルートキットを使用しました。

このような攻撃の被害に遭うリスクを軽減するために、取るべき対策を以下に示します。

Linuxアップデートの適用

システム管理者はソフトウェアの進化や最新のセキュリティ検出・緩和のセーフガードを活用するために、コンピュータシステムのベンダーが提供するソフトウェアの最新バージョンを継続的にチェックし実行する必要があります。これは、NSA と FBI の共同報告書「Russian GRU 85th GTsSS Deploys Previously Undisclosed Drovorub Malware」で推奨されています。システム管理者は、カーネル署名を最大限に活用するため、Linux Kernel 3.7 以降にアップデートしてください。

信頼されないカーネルモジュールの防止

システム所有者は、有効なデジタル署名を持つモジュールのみをロードするようにシステムを設定することをお勧めします。これにより、攻撃者が悪意のあるカーネルモジュールをシステムに導入することがより困難になります。攻撃者は悪意のあるカーネルモジュールを使用して、システムを制御したり、隠したり、再起動後も攻撃の持続が可能です(National Security Agency報告)。

Tracee を使用してカーネルの操作を検出

Tracee は、Linux 用のオープンソースのランタイムセキュリティおよび監査ツールで、Linux の一般的なセキュリティ問題を対処するために構築されています。Tracee 0.5.0 以降では、運用担当者やセキュリティ研究者が Tracee eBPF データ収集ツールの上に Rego シグネチャを書くことができます。また、Aqua は「Attempt to load a kernel module detection」などの基本的なシグネチャを追加しており、これにより実務者は不審なカーネルドライバーのロードを検出できます。Tracee を使用してどのように特権昇格を検出できるかについてのより詳細な分析については、「Team NautilusあtBlackHat 2021」の講演をご覧ください。

同様の機能は、Aqua 社のエンタープライズ向けソリューションである Aqua Dynamic Threat Analysis(DTA)にもあります。このソリューションは、サンドボックス環境内でコンテナの動作を動的に分析し、静的なイメージスキャンでは検出されない攻撃ベクターを特定します。

Aqua Enforcerによるユーザ空間ルートキットの検出

ファイル整合性監視(FIM)とは、現在のファイルの状態と既知の良好なベースラインとの間の検証方法を用いて、OS やアプリケーションのファイルの整合性を検証するプロセスです。前述のルートキットの1つには、いくつかのバイナリの名前を変更し、これらのバイナリの名前を持つ新しいファイルを挿入する手法が含まれていました。Aqua の FIM 機能を使用することで、組織はこのようなファイルの変更を検出し、環境内のこのような活動に対処できます。

New call-to-action

新規CTA