
バックドア、C2、ライブラリインジェクション、実行ハイジャック、永続化、ステルス機能を備えたLinux eBPFルートキット
TripleCross は、eBPF テクノロジーの攻撃能力を示す Linux eBPF ルートキットです。
TripleCross は、この分野の以前のインプラント設計、特に DEFCON 27 の Jeff Dileo1、DEFCON 29 の Pat Hogan2、同じく DEFCON 29 の Guillaume Fournier と Sylvain Afchain3、そして Kris Nóva の Boopkit4 の研究に触発されています。これらの eBPF テクノロジーの攻撃能力に関する先駆的な探求により開拓された技法の一部を再利用し、拡張しています。
このルートキットは、UC3M での学士論文のために作成されました。設計の詳細については、論文ドキュメント を参照してください。
このルートキットは 純粋に教育および学術目的 です。ソフトウェアは「現状のまま」提供され、著者は使用中に発生する可能性のあるいかなる損害や事故についても責任を負いません。
TripleCross を法律違反に使用しないでください。提供されたソフトウェアおよび情報の誤用は、刑事告訴につながる可能性があります。
次の図は、TripleCross のアーキテクチャとそのモジュールを示しています。
ルートキットの通信に使用される Raw ソケットライブラリ RawTCP_Lib は私の著作であり、独自のリポジトリ があります。
次の表は、主要なソースコードファイルとディレクトリを説明し、ナビゲーションを容易にします。
この研究プロジェクトは、以下の環境でテストされています。
| ディストリビューション | カーネル | GCC | CLANG | GLIBC | |
|---|---|---|---|---|---|
| バージョン | Ubuntu 21.04 | 5.11.0 | 10.3.0 | 12.0.0 | 2.33 |
Ubuntu 21.04 を使用することを推奨します。デフォルトでここに示すソフトウェアバージョンが組み込まれます。そうでない場合、発生する可能性のある問題の一部はこちらで説明されています。
ルートキットのソースコードは、2 つの Makefile を使用してコンパイルされます。```
cd src make all
cd client make
以下の表は、各 Makefile の目的を詳細に説明しています:
| MAKEFILE | COMMAND | 説明 | 生成されるファイル |
| ------------- | ------------- | ------------- | ------------- |
| src/client/Makefile | make | ルートキットクライアントのコンパイル | src/client/injector |
| src/Makefile | make help | ルートキット機能をテストするためのプログラム、および実行ハイジャックモジュールとライブラリインジェクションモジュールの悪意のあるプログラムとライブラリのコンパイル(それぞれ) | src/helpers/simple_timer, src/helpers/simple_open, src/helpers/simple_execve, src/helpers/lib_injection.so, src/helpers/execve_hijack |
| src/Makefile | make kit | libbpf ライブラリを使用したルートキットのコンパイル | src/bin/kit |
| src/Makefile | make tckit | ルートキット TC 出力プログラムのコンパイル | src/bin/tc.o |
### インストール
ルートキットファイルが src/bin/ に生成されたら、*tc.o* と *kit* プログラムを順にロードする必要があります。以下の例では、ルートキットのバックドアがネットワークインターフェース *enp0s3* で動作します:```
// TC egress program
sudo tc qdisc add dev enp0s3 clsact
sudo tc filter add dev enp0s3 egress bpf direct-action obj bin/tc.o sec classifier/egress
// Libbpf-powered rootkit
sudo ./bin/kit -t enp0s3
攻撃者が実際の攻撃シナリオで行うように、ルートキットを自動的にコンパイルしてインストールする2つのスクリプト、packager.sh と deployer.sh があります。
packager.sh を実行すると、apps/ ディレクトリ以下にすべてのルートキットファイルが生成されます。
deployer.sh を実行すると、ルートキットがインストールされ、永続化ファイルが作成されます。
これらのスクリプトは、永続化モジュールが正しく機能するために、以下のパラメータを最初に設定する必要があります。
| スクリプト | 定数 | 説明 |
|---|---|---|
| src/helpers/deployer.sh | CRON_PERSIST | 再起動後に実行するCronジョブ |
| src/helpers/deployer.sh | SUDO_PERSIST | パスワードなしで特権を付与するSudoエントリ |
ルートキットは、sys_timerfd_settime または sys_openat システムコールを呼び出すプロセスの実行を乗っ取ることができます。これは、呼び出しを行っているプロセスの仮想メモリにあるGlobal Offset Table(GOT)セクションを上書きすることで実現されます。これにより、悪意のあるライブラリ(src/helpers/injection_lib.c)が実行されます。このライブラリは攻撃マシンにリバースシェルを起動し、その後、プロセスをクラッシュさせることなく実行フローを元の関数に戻します。
TripleCrossは、以下の一般的なELFハードニング技術をバイパスするように準備されています。
また、Intel CET互換のコードでも動作するよう準備されています。
モジュールの機能は、2つのテストプログラム src/helpers/simple_timer.c と src/helpers/simple_open.c を使用して確認できます。あるいは、任意のシステムプロセスを乗っ取ることも可能です(systemdでテスト済み、動作確認済み)。
モジュールの設定は、以下の定数によって行われます。
| ファイル名 | 定数 | 説明 |
|---|
攻撃マシンからのリバースシェルを受信するには、netcatを使用します:``` nc -nlvp <ATTACKER_PORT>
### GOTハイジャック技術によるライブラリ注入
TripleCrossに組み込まれているこの技術は、5つの段階で構成されています。
#### GOTとリターンアドレスの特定
ルートキットは、トレースポイントプログラムを使用してシステムコールをフックします。そこから、PLTスタブがシステムコールを担当するglibc関数を呼び出すために使用したGOTセクションのアドレスを特定します。
GOTセクションに到達するために、eBPFプログラムはスタックに保存されたリターンアドレスを使用します。注意点は以下の通りです。
* .textは.pltを*call*するため、*rip*が*ret*としてスタックに保存されます。
* .pltは.gotを使用してglibcに*jump*するため、他の*rip*は保存されません。また、*rbp*の値を変更または保存しません。
* Glibcは*syscall*を実行しますが、*rip*をスタックに保存せず、*rcx*に保存します。
<img src="https://assets.kitploit.com/production/public/readmes/5614/d216fa5b7b656bb52587027db28f3e3902fa8389d0b2944a1f7e870d6d2e6bee.jpg" float="left">
したがって、スタック上のアドレスが、eBPFからフックしたシステムコールを実行するglibc関数にジャンプするGOTアドレスを使用するPLTスタブのリターンアドレスであるかどうかを確認するには、それが正しいGOTに導くリターンアドレスであることを確認する必要があります。
リターンアドレスを見つけるための2つの手法が組み込まれています。
* sys_timerfd_settimeを使用する場合、eBPFプログラムはシステムコールの引数を使用して前方にスキャンします。
* sys_openatを使用する場合、eBPFプログラムはトレースポイントの*pt_regs*構造体のデータを使用してリターンアドレスをスキャンします。
<img src="https://assets.kitploit.com/production/public/readmes/5614/61217fb3fd84bec65cbbee906dd27860e5e1c211912cfe450ea4cf9051fa480b.png" float="left">
#### シェルコードのための主要関数の特定
シェルコードは、ASLRやPIEをバイパスするために動的に生成する必要があります。これらはプログラム実行のたびにdlopen()などの関数のアドレスを変更します。
<img src="https://assets.kitploit.com/production/public/readmes/5614/6cbb620495d8cb9711e499fd5b1ae9ea845c03d0c33019cf008b456a95d5ddd6.png" float="left">
#### コードケイブへのシェルコードの注入
ASLRとPIEが無効になっている場合は、ELFをリバースエンジニアリングすることでコードケイブを見つけることができますが、通常はそうではありません。eBPFプログラムは、ユーザー空間のルートキットプログラムにリクエストを発行し、/procファイルシステムを使用して.text(実行可能)セクションのコードケイブを特定し、そこに書き込みます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/c7daea0eed684437b5c7d971d0f69f5aac9138861d44da36c5368be9f97666d1.png" float="left">
#### GOTセクションの上書き
実行可能ファイルでPartial RELROとFull RELROのどちらがアクティブであるかに応じて、eBPFプログラムはGOTセクションを直接、または/procファイルシステムを使用して上書きします。
<img src="https://assets.kitploit.com/production/public/readmes/5614/7e69ec2982ee8c77c39b42f364ab25e52c40d96890f7413b3afe04dde1b825c3.png" float="left">
#### 次のシステムコールの待機
ハイジャックされたプログラムで次のシステムコールが発行されると、PLTセクションは変更されたGOTセクションを使用し、実行フローがハイジャックされてコードケイブ内のシェルコードにリダイレクトされます。シェルコードはプログラムのクラッシュを防ぐように準備されており、悪意のあるライブラリ(*src/helpers/lib_injection.so*)を呼び出します。このライブラリはfork()を発行し、攻撃マシンとのリバースシェルを生成します。その後、実行フローが復元されます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/4e780cbcba855fe11a55f6a34709d83d855a4235960b15b69470233147f04318.png" float="left">
## バックドアとC2
バックドアは、設定を必要とせずにそのまま動作します。バックドアは、ルートキットクライアントプログラムを使用してリモートから制御できます。
| クライアント引数 | アクションの説明 |
| ------------- | ------------- |
| ./injector -c \<被害者IP\> | 実行ハイジャックモジュールを使用して、プレーンテキストの擬似シェルを生成します |
| ./injector -e \<被害者IP\> | パターンベースのトリガーでバックドアに命令することで、暗号化された擬似シェルを生成します |
| ./injector -s \<被害者IP\> | マルチパケットトリガー(両方のタイプ)でバックドアに命令することで、暗号化された擬似シェルを生成します |
| ./injector -p \<被害者IP\> | パターンベースのトリガーでバックドアに命令することで、ファントムシェルを生成します |
| ./injector -a \<被害者IP\> | ルートキットにすべてのeBPFプログラムをアクティブ化するよう命令します |
| ./injector -u \<被害者IP\> | ルートキットにすべてのeBPFプログラムをデタッチするよう命令します |
| ./injector -S \<被害者IP\> | バックドアがカーネルからメッセージを隠す方法を示します(シンプルなPoC) |
| ./injector -h | ヘルプを表示します |
### バックドアトリガー
アクションはバックドアトリガーを使用してバックドアに送信されます。トリガーは、属性**K3**の値に応じてバックドアに実行するアクションを示します。
| K3の値 | アクション |
| ------------- | ------------- |
| 0x1F29 | 暗号化された擬似シェル接続を開始するリクエスト |
| 0x4E14 | ファントムシェル接続を開始するリクエスト |
| 0x1D25 | すべてのルートキットeBPFプログラムをロードしてアタッチするリクエスト |
| 0x1D24 | すべてのルートキットeBPFプログラム(バックドアのものを除く)をデタッチするリクエスト |
#### パターンベースのトリガー
このトリガーは、コマンドとクライアント情報を隠してバックドアが認識できるようにする一方で、外部のネットワーク監視者には十分にランダムに見えるようにします。これは、最近発見されたNSAルートキット[Bvp47](https://www.pangulab.cn/files/The_Bvp47_a_top-tier_backdoor_of_us_nsa_equation_group.en.pdf)で使用されているトリガーに基づいています。
<img src="https://assets.kitploit.com/production/public/readmes/5614/58cec7ee2dbd89b6c7d71d60c006a1a98d7b9165b20bdbe006467a82d5dc30ab.png" float="left">
#### マルチパケットトリガー
このトリガーは複数のTCPパケットで構成され、バックドアペイロードがパケットヘッダーに隠されています。この設計は、Vault 7リークで説明されているCIAの[Hive](https://wikileaks.org/vault7/document/hive-DevelopersGuide/hive-DevelopersGuide.pdf)インプラントに基づいています。次のペイロードが使用されます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/45a8348c3d366af4941d9cca845c281fc8c5a565353fc8fe3fb91350f39dd5f8.png" float="left">
次に、上記のペイロードに対してローリングXORが計算され、ルートキットクライアントが選択したモードに応じて複数の部分に分割されます。TripleCrossは、TCPシーケンス番号に隠されたペイロードをサポートします。
<img src="https://assets.kitploit.com/production/public/readmes/5614/2b9d7fd46f7133e3eeda694e0b4791fbed2a51616b7d2f14e989a9e0e56af9e2.png" float="left">
また、TCP送信元ポートに隠されたペイロードもサポートします。
<img src="https://assets.kitploit.com/production/public/readmes/5614/1a6ea6da628a9902eaf55cc3c1549a2ecf26cba211275acdce6bc5491b34140c.png" float="left">
### バックドアの擬似シェル
クライアントはルートキットの擬似シェルを確立できます。これは、シェルプログラムをシミュレートする特別なルートキット間のクライアント接続であり、攻撃者がリモートでLinuxコマンドを実行し、感染したマシンで直接実行しているかのように結果を取得できるようにします。ルートキットには複数の擬似シェルが組み込まれています。
#### プレーンテキストの擬似シェル
このシェルは、実行ハイジャックモジュールが正常に実行された後に生成されます。これにより、次のようにルートキットクライアントとの接続を確立する悪意のあるファイルが実行されます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/6495b5b62c33ae136b8c965658d9c5f501e609029bde7fcefe7266966f8effbb.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/5301e208d9853760eabdc14772c57a3639f28d71d050ee82d151bff93a76cedf.png" float="right">
#### 暗号化された擬似シェル
暗号化された擬似シェルは、ルートキットクライアントがいつでもリクエストでき、ルートキットとルートキットクライアント間のTLS接続で構成されます。暗号化された接続内では、プレーンテキストの擬似シェルと同様に、コマンドと情報を通信するための伝送プロトコルが使用されます。
暗号化された擬似シェルを生成するには、バックドアがトリガーをリッスンする必要があります。バックドアは、パターンベースのトリガーまたは両方のタイプのマルチパケットトリガーのいずれかを受け入れます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/d4929247af8895f78522f28c4ac8087e74d76b91320c67e0b37ea841cd8869d0.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/6e2a72d04028212a4917397b75b052a4bdf3c0529fb6c5e336b7fc0a06571728.png" float="right">
#### ファントムシェル
ファントムシェルは、XDPとTCプログラムの組み合わせを使用して、特に新しいパケットを生成できないというeBPFのネットワークにおける制限を克服します。このため、バックドアは既存のトラフィックを変更し、ペイロードをC2送信のデータで上書きします。元のパケットは失われません。TCP再送信により、元のパケット(変更なし)が短期間後に再度送信されるためです。
次のプロトコルは、ファントムシェルを使用したコマンド実行中のトラフィックを示しています。
<img src="https://assets.kitploit.com/production/public/readmes/5614/0aafe6b672757e4e9d37402c72ce14893a8a7f198030b2f2386df631c345d16b.png" float="left">
ファントムシェルは、バックドアが実行するコマンドを発行するルートキットクライアントによってリクエストされます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/e07dec48ff6a22e708b6d4b0d762473cc6483f065011cd6cdccdac49f12f916b.png" float="left">
感染したマシンがTCPパケットを送信した後、バックドアはそれを上書きし、クライアントが応答を表示します。
<img src="https://assets.kitploit.com/production/public/readmes/5614/19bea585b78a0bb1d52aa7c63ff05a0111551a0cc767732775491641e1dec021.png" float="left">
## 実行ハイジャックモジュール
原則として、eBPFプログラムは単独でプログラムの実行を開始することはできません。このモジュールは、悪意のあるルートキットが、ユーザー空間で悪意のあるコードを実行するために、どのようにして良性のプログラムを利用できるかを示しています。このモジュールは2つの目標を達成します。
* 他のプログラムの実行を利用して、悪意のあるユーザープログラムを実行します。
* ユーザー空間に対して透過的であること。つまり、プログラムの実行をハイジャックして別のプログラムを実行しても、元のプログラムも最小限の遅延で実行されるべきです。
このモジュールは、sys_execve()システムコールをハイジャックし、その引数を変更して、代わりに悪意のあるプログラム(*src/helpers/execve_hijack.c*)が実行されるようにすることで動作します。この変更は、悪意のあるプログラムが元のプログラムを元の引数で実行できるように行われ、ユーザー空間での懸念を引き起こさないようにします。次の図は、全体的な機能をまとめたものです。
<img src="https://assets.kitploit.com/production/public/readmes/5614/601610696506e303f91a7957ec2a3d61f73f7d0e036430a9f67bd80a6f19b2d3.png" float="left">
元のsys_execve()呼び出しの引数は、元の引数が失われないように変更され(argv[0]を使用)、悪意のあるプログラムの後に元のプログラムを実行できるようにします。
<img src="https://assets.kitploit.com/production/public/readmes/5614/e483317a3bdac422cdfc49ca92acdcefe624ddceb5b2ed036ccec141c8d1e5e6.png" float="left">
実行ハイジャックモジュールをテストするためのサンプルテストプログラム(*src/helpers/simple_execve.c*)を組み込んでいます。このモジュールは、設定に応じてシステム内の任意の呼び出しをハイジャックすることもできます。
| ファイル名 | 定数 | 説明 |
| ------------- | ------------- | ------------- |
| src/common/constants.h | PATH_EXECUTION_HIJACK_PROGRAM | sys_execve呼び出しの実行成功時に実行される悪意のあるプログラムの場所 |
| src/common/constants.h | EXEC_HIJACK_ACTIVE | 実行ハイジャックモジュールを無効化(0)または有効化(1)します |
| src/common/constants.h | TASK_COMM_RESTRICT_HIJACK_ACTIVE | すべてのsys_execve呼び出しをハイジャックする(0)、またはTASK_COMM_NAME_RESTRICT_HIJACKで指定されたもののみをハイジャックする(1) |
| src/common/constants.h | TASK_COMM_NAME_RESTRICT_HIJACK | sys_execve呼び出しをハイジャックする元のプログラムの名前 |
ハイジャックが成功すると、モジュールは自身を停止します。悪意のあるプログラム*execve_hijack*は、ルートキットクライアントからのプレーンテキストの擬似シェルのリクエストをリッスンします。
## ルートキットの永続性
感染したマシンが再起動されると、すべてのeBPFプログラムはカーネルからアンロードされ、ユーザーランドのルートキットプログラムは強制終了されます。さらに、ルートキットが自動的に再実行されたとしても、eBPFプログラムを再度アタッチするために必要なルート権限を失っています。ルートキットの永続性モジュールは、これらの2つの課題に取り組むことを目的としています。
* マシンの再起動イベント後に、ルートキットを自動的かつユーザーの操作なしで実行します。
* ルートキットがマシンで最初に実行されたときにルート権限を取得したら、再起動後もそれを維持する必要があります。
TripleCrossは、この機能を実装するために、*cron.d*と*sudoers.d*の下に作成された2つの秘密ファイルを使用します。これらのエントリにより、再起動後にルートキットが自動的かつ完全な権限でロードされることが保証されます。これらのファイルは、*deployer.sh*スクリプトによって作成および管理されます。
<img src="https://assets.kitploit.com/production/public/readmes/5614/88500b779b9ad5ba771803900a8abfffd08f3a6be59518e690534779a4134cf8.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/5ae61ed98af6d7c8aa9448fed3de553712ffb5c63e95d98a6f4300ff407bce23.png" float="right">
スクリプトには、標的システム上で感染させるユーザー向けに設定する必要がある2つの定数が含まれています。
| スクリプト | 定数 | 説明 |
| ------------- | ------------- | ------------- |
| src/helpers/deployer.sh | CRON_PERSIST | 再起動後に実行するcronジョブ |
| src/helpers/deployer.sh | SUDO_PERSIST | パスワードなしの権限を付与するsudoエントリ |
## ルートキットのステルス性
永続性モジュールは追加のファイルを作成することに基づいていますが、それらはシステム所有者やソフトウェアツールによって最終的に発見される可能性があるため、システムに残しておくリスクがあります。さらに、ルートキットファイルはどこかの場所に保存する必要があり、そこで発見される可能性があります。
以上を考慮して、ステルスモジュールは以下の機能を提供します。
* ディレクトリをユーザーから完全に隠します(これにより、すべてのルートキットファイルを内部に隠すことができます)。
* ディレクトリ内の特定のファイルを隠します(永続性ファイルを隠す必要がありますが、*sudoers.d*や*cron.d*ディレクトリは通常のシステム機能に属するため、完全に隠すことはできません)。
ルートキットによって隠されるファイルとディレクトリは、以下の設定定数によってカスタマイズできます。
| ファイル名 | 定数 | 説明 |
| ------------- | ------------- | ------------- |
| src/common/constants.h | SECRET_DIRECTORY_NAME_HIDE | 隠すディレクトリの名前 |
| src/common/constants.h | SECRET_FILE_PERSISTENCE_NAME | 隠すファイルの名前 |
デフォルトでは、TripleCrossは「*ebpfbackdoor*」という名前のファイルと「SECRETDIR」という名前のディレクトリを隠します。このモジュールはルートキットのインストール後に自動的にアクティブになります。
この機能を実現するために使用される手法は、sys_getdents()システムコールの引数を改ざんすることです。
<img src="https://assets.kitploit.com/production/public/readmes/5614/7f928351c1c07e7b6a534846c5374788449e03455191cddf8c7f02af2c885852.png" float="left">
## ライセンス
TripleCrossルートキットとルートキットクライアントは、GPLv3ライセンスの下でライセンスされています。[LICENSE](https://github.com/h3xduck/TripleCross/blob/master/LICENSE)を参照してください。
[RawTCP_Lib](https://github.com/h3xduck/RawTCP_Lib)ライブラリはMITライセンスの下でライセンスされています。
元の論文文書と含まれる図は、[Creative Commons BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/)の下で公開されています。
| ディレクトリ | 説明 |
|---|
| docs | 元の論文ドキュメント |
| src/client | ルートキットクライアントのソースコード |
| src/client/lib | RawTCP_Lib 共有ライブラリ |
| src/common | ルートキットの定数と設定。リングバッファなど、ルートキットの eBPF 側とユーザースペース側に共通の要素の実装も含む |
| src/ebpf | ルートキットが使用する eBPF プログラムのソースコード |
| src/helpers | いくつかのルートキットモジュールの機能をテストするためのプログラム、および実行ハイジャックモジュールとライブラリインジェクションモジュールでそれぞれ使用される悪意のあるプログラムとライブラリを含む |
| src/libbpf | ルートキットに統合された libbpf ライブラリ |
| src/user | ルートキットが使用するユーザーランドプログラムのソースコード |
| src/vmlinux | カーネルデータ構造の定義を含むヘッダー(これは libbpf を使用する場合の推奨方法) |
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_TIMERFD_SETTIME | sys_timerfd_settime システムコールでハイジャックするプロセス名 |
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_OPEN | sys_openat システムコールでハイジャックするプロセス名 |
| src/helpers/injection_lib.c | ATTACKER_IP & ATTACKER_PORT | 攻撃マシンのIPアドレスとポート |