Linux システムを狙う Reptile マルウェア

Reptile は Github にオープンソースとして公開されている Linux システムを対象とするカーネルモジュールのルートキットである。[1](英語外部サイト) ルートキットは自身や他のマルウェアを隠蔽する機能を持つマルウェアであり、主にファイルおよびプロセス、ネットワーク通信がその隠蔽対象である。Reptile がサポートする隠蔽機能には、カーネルモジュール自身以外にもファイルおよびディレクトリ、ファイルの内容、プロセス、ネットワークトラフィックがある。

一般的に隠蔽機能のみを提供する他のルートキットマルウェアとは異なり、Reptile はリバースシェルを同時に提供し、攻撃者が容易にシステムを制御できるようにサポートする。Reptile がサポートする機能のうち、最も特徴的なものは Port Knocking 手法である。Port Knocking は感染システムにおいて特定のポートをオープンして待機し、攻撃者がそのシステムに Magic Packet を送信するときに渡されたパケットをベースに C&C サーバーに接続する方式である。

このような方式は、過去 Avast のレポートで取り上げられた Syslogk と類似している。[2](英語外部サイト) もちろん Syslogk が別のオープンソース Linux カーネルモジュールのルートキットである Adore-Ng をベースに制作されたという点は違いであるといえる。しかし、感染システムで待機しておき Magic Packet をトリガーとして動作する方式や、攻撃に同時使用するバックドアマルウェア Rekoobe、すなわちカスタマイズされた TinySHell を使用した点は、Reptile がサポートする方式と類似している。

オープンソースの Reptile は Github に公開されて以降、攻撃に使用され続けている。例えば、最近 Mandiant のレポートでもフォーティネット製品のゼロデイを利用して攻撃中の、中国を拠点とする攻撃グループが攻撃に Reptile を同時に使用した事例が確認されている。[3] この他にも Mélofée マルウェアを解析した ExaTrack のレポートでも Reptile ルートキットを確認することができ、ExaTrack はこれを中国を拠点とする Winnti 攻撃グループの仕業であると見ている。[4](英語外部サイト)

この記事では、Reptile の基本的な構造と機能を簡単に解析したあと、韓国国内の企業を対象とする実際の攻撃に使用された事例を整理する。韓国国内の攻撃事例では ICMP Shell が同時に攻撃に使用されたことが特徴である。最後にはインストール先、すなわちマルウェアの偽装したパス名をベースに Mélofée マルウェアの事例との類似性を整理する。

1. Reptile の解析

1.1. Reptile の構造

Figure 1. Reptile の動作構造
1.1.1. 攻撃者のシステム

Reptile は感染システムにインストールされるマルウェアだけでなく、攻撃者が使用するツールもサポートしている。Listener は引数として Listen するポートとパスワードを受け取って動作するコマンドラインツールであり、感染システムで実行されるリバースシェルからの接続を待機する。Reptile はオプションによってインストール後に直接指定したアドレスでリバースシェルを動作させることができる。この場合、C&C サーバーで動作する Listener がこの接続を受け、攻撃者にシェルを提供する。

攻撃者の C&C サーバーを別途指定しなくても Port Knocking 方式を利用して感染システムに特定のパケットを渡すことでリバースシェルを動作させることができる。この時に使用されるのが Packet であり、リバースシェルが接続を試みるアドレス、Port Knocking 方式で使用するプロトコル等の引数を受けて動作するコマンドラインツールである。Listener と Packet を直接使用することもできるが、インターフェースを提供する Client を利用することもできる。

1.1.2. 被害システム

インストールするパス名を別途指定しなかった場合、マルウェアは基本的に /reptile/ ディレクトリ内の reptile、reptile_shell、reptile_cmd の名前でインストールされる。Reptile ルートキットをインストールする Loader である reptile は、暗号化された形式でファイル内部に存在する Reptile ルートキットのカーネルモジュールを復号化、およびロードする機能を担う。すなわち、Reptile ルートキットはダイレクトにカーネルモジュール形式のファイルで存在せず、Loader により復号化のプロセスを経てインストールされる。

Figure 2. インストールディレクトリ

Reptile ルートキットにコマンドを伝達する機能を担う reptile_cmd は、引数で隠蔽対象を指定してから実行する方式によりルートキットと通信する。リバースシェルマルウェア reptile_shell はコマンドラインの引数を受け取ることができ、Reptile ルートキットにより実行される。

インストール過程で直接 C&C サーバーに接続を試みるようオプションを指定する場合、/reptile/reptile_start スクリプトファイルにコマンドが指定される。Reptile ルートキットはカーネルモジュールのロード後、そのスクリプトファイルを実行させる方式でリバースシェルが動作する。または Port Knocking 手法によってアドレスを受け取る場合も、リバースシェルを実行して復号化された C&C サーバーアドレスを伝達することもある。

1.2. Reptile ルートキットの解析

/reptile/ ディレクトリに生成される reptile はカーネルモジュールではなくユーザーモードのアプリケーションである。ローダーは、実行されるとデータセクションに含まれていた暗号化されたカーネルモジュール Reptile を復号化したあと init_module() 関数を利用してメモリ上にロードする。暗号化/復号化に使われるアルゴリズムは以後 Magic Packet の復号化にも使われ、 キー値はビルド時にランダムな値を利用して作成するため、生成されたファイルごとに異なる値を持つ。

Figure 3. Reptile で使用される暗号化関数

ロードされた Reptile は kmatryoshka という別のオープンソースを利用してパックされたカーネルモジュールである。[5](英語外部サイト) kmatryoshka は Linux カーネルモジュールベースのパッカーであり、暗号化された形式で存在するオリジナルのカーネルモジュールを復号化したあと sys_init_module() 関数を利用してロードする機能を担う。すなわち、オリジナルの Reptile ルートキットはユーザーモードおよびカーネルモードでそれぞれパックされた形式で存在する。

Figure 4.Kmatryoshka のルーティン
1.2.1. 隠蔽機能の解析

Reptile はカーネル関数に対するフックのために KHOOK という Linux カーネル関数フックエンジンを使用する。[6](英語外部サイト) 例えば Port Knocking 方式を使用するために ip_rcv() カーネル関数をフックして、これによって渡されたパケットをモニタリングできる。

そして、ルートキットにコマンドを伝達するときは reptile_cmd を使用するが、reptile_cmd は Reptile カーネルモジュールに ioctl を伝達する。さらに、このような ioctl をモニタリングするために inet_ioctl() カーネル関数をフックする。Ioctl で伝達するデータのうち cmd はコマンド番号を意味し、プロセス隠蔽コマンドのように PID のような追加データを伝達しなければならない場合は control 構造体の argv 変数を利用して伝達する。コマンドの伝達プロセスで使用する AUTH、HTUA はランダムな値であり、Reptile は ioctl をモニタリングし、マッチすると対応するコマンドを実行する。

Figure 5. ioctl の伝達
番号 コマンド 説明
0 hide / show ファイルおよび自己の隠蔽/解除
1 hide / show プロセスの隠蔽/解除
2 file-tampering ファイル内容の隠蔽
3 root root 権限の付与
4 conn hide ネットワーク通信の隠蔽
5 conn show ネットワーク通信の隠蔽/解除
Table 1. cmd コマンド

Reptile は隠蔽機能と Port Knocking 機能のほか「root」コマンドを利用して現在のユーザーに root 権限を付与する権限昇格機能をサポートしている。また Udev を利用した持続性維持の手法もサポートしているが、/lib/udev/rules.d/ ディレクトリに以下のような Rule ファイルを生成してコピーしたパスを指定し、再起動後も実行できるようにする。

Figure 6. 生成された udev の rules ファイル

A. ファイルおよびディレクトリの隠蔽
Reptile ルートキットは「hide」および「show」コマンドにより、ファイルおよびディレクトリを隠蔽または隠蔽解除することができる。隠蔽対象は、ビルド時に指定した文字列を含むパスである。このために fillonedir()、filldir()、filldir64() のような複数のカーネル関数をフックし、パス名に隠蔽対象の文字列が含まれている場合はフック関数から「ENOENT」、すなわち「no such file or directory」エラーを返す。

Figure 7. ファイルおよびディレクトリの隠蔽

B. 自己の隠蔽
「hide」、「show」コマンドの場合、ファイルおよびディレクトリ以外にも Reptile カーネルモジュール自体を隠蔽する機能もサポートしている。「hide」コマンドを受け取るとモジュールリストから現在のモジュールを削除する方式である。これにより、lsmod コマンドでは現在インストールされている Reptile のカーネルモジュールが表示されない。

C. プロセスの隠蔽
「hide」および「show」コマンドとともに PID を伝達する場合は、その PID のプロセスを隠蔽する。プロセスの隠蔽に使用する方式は、大きく分けて4つある。1つは find_task_by_vpid() 関数をフックして隠蔽対象プロセスである場合 NULL を返すものであり、もう1つは似たように vfs_statx() 関数をフックして「EINVAL」、すなわち「Invalid argument」エラーを返すものである。find_task_by_vpid() 関数は getsid()、getpgid() のようなシステムのコールに使用される関数である。

また next_tgid() をフックして隠蔽対象のプロセスに対してはスキップするため、/proc/ リストには表示されなくなる。最後に sys_kill および __x64_sys_kill システムのコールについては「ESRCH」、すなわち「No such process」エラーを返して終了が不可能なようにする。この他にも load_elf_binary() 関数をフックして reptile_shell のパスを有する場合は当該プロセスを隠蔽する。

D. TCP/UDP の隠蔽
「conn」コマンドと隠蔽対象の IP アドレスを引数として伝達すると TCP / UDP ネットワーク通信を隠蔽できる。このために tcp4_seq_show() 関数と udp4_seq_show() 関数をフックする。

E. ファイル内容の隠蔽
Reptile は File Tempering、すなわちファイルの内容を隠蔽できる機能を提供する。以下のようにビルド時に指定したタグを本文に追加すると、このタグ間にある文字列を隠蔽する。デフォルトの設定では「#<reptile>」、「#</reptile>」タグを使用することができる。この機能を有効化するコマンドは「file-tampering」であり、このために vfs_read() 関数をフックする。

1.2.2. PORT KNOCKING

Reptile ルートキットは Port Knocking 手法をサポートしている。感染システムにインストールされたあと、すぐに C&C サーバーに接続する代わりに、特定のポートを開放して待機しておき、攻撃者が当該システムに Magic Packet を送信するときに動作する方式である。Magic Packet によって伝達されたデータには C&C サーバーのアドレスがあり、これをベースにリバースシェルが C&C サーバーに接続する。

Reptile の defconfig ファイルには基本的な設定が存在するが、デフォルトで MAGIC_VALUE が「hax0r」であり、PASSWORD が「s3cr3t」、SRCPORT が「666」である。

Figure 8. defconfig ファイル

感染システムの Reptile ルートキットはカーネル関数をフックして TCP / UDP / ICMP プロトコルを通じて渡されたパケットをモニタリングする。TCP / UDP パケットを渡された場合、まず Source Port をチェックするが、上記設定ファイルで指定した「666」ポートがその対象である。

Figure 9. SRCPORT のチェック

攻撃者は Client を利用して感染システムに Magic Packet を送信することができる。このために、まず Port Knocking 手法で使用するプロトコルとして TCP / UDP / ICMP から1つを選択することができ、感染システムの IP アドレスと上記で Reptile 制作時に設定した設定データである MAGIC_VALUE、PASSWORD、SRCPORT を指定する。その後 run コマンドを実行すると Packet はデータを暗号化して感染システムに送信される。

Figure 10.Port Knocking を利用したリバースシェル

666番のポートを開放して待機中だった Reptile は、当該ポートにパケットが受信されると、渡されたパケットのデータに MAGIC_VALUE と TOKEN で指定した値「hax0r」が含まれているかをチェックする。ここまでのプロセスが完了するとパケットを復号化して C&C サーバーのアドレスとポート番号を取得したあと、その値を引数として reptile_shell、すなわちリバースシェルを実行する。

Figure 11. MAGIC_VALUE のチェック

1.3. リバースシェル

Reptile ルートキットにより実行されたリバースシェルは、渡されたアドレスをベースに C&C サーバーに接続してシェルを提供する。リバースシェルは設定データで PASSWORD に指定した「s3cr3t」を引数として渡して実行されるが、PASSWORD は C&C サーバーで待機中であった Listener との通信においてセッションキーとして使用される。

リバースシェルは引数を受け取って動作するコマンドラインツールであり、条件によって2種類の方式によって実行されることがある。1つ目の方式は上記で取り上げた Port Knocking 方式であり、2つ目の方式は Reptile ルートキットのカーネルモジュールのインストールプロセスで実行される方式である。

Figure 12. reptile_shell の引数構造

Reptile ルートキットはインストール後の初期化プロセスでスタートアップスクリプトである reptile_start ファイルを実行する。このスクリプトには様々なコマンドが含まれる場合があり、代表的なものとしてリバースシェルを実行させるコマンドも存在する。

Figure 13. make プロセス、および生成された reptile_start スクリプトファイル

Reptile のリバースシェルはオープンソースの Linux バックドアマルウェアである TinySHell をベースにしている。TinySHell をベースに制作されたバックドアマルウェアには Rekoobe があり、主に中国の攻撃グループが使用しているものとして知られている。[7] Avast のレポートによれば Syslogk ルートキットも Magic Packet をトリガーとして動作する Port Knocking 方式をサポートしている。そして、バックドアとしてカスタマイズされた TinySHell、すなわち Rekoobe を使用した。これらの共通点から考えると、Syslogk 攻撃者が Reptile の構造を借用したものと推定される。

TinySHell と比較したとき、Reptile のリバースシェルはサポートするコマンドを含み、ほとんどのコードが同じである。特に C&C サーバーとの通信時に HMAC SHA1 アルゴリズムと AES-128 キーを用いて通信データを暗号化する方式や、通信プロセス中、完全性検証に使われるデータも同じように使用される。

Figure 14. TinySHell(左)と Reptile リバースシェル(右)のルーティンの比較

もちろん、違いも存在する。ファイルのダウンロード/アップロード、コマンド実行の他にもディレイコマンドをサポートしている点や ioctl で Reptile ルートキットに隠蔽コマンドを送信して C&C サーバーとの通信を隠す機能がデフォルトで備わっている点である。

2. 攻撃事例

2.1. VirusTotal でのハンティング

Reptile は Github に公開されているオープンソースマルウェアであるため、過去から様々な攻撃者により使用されている。Mandiant 社が最近公開した、中国を拠点とする攻撃グループによるフォーティネット製品のゼロデイ攻撃の事例 [8] を除いても、VirusTotal プラットフォームを見ると Reptile ルートキットマルウェアが定期的にアップロードされていることが確認できる。

実際の攻撃で使われたかどうかは分からないが、この数年間で多数の Reptile ルートキットが VirusTotal にアップロードされている。ここではアップロードされた複数の Reptile のうち、一部を対象にそれぞれの設定データを抽出して分類した。カーネルモジュールの vermagic を見ると、ほとんどの RHEL / CentOS Linux が攻撃またはテスト対象であることが特徴である。

Date Name Port MAGIC_VALUE PASSWORD Location vermagic
2020.05.22 rxp.ko 666 smoke smoker666 /rxp/ 2.6.32-696.18.7.el6.x86_64
2021.06.05 falc0n.ko 41302 7313F4lc0n4710n F4lc0nFly1n9d00r /usr/falc0n/ 3.10.0-1127.10.1.el7.x86_64
2022.04.27 N/A 2307 hA30r x5s3rt /opttest/ 3.10.0-1160.59.1.el7.x86_64
2022.11.21 myshell.ko 666 xiaofangzi xiaofangzi /myshell/ 2.6.32-431.el6.x86_64
Table 2. VirusTotal にアップロードされた Reptile ルートキット

2.2. 韓国国内の攻撃事例

Reptile は、過去に韓国国内の企業を対象とする攻撃においても使われた。初期侵入方式は未確認だが、Reptile のルートキット、リバースシェル、Cmd、スタートアップスクリプトがすべて収集され、基本的な設定を確認することができた。

この攻撃事例では Reptile の他にも ISH と呼ばれる ICMP Shell が攻撃に使われた。ISH は ICMP プロトコルを利用して攻撃者にシェルを提供できるマルウェアである。一般的にリバースシェルやバインドシェルは TCP や HTTP 等のプロトコルを利用するが、攻撃者はこれらの通信に対するネットワーク検出を回避するために ISH を使用したものと推定される。

2.2.1. REPTILE の解析

マルウェアは「/etc/intel_audio/」パスにインストールされたものと推定され、攻撃者は「reptile」の代わりに「intel_audio」をキーワードに使用した。

Figure 15. intel_audio_start スクリプト

また、intel_audio_start ファイルにリバースシェルを実行するコマンドラインが存在しないため、リバースシェルは Port Knocking 方式を使用するものと推定される。または、下記で取り上げるバインドシェルである ISH を使用した可能性もある。この他にも、攻撃者は file-tampering 機能を有効化した。

以下で rc.local 自動実行スクリプトを確認すると、file-tampering 機能によって隠蔽対象となる「#<intel_audio>」、「#</intel_audio>」タグの間に持続性維持のためのコマンドが存在することを確認できる。特異事項としては、攻撃者はローダー形式の Reptile ではなくカーネルモジュール形式の Reptile を使用するため、直接 insmod コマンドを利用して「/etc/intel_audio/intel_audio.ko」をロードするという点である。

Figure 16. rc.local 自動実行スクリプト

Intel_audio.ko はローダーによりパックされる前の段階、すなわち kmatryoshka でパックされたカーネルモジュールである。カーネルモジュールの vermagic を確認すると「3.10.0-514.el7.x86_64」、すなわち感染対象が Redhat または CentOS ベースの Linux システムであったものと推定できる。

抽出したルートキットには、様々な設定データがハードコーディングされている。例えば reptile_init() 関数にはスタートアップスクリプトファイルのパス名「/etc/intel_audio/intel_audio_start」が確認できる。攻撃者は正常なプログラムを装うために MAGIC_VALUE と PASSWORD 文字列を glibc による文字列で設定したことが特徴である。

Figure 17. reptile_init() 関数
項目 データ
インストール先 /etc/intel_audio/intel_audio.ko
ポート番号 5214
MAGIC_VALUE “glibc_0.1.5.so”
PASSWORD “glibc_0.1.6.so”
スタートアップスクリプトのパス /etc/intel_audio/intel_audio_start
リバースシェルのパス /etc/intel_audio/intel_audio_reverse
vermagic 3.10.0-514.el7.x86_64
Table 3. 韓国国内の攻撃に使用された Reptile の設定データ
2.2.2. ICMP SHELL の解析

「rc.local」自動実行スクリプトで実行および隠蔽対象となる「/etc/intel_audio/gvfs-gdb-volume-monitor」ファイルは、ISH という名前の ICMP Shell である。ISH はサーバーモジュール ishd とクライアントモジュール ish で構成されている。「gvfs-gdb-volume-monitor」ファイルは ishd であり、Reptile ルートキットにより実行され Listen しながら待機しておき、攻撃者が ish を利用して接続すると ICMP Shell を提供していたものと推定される。「gvfs-gdb-volume-monitor」で確認されるコマンドラインオプションも ishd と同様である。

Figure 18. ishd のメインルーティン

攻撃者は ishd マルウェアを生成する際にファイル検知を回避し、正常なプログラムを装うためにソースコードをそのまま使用せず、編集して制作している。以下の図は、左はオリジナルの ishd のソースコードで確認できる usage() 関数であり、右は「gvfs-gdb-volume-monitor」で確認できる usage() 関数である。これにより、他の引数を与えずにマルウェアが実行されるとき、「ICMP Debug Tool」という文字列を出力し、バインドシェルではなく正常なプログラムとして認識されるように誘導する。

Figure 19. 編集された出力文字列

3. Melofee との類似性

ExaTrack 社は最近、Linux サーバーを対象とするマルウェアを解析し、Mélofée と名付けた。攻撃に使用されたマルウェアとインフラをベースに、中国を拠点とする Winnti (APT41)攻撃グループとの関連性を確認した。[9](英語外部サイト)

攻撃者は、攻撃プロセスで Reptile ルートキットを同時に使用したが、ルートキットのインストール先が「/etc/intel_audio/intel_audio.ko」であることが特徴である。「/etc/intel_audio/intel_audio.ko」のパス名は上記で取り上げた韓国国内の企業を対象とする Linux サーバー攻撃の事例で確認された Reptile ルートキットのインストール先と同じである。

攻撃プロセスにおいて Reptile ルートキットが同時に使用されたという点や、インストール先が同じパス名である点、そして Reptile がデフォルトで提供する方式ではなく insmod コマンドで直接カーネルモジュールをインストールするという点が、2つの攻撃事例の共通点である。

Figure 20. Mélofée が生成した rc.modules ファイル

違いも存在する。Mélofée の攻撃事例で使用された Reptile はファイル隠蔽機能のみが有効化された形式であり、隠蔽対象のパスも以下のように「intel_audio」、「rc.modules」の2つでハードコーディングされている。

Figure 21.ハードコーディングされた隠蔽対象パス

韓国国内の攻撃事例ではマルウェアのほかに確認できる情報が限られていることから、これ以上の関連する情報を把握するのには限界がある。もちろん、正常なカーネルモジュールを偽装するために使用したパス名だが、攻撃に使われた「intel_audio」というキーワード自体があまりよく使われない文字列であるという点は、どちらの攻撃事例においても特徴的だと言える。

4. 結論

Reptile はファイル/ディレクトリおよびプロセス、ネットワーク通信の隠蔽機能を提供する Linux のカーネルモードルートキットマルウェアである。オープンソースであるため、様々な攻撃者が容易に使用でき、実際に多数の攻撃事例が確認されている。ルートキットの特性上、他のマルウェアと同時に使われるケースが多いが、Reptile 自体もリバースシェルを同時に提供しているため、Reptile がインストールされたシステムは攻撃者により制御権を奪われることになる。

このようなセキュリティ脅威を防止するためには脆弱な環境設定をチェックし、関連するシステムを常に最新バージョンにアップデートして攻撃から保護することが必要である。また、V3 を最新バージョンにアップデートしてマルウェアへの感染を事前に遮断できるように注意を払わなければならない。

V3 製品群では、これらのマルウェアに対して以下のような検知名で検知している。

ファイル検知
– Trojan/Script.Config (2023.07.20.03)
– Rootkit/Linux.Reptile.644496 (2020.05.31.00)
– Trojan/Linux.Reptile.10416 (2020.05.31.00)
– Trojan/Linux.Rvshell.55784 (2020.05.31.00)
– Backdoor/Linux.Ishell.10576 (2020.05.31.00)
– Rootkit/Linux.Reptile.560980 (2023.07.18.00)
– Rootkit/Linux.Reptile.802168 (2023.07.18.00)
– Rootkit/Linux.Reptile.799432 (2023.07.18.00)
– Rootkit/Linux.Reptile.569740 (2023.07.18.00)

IOC
MD5
– 1957e405e7326bd2c91d20da1599d18e:スタートアップスクリプト(intel_audio_start)
– d1abb8c012cc8864dcc109b5a15003ac:Reptile Rootkit (intel_audio.ko)
– f8247453077dd6c5c1471edd01733d7f:Reptile Cmd (intel_audio_cmd)
– cb61b3624885deed6b2181b15db86f4d:Reptile Reverse Shell (intel_audio_reverse)
– c3c332627e68ce7673ca6f0d273b282e:ICMP Shell (gvfs-gdb-volume-monitor)
– 246c5bec21c0a87657786d5d9b53fe38:Reptile ルートキット(rxp.ko)
– bb2a0bac5451f8acb229d17c97891eaf:Reptile ルートキット(falc0n.ko)
– 977bb7fa58e6dfe80f4bea1a04900276:Reptile ルートキット(N/A)
– 5b788feef374bbac8a572adaf1da3d38:Reptile ルートキット(myshell.ko)

関連 IOC および詳細な解析情報は、AhnLab の次世代脅威インテリジェンスプラットフォーム「AhnLab TIP」サブスクリプションサービスを通して確認できる。

Categories:マルウェアの情報

Tagged as:

5 1 vote
評価する
Subscribe
Notify of
guest

0 コメント
Inline Feedbacks
View all comments