インシデント発生時に電源を入れたままにすべきか問題

### 更新履歴
2024/6/28 ネットワーク遮断の是非について追記しました。

# はじめに
とあるセキュリティインシデントにおいて、サーバを電源ケーブルごと引き抜いたという対応が行われ、X（Twitter）ではこの対応について賛否両論が見られました。このうち電源を入れたままにすべきという人の意見には、「マルウェアの中にはシャットダウンすることで自分自身を削除し、感染痕跡を削除するものがある」「メモリを調査すべきなのでシャットダウンすべきではない」のような意見が見られました。

本記事では実際にメモリからどのような情報がわかるか、そしてメモリダンプを解析することの有用性と課題について記載します。
また、インシデント発生時の特に封じ込めフェーズについても考察します。

# メモリフォレンジック
セキュリティインシデントにおいてはフォレンジック調査が行われる場合があります。フォレンジック調査には、HDDやSSDのようなストレージを調査対象とするディスクフォレンジック、パケットキャプチャやNetFlow、ProxyやFWのログのような通信を対象とするネットワークフォレンジック、そして今回取り上げるメモリフォレンジックがあります。

一般的にメモリフォレンジックは他の調査手法では調査が難しいプロセスやネットワーク接続の状態を調査することが可能です。

# メモリフォレンジックの流れ
メモリフォレンジックも他の調査手法と基本的には変わりません。データを保全し、そのデータを調査します。メモリの場合はメモリダンプを行い、専用のツールで調査するのが一般的です。

# Windowsのメモリフォレンジック
## メモリダンプの方法
過去にFTK Imagerを用いた詳細な手順を記載していますので、こちらをご参照ください。他にもDumpITやRam Captureというツールもあります。どちらも簡単な操作でメモリダンプを取得できます。

https://qiita.com/log0417/items/4afb31762bc5914d43a7

なお、仮想マシンの場合はサスペンドすることでVolatility3で調査可能なメモリダンプを取得することができます。VMwareの場合、.vmssと.vmemの2つのファイルが必要です。

もしSOARがあるのであれば、特定のアラートを検知したらメモリダンプを取得し、安全な場所に保管するというようなプレイブックを作成するという方法が取れそうです。

## メモリダンプの調査
本記事ではVolatility3を使います。

https://github.com/volatilityfoundation/volatility3

使用方法は一例として以下のような記事で紹介されています。

https://qiita.com/ninja400/items/f3dd1e6eb80fd5b39ba9

また以下の書籍もあります。こちらは大変よくまとまっておりおすすめです。

https://nextpublishing.jp/book/17165.html

ではディスクフォレンジックでは確認が難しい痕跡の例を見ていきましょう。

プロセスの親子関係を表示するwindows.pstreeの実行例が以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/3e2a291d-bb2a-35d6-27e4-c1930b2f02b7.png)

また、終了したプロセスも表示できるpsscanもあります。psscanの場合、マルウェアによって通常のプロセス一覧には表示されないプロセス[^1]も確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/396db454-3834-a8dc-2a9c-7bf1c7ae8870.png)

そしてネットワーク接続の状態を確認することも可能です。この出力はnetstatコマンドの結果と似ていますが、PIDやプロセス名まで出力されるのが特徴です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/529d0158-f504-5474-de69-33f3d00ba975.png)

他にもハンドルや特権の表示やメモリダンプからファイルを取り出すなどの操作が可能です。さらにマルウェアによってコードインジェクションされたプロセスを確認するmalfind[^2]もあります。これらはディスクフォレンジックで調査することができなかったり、困難だったりする情報です。メモリが取得できるのであれば取得した方が良いでしょう。

# Linuxのメモリフォレンジック
## Linuxのメモリダンプ
LiMEを使うことでメモリダンプを取得可能です。ただしLiMEは現在積極的にメンテナンスされていないとのことでした。仮想マシンであればサスペンドで代替できます。

https://github.com/504ensicsLabs/LiME

必要なパッケージを追加した後、LiMEをmakeします。

```
apt install linux-headers-6.1.0-21-amd64 gcc
git clone https://github.com/504ensicsLabs/LiME.git
cd LiME/src/
make
```
本検証ではmakeまで成功していますが、insmodコマンドが成功せず、解決できなかったため、仮想マシンのサスペンドにより代替しています。

```
# insmod lime-6.1.0-21-amd64.ko "test.mem format=mem format=lime"
insmod: ERROR: could not insert module lime-6.1.0-21-amd64.ko: Invalid parameters
```

# Linuxのメモリ調査
以下のIIJさんのリンクにもあるとおり、Voalatility3ではカーネルバージョンごとにプロファイルを作成する必要があります。この点が非常にやっかいで、調査対象が数台であればともかく、数十台になるとプロファイルを作成するのが困難になります。

https://www.iij.ad.jp/dev/report/iir/045/02.html

今回はDebianを新規にインストールしたものを使用してプロファイルを作成、メモリダンプの調査を行います。

デバッグシンボルが含まれるカーネルをダウンロードします。必ず調査対象のカーネルバージョンと一致するものを指定します。

```
apt install linux-image-6.1.0-21-amd64-dbg
```

上記ファイルは以下に保存されます。
/usr/lib/debug/vmlinux-6.1.0-21-amd64

dwarf2jsonのビルドを行うためにgolangをインストールします。

```
apt install golang
```

私の環境ではgitがインストールされていなかったため、インストールします。

```
apt install git
```

ソースコードをダウンロードしてコンパイルします。

```
git clone https://github.com/volatilityfoundation/dwarf2json.git
cd dwarf2json
go build
```

これでdwarf2jsonが使えるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/9d476bdd-f564-a22e-a8f9-644b56ee7bb8.png)

デバッグカーネルを元にプロファイルを作成します。この作業には私の環境（仮想マシンのメモリを16GB、CPUコア数を8まで増やした状態）で2分程度かかりました。
```
./dwarf2json linux --elf /usr/lib/debug/vmlinux-6.1.0-21-amd64 > output.json
```

作成したJSONファイルをVolatility3の-sオプションで指定します。
私の場合は仮想マシンのサスペンドファイルと同じフォルダに置いているため、「.」を指定しています。
```
vol -s . -f Debian-1fbfd5c7.vmem linux.pslist
```

以下の通りプロセスの一覧が表示できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/007682e4-d015-7821-925e-9a3db6927451.png)

残念ながらlinux.pstreeは私の環境では動作しませんでした。
Windowsではnetscanだったネットワーク接続の表示はlinux.sockstatになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/69eda590-aa61-7b4e-c709-7bdefe367982.png)

また、Windowsと同様にmalfindも利用可能です。ただし私の環境ではコードインジェクションされたプロセスがないのか、表示されませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549537/00bf1417-742f-b165-1f15-225f0c4ed733.png)

# メモリを取得することの有用性と課題
ここまで検証したとおり、メモリを取得することで様々な情報が取得でき、セキュリティインシデントの原因や影響の調査に役立つことが期待できます。一方で、メモリはその性質上、長期間データが保存されず、シャットダウンや再起動によって簡単にデータが消失します。仮にシャットダウンや再起動が行われなかったとしても、プロセスの終了によってもデータが消失する可能性があります。このためセキュリティインシデント発覚後、できるだけ早期に取得することが望ましいと言えます。

最初に述べた電源を入れたままにすべきかどうかについては、メモリを取得できるなら取得した方が良く、その場合はより多くの情報が得られる可能性があるといえます。またメモリにしか存在しないマルウェア（ファイルレスマルウェア）もあります。
ではメモリがないとセキュリティインシデントの調査ができないかというとそんなことはありません。フォレンジック調査というのはそもそも不完全なデータを元に調査することが多く、個人的な経験からもメモリダンプがないと手も足も出ないというケースはほぼありません。そもそも調査開始時点でシャットダウンされているというケースは非常に多いです。

ここまでフォレンジック調査の観点から述べてきましたが、インシデントレスポンスという観点で考えた時に、電源を切るという選択肢は決して間違っていないとも思います。ランサムウェアがすでに動作しているというケースでは、すべてのファイルが暗号化される前に電源を落としてしまうことで一部のデータを守るという判断はあり得ます。（気づいたときには手遅れというケースも多いですが）
また、攻撃者がまだ攻撃を継続しているという場合は、通常であればネットワークを切断して締め出すことが可能ですが、電源を落とすことで証拠隠滅をさせないという判断もあり得ます。

# ネットワーク遮断の是非について
電源を入れたままにすべきか問題に関連し、ネットワークを遮断すべきかについても考察します。

一般的にセキュリティインシデントが発生した場合、ネットワークから切り離すという方法がとられます。最近ではEDRによる論理遮断も可能です。他にも例えば隔離されたVLANに接続させるという方法もあります。
いずれの方法も攻撃者と通信させないことを目的としています。これにより遠隔から操作されることを防ぎ、新たな侵入を防ぐことが可能です。
一方で、海外の書籍やトレーニングにおいては、先にスコープを特定するように書かれている場合があります。これの意図するところは、侵害されているマシンをすべて特定することを優先すべきということのようです。侵害されているマシンが特定できていればOSの再インストールを行いマルウェアを駆除できますが、この特定に漏れがあると、OSの再インストールを行っていないマシンから新たに侵入が再開されてしまうということです。そのため、あえて攻撃者を泳がせ、すべての侵害されたマシンを特定してからネットワークを遮断した方が再発しないということです。

ではどちらの対応が望ましいのでしょうか？
この判断は非常に悩ましいです。攻撃者を泳がせてしまうと、新たな感染拡大や情報漏洩が発生してしまうかもしれません。一方でモグラたたきになってしまうのもインシデント対応の長期化を招きます。私が過去に対応したセキュリティインシデントでは、すべてネットワークを遮断する選択を取っていました。やはりさらなる情報漏洩のリスクがある状況を放置することは厳しいという判断です。

ネットワークを遮断する選択をする場合、モグラたたきになってしまうリスクを踏まえた対応が必要になります。可能なら侵害された可能性が少しでもあるマシンはすべてOS再インストールをした方が良いでしょう。場合によっては途中経路のスイッチやルータも侵害されている可能性がある点にも注意が必要です。

あえてネットワークを遮断しない選択をする場合、攻撃者の動きを追跡できるように追加のログを取得する設定に変更すると良いでしょう。WindowsであればSysmon、Linuxであればプロセスアカウンティングを使うと実行されたコマンドが確認できます。可能ならこれらの設定は侵害される前に行っておき、ログは別のサーバに飛ばすのがベストです。そして攻撃者が侵入したマシンをすべて列挙できた段階で一気にネットワークを切断し、侵害されたマシンをすべてクリーンにします。
なおこの対応はサイバー攻撃に精通している必要があるため、インシデントレスポンスの専門家が行うか、監修した状態で行ってください。

# まとめ
本記事ではメモリダンプからどのような情報が得られるかについて述べました。
電源を入れたままにすべきか、それとも電源を落とすべきかについては以下の点を考慮する必要があると考えられます。どちらも一長一短であり、セキュリティインシデントの内容、状況、ビジネスへの影響などを総合的に考慮する必要があると考えます。
・電源を入れたままメモリダンプを取得することにより、より多くの情報が得られ、セキュリティインシデントの調査に有用となる可能性がある
・メモリダンプの取得は可能な限り早急に行った方が良い
・電源を落とすことにより、ランサムウェアによる暗号化を途中で止められる可能性がある
・電源を落とすことにより、攻撃者による証拠隠滅を防げる可能性がある
・メモリダンプがなくてもフォレンジック調査は十分可能である
※上記考慮点は一例であり、状況次第で他にも考えられます。

また、ネットワークを切断すべきかどうかについても考察しました。これにはメリットもデメリットもありますが、いずれの方法であっても再発しないように注意が必要です。

[^1]: DKOMと呼ばれる手法がルートキットによって使われる。
https://en.wikipedia.org/wiki/Direct_kernel_object_manipulation
[^2]: malfindという名前からマルウェアを探す機能と誤解されがちだが、正確にはコードインジェクションされたプロセスの表示です。正規のプログラムでもコードインジェクションされる場合があるため、malfindで表示されるプログラムがすべてマルウェアによって侵害されているわけではありません。またたびたび誤検知も発生します。