このページでは、Virtual Machine Threat Detection のカーネルモードのルートキット検出結果の有効性を確認するために実行できるタスクについて説明します。カーネルモード ルートキットの検出結果は、VM のカーネルメモリがマルウェアによって改ざんされた可能性があることを示します。
VM Threat Detection からカーネルモード ルートキットの検出結果を受け取った場合は、影響を受ける Compute Engine インスタンスで次の Linux コマンドを実行して、ハイジャックされたシステムコールや隠しカーネル モジュールなど、異常を示す可能性のあるデータポイントをシステムでプローブすることをおすすめします。
または、影響を受ける VM で提供されているデータ収集スクリプトを実行することもできます。スクリプトは、このページで説明されているコマンドを実行します。
特に記載がない限り、このページの各検査タスクは、すべてのカーネルモード ルートキットの検出結果に関連しています。
このドキュメントの前提条件は次のとおりです。
VM Threat Detection からカーネルモードのルートキットの検出結果を受け取った後にこのドキュメントのタスクを実行している。関連する検出結果のカテゴリのリストについては、カーネルモード ルートキットの脅威の検出結果をご覧ください。
Linux コマンドライン ツールと Linux カーネルについて理解している。
VM Threat Detection について
Virtual Machine Threat Detection は、Security Command Center の組み込みサービスです。このサービスは、仮想マシンをスキャンして、侵害されたクラウド環境で実行されている、悪質な可能性のあるアプリケーション(暗号通貨マイニング ソフトウェア、カーネルモード ルートキット、マルウェアなど)を検出します。
VM Threat Detection は、Security Command Center の脅威検出スイートの一部であり、Event Threat Detection と Container Threat Detection の既存の機能を補完するように設計されています。
VM Threat Detection については、Virtual Machine Threat Detection の概要をご覧ください。VM Threat Detection の検出結果の詳細を表示する方法については、Google Cloud コンソールで検出結果を確認するをご覧ください。
始める前に
Security Command Center のすべてのリソースと検出結果を表示し、影響を受ける Compute Engine インスタンスを管理するために必要な権限を取得するには、次の IAM ロールを付与するよう管理者に依頼してください。
-
組織に対するセキュリティ センター管理者の閲覧者 (
roles/securitycenter.adminViewer
) -
Compute Engine インスタンスに対する Compute インスタンス管理者(v1)(
roles/compute.instanceAdmin.v1
)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
影響を受ける VM を特定する
- 検出結果の詳細を表示します。
- [影響を受けるリソース] セクションの [リソースの完全名] フィールドで、リンクをクリックします。影響を受ける Compute Engine インスタンスの詳細ビューが新しいタブで開きます。
- インスタンスに接続します。詳細については、Compute Engine のドキュメントの Linux VM に接続するをご覧ください。
予期しないカーネル モジュールを見つける
VM に予期しないモジュールが存在する場合、VM のカーネルメモリが侵害されている可能性があります。
予期しないカーネル モジュールを見つける手順は次のとおりです。
VM に読み込まれているすべてのカーネル モジュールを一覧表示します。
lsmod cat /proc/modules
読み込まれたモジュールと読み込まれていないモジュールの
sysfs
エントリを一覧表示します。ls -l /sys/module/
これらのリストの結果を、プロジェクト内の他の VM のリストと比較します。影響を受ける VM には表示されるにもかかわらず他の VM には表示されないモジュールを探します。
ツリー外モジュール用の syslog
を検索する
VM にツリー外モジュールが読み込まれた兆候は、異常なカーネル モジュールが読み込まれたことを示している可能性があります。カーネルログ バッファと syslog
メッセージを検索して、ツリー外モジュールが読み込まれたかどうかを確認できます。ログエントリでは、ツリー外モジュールは tainted 読み込みとしてマークされます。
カーネルログ バッファと syslog
メッセージで、次のようなログエントリを検索します。
MODULE_NAME: loading out-of-tree module taints kernel.
カーネルログ バッファで、ツリー外モジュールの存在を示すログエントリを検索します。
sudo dmesg | grep out-of-tree
すべての
syslog
メッセージを検索して、ツリー外モジュールの存在を示すログエントリを探します。grep "out-of-tree" /var/log/syslog*
ライブパッチの有無を確認する
VM でのライブパッチ適用は、VM Threat Detection の検出を妨げ、誤検出の検出結果をトリガーする可能性があります。
ライブパッチをチェックする手順は次のとおりです。
ライブパッチ モジュールのインストールとロギングについては、
syslog
を確認してください。通常、ライブパッチはカーネルftrace
ポイントをインストールしてカーネルコードを変更します。sudo grep livepatch /var/log/syslog*
ライブパッチ用にインストールされた新しいカーネル モジュール(通常は
livepatch
で始まる)を検索します。sudo lsmod | grep livepatch
パッチファイルを検索します。
sudo ls -l /sys/kernel/livepatch
ライブパッチについては、Linux カーネルのドキュメントのライブパッチをご覧ください。
VM で検出された他の悪意のあるアクティビティの可能性を確認する
- Security Command Center で、調査中の VM Threat Detection の検出結果の詳細を表示します。
- [影響を受けるリソース] セクションの [リソースの完全な名前] フィールドで、プルダウン矢印をクリックし、[このリソースの完全な名前を含むすべての検出結果を表示] をクリックします。検出結果クエリが更新され、この VM の検出結果のみが表示されます。
- 潜在的なクリプトマイニング アクティビティ、マルウェア、異常な IAM 権限付与、その他のセキュリティ上の脅威を示す検出結果を確認します。
ウイルス対策ソフトウェアが誤検出を引き起こしているかどうかを確認する
ウイルス対策ソフトウェアは VM Threat Detection の検出を妨げ、誤検出を引き起こす可能性があります。
システムで実行中のすべてのプロセスを確認する
予期しないプロセスが存在する場合、VM Threat Detection の検出結果が有効であり、VM が侵害されている可能性があります。
VM で実行されているすべてのプロセスを一覧表示します。
ps -eAf
この VM で通常実行されないデバッガ プロセス(
gdb
、strace
、pstack
など)を探します。デバッガ プロセスは他のプロセスをスヌーピングできます。VM で他の不審なプロセスを探します。
起動したカーネルを確認する
起動したカーネルをチェックして、Linux カーネルを特定します。
cat /proc/version
返された値が想定されるカーネル バージョンでない場合は、カーネルの kexec
ツールを悪用したハイジャック攻撃が行われた可能性があります。kexec
ツールを使用すると、システムをソフトブートして別のカーネルを使用できます。
Unexpected system call handler
の追加タスク
Defense Evasion: Unexpected system call handler
の検出結果が表示された場合は、このタスクを実行します。
システムコールを監査し、使用状況と呼び出し元に異常がないか確認します。監査ログには、システムコールの呼び出しプロセスと引数に関する情報が記録されます。検証タスクを実行して、一般的なシステムコールの想定される動作を確認することもできます。詳細については、このページの Diamorphine ルートキットを使用した検査の例をご覧ください。
Unexpected interrupt handler
の追加タスク
Defense Evasion: Unexpected interrupt handler
の検出結果が表示された場合は、このタスクを実行します。
システム上のライブ割り込みハンドラを一覧表示し、結果をプロジェクト内の他の類似 VM の情報と比較します。予期しない割り込みハンドラは、VM が侵害されていることを示す可能性があります。
ライブ割り込みハンドラを一覧表示するには、次のコマンドを実行します。
cat /proc/interrupts
出力は次のようになります。
CPU0 CPU1 0: 44 0 IO-APIC 0-edge timer 1: 9 0 IO-APIC 1-edge i8042 4: 17493 0 IO-APIC 4-edge ttyS0 8: 0 0 IO-APIC 8-edge rtc0 9: 0 0 IO-APIC 9-fasteoi acpi 12: 0 152 IO-APIC 12-edge i8042 24: 16 0 PCI-MSI 81920-edge virtio2-config 25: 0 40194 PCI-MSI 81921-edge virtio2-inflate 26: 58528 0 PCI-MSI 81922-edge virtio2-deflate 27: 0 966356 PCI-MSI 81923-edge virtio2-stats 28: 0 0 PCI-MSI 49152-edge virtio0-config 29: 0 0 PCI-MSI 49153-edge virtio0-control 30: 0 0 PCI-MSI 49154-edge virtio0-event 31: 0 555807 PCI-MSI 49155-edge virtio0-request 32: 0 0 PCI-MSI 98304-edge virtio3-config 33: 184 0 PCI-MSI 98305-edge virtio3-input 34: 0 0 PCI-MSI 65536-edge virtio1-config 35: 556203 0 PCI-MSI 65537-edge virtio1-input.0 36: 552746 1 PCI-MSI 65538-edge virtio1-output.0 37: 1 426036 PCI-MSI 65539-edge virtio1-input.1 38: 0 408475 PCI-MSI 65540-edge virtio1-output.1
Unexpected processes in runqueue
の追加タスク
Defense Evasion: Unexpected processes in
runqueue
の検出結果が表示された場合は、次の手順を行います。このセクションでは、調査結果を調査するためのデータポイントを追加で収集する方法について説明します。これらのデータポイントは、マルウェアの問題を直接示すものではない可能性があります。
このタスクでは、CPU ごとのスケジューラ キューを確認します。一部のプロセスは短時間で終了する可能性がありますが、CPU あたりの実行中のプロセスを使用してスケジューラ キューの動作を評価し、異常な動作を探すことができます。
各実行中のプロセスが CPU ごとに費やした時間の詳細を表示します。これにより、特定の CPU が非常にビジー状態かどうかを確認できます。結果を
/proc/interrupts
から CPU に固定された割り込みに関連付けることができます。cat /proc/schedstat
このコマンドの詳細については、Linux カーネルのドキュメントのスケジューラ統計情報をご覧ください。
現在の実行可能なタスクと、各 CPU のコンテキスト切り替えに関する詳細を一覧表示します。
cat /proc/sched_debug
出力は次のようになります。
Sched Debug Version: v0.11, 5.4.0-1081-gke #87-Ubuntu ktime : 976187427.733850 sched_clk : 976101974.761097 cpu_clk : 976101973.335113 jiffies : 4538939132 sched_clock_stable() : 1 sysctl_sched .sysctl_sched_latency : 12.000000 .sysctl_sched_min_granularity : 1.500000 .sysctl_sched_wakeup_granularity : 2.000000 .sysctl_sched_child_runs_first : 0 .sysctl_sched_features : 2059067 .sysctl_sched_tunable_scaling : 1 (logarithmic) cpu#0, 2199.998 MHz .nr_running : 0 .nr_switches : 16250401 .nr_load_updates : 0 .nr_uninterruptible : 12692 .next_balance : 4538.939133 .curr->pid : 0 .clock : 976101971.732857 .clock_task : 976101971.732857 .avg_idle : 880408 .max_idle_balance_cost : 500000 runnable tasks: S task PID tree-key switches prio wait-time sum-exec sum-sleep ----------------------------------------------------------------------------------------------------------- S systemd 1 51740.602172 326778 120 0.000000 165741.786097 0.000000 0 0 /init.scope S kthreadd 2 1482297.917240 1361 120 0.000000 112.028205 0.000000 0 0 / I rcu_sched 11 1482642.606136 1090339 120 0.000000 17958.156471 0.000000 0 0 / S cpuhp/1 15 537.058588 8 120 0.000000 2.275927 0.000000 0 0 / S idle_inject/1 16 -2.994953 3 49 0.000000 0.012780 0.000000 0 0 / S migration/1 17 0.000000 245774 0 0.000000 5566.508869 0.000000 0 0 / S ksoftirqd/1 18 1482595.656315 47766 120 0.000000 1235.099147 0.000000 0 0 / I kworker/1:0H 20 536.961474 5 100 0.000000 0.043908 0.000000 0 0 / S kdevtmpfs 21 11301.343465 177 120 0.000000 3.195291 0.000000 0 0 / I netns 22 6.983329 2 100 0.000000 0.021870 0.000000 0 0 / Srcu_tasks_kthre 23 10.993528 2 120 0.000000 0.010200 0.000000 0 0 / S kauditd 24 1482525.828948 319 120 0.000000 14.489652 0.000000 0 0 /
次の内容を確認します。
- 実行中のプロセス名。
- CPU あたりのコンテキスト切り替えの数。CPU でのスイッチ数が少なすぎるか多すぎるプロセスがあるかどうかを確認します。
- 使用した CPU 時間(アイドル状態ではない時間)。
Diamorphine ルートキットを使用した検査の例
このセクションでは、Diamorphine ルートキットがインストールされている VM の検査について説明します。Diamorphine は、よく使われるローダブル カーネル モジュール(LKM)です。このルートキットは、次の検出結果カテゴリをトリガーします。
Defense Evasion: Unexpected system call handler
Defense Evasion: Unexpected kernel modules
Defense Evasion: Unexpected kernel read-only data modification
これらの検出結果カテゴリの詳細については、カーネルモードのルートキットの脅威の検出結果をご覧ください。
VM で実施した検査手順と確認された症状は次のとおりです。
読み込まれているすべてのツリー外カーネル モジュールについて
syslog
を検索します。カーネルログ バッファを検索します。
sudo dmesg | grep out-of-tree
出力:
diamorphine: loading out-of-tree module taints kernel.
syslog
メッセージを検索します。grep "out-of-tree" /var/log/syslog*
出力:
/var/log/syslog: diamorphine: loading out-of-tree module taints kernel.
syslog
を検索して、モジュールの検証の失敗がないか確認します(すべての Linux ディストリビューションで利用できるわけではありません)。カーネルログ バッファを検索します。
sudo dmesg | grep "module verification failed"
出力:
diamorphine: module verification failed: signature and/or required key missing - tainting kernel
syslog
メッセージを検索します。sudo grep "module verification failed" /var/log/syslog*
出力:
/var/log/syslog: diamorphine: module verification failed: signature and/or required key missing - tainting kernel
モジュールが
/proc/modules
コマンドとlsmod
コマンドから非表示になっていることを確認します。sudo grep diamorphine /proc/modules sudo lsmod | grep diamorphine
結果は表示されませんでした。
モジュールに
sysfs
のエントリがあることを確認します。sudo cat /sys/module/diamorphine/coresize
出力:
16384
アーキテクチャのシステムコール テーブルを取得します。
sudo ausyscall --dump
出力:
Using x86_64 syscall table: 0 read 1 write 2 open 3 close
ルートキットによって改ざんされることが多い
kill
やgetdents
などのシステムコールで異常がないか監査します。システムコール ハンドラの改ざんをチェックするには、システムコールを監査して、異常な動作がないか確認します。これらの動作はシステムコールごとに異なります。
通常、ハッキングされるシステムコールは
kill
コールです。kill
システムコールがバイパスされたかどうかを確認できます。次の例では、kill
システムコールが監査されています。auditd
をインストールし、Diamorphine ルートキットなしで VM の動作を観察します。$ sudo apt-get update && sudo apt-get install auditd $ # Add audit rules for specific system calls $ sudo echo "-a exit,always -F arch=b64 -S kill -k audit_kill" >> /etc/audit/rules.d/audit.rules $ sudo /etc/init.d/auditd restart Restarting auditd (via systemctl): auditd.service. $ # Behavior observed without rootkit $ sleep 600 & [1] 1119 $ sudo kill -9 1119 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1119" type=OBJ_PID msg=audit(1677517839.523:198): opid=1119 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677517839.523:198): arch=c000003e syscall=62 success=yes exit=0 a0=45f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill" $ sleep 600 & [1] 1087 $ sudo kill -31 1087 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1087" type=OBJ_PID msg=audit(1677517760.844:168): opid=1087 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677517760.844:168): arch=c000003e syscall=62 success=yes exit=0 a0=43f a1=1f a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
検査のこの時点で、Diamorphine ルートキットがインストールされました。次の手順では、ルートキットのインストール後の VM の動作を示します。
Diamorphine ルートキットのインストール後、シグナルの監査ログエントリが存在しないことを確認します。
$ sudo ausearch -k audit_kill | grep -A 3 "pid=1158" $ sleep 600 & [2] 1167
シグナルの監査ログエントリで詳細を確認します。この例では、この特定のシグナルはルートキットによって完全にハイジャックされていませんが、呼び出し元プロセスに関する情報は利用可能です。
$ sudo kill -9 1167 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1167" type=OBJ_PID msg=audit(1677518008.586:237): opid=1167 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677518008.586:237): arch=c000003e syscall=62 success=yes exit=0 a0=48f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
データ収集スクリプトをデバッグする
次のスクリプトは、このページで説明するデバッグタスクの多くを実行します。このスクリプトは、sudo
モードまたは root
モードで実行できます。スクリプトはシステムからデバッグ情報のみを読み取ります。
$ cat kprot.sh
#!/bin/bash
echo "Boot command line"
cat /proc/cmdline
echo "=================================================="
echo "Loaded modules"
cat /proc/modules
echo "=================================================="
echo "Current tracer"
cat /sys/kernel/debug/tracing/current_tracer
echo "=================================================="
echo "Tracing event enable"
cat /sys/kernel/debug/tracing/events/enable
echo "=================================================="
echo "Tracing sub events enable"
for en in `find /sys/kernel/debug/tracing/events/*/enable`; do printf "\b$en\n"; cat $en; done
echo "=================================================="
echo "IP table rules"
iptables -L
echo "=================================================="
echo "Ftrace list"
cat /sys/kernel/debug/tracing/enabled_functions
echo "=================================================="
echo "Kprobes enabled"
cat /sys/kernel/debug/kprobes/enabled
echo "=================================================="
echo "Kprobes list"
cat /sys/kernel/debug/kprobes/list
echo "=================================================="
echo "Kprobes blocklist"
cat /sys/kernel/debug/kprobes/blacklist
echo "=================================================="
echo "BPF trace"
sudo apt update && sudo apt-get update && sudo apt-get install bpftrace
bpftrace -l
echo "=================================================="
echo "BPF prog list"
sudo apt update && sudo apt install linux-tools-`uname -r`
bpftool prog
echo "=================================================="