こんにちは!セキュリティの世界へようこそ。インシデントレスポンスやデジタルフォレンジックの世界、なんだか映画みたいでかっこいいけれど、専門用語が多くて難しそう……そんな風に感じていませんか?
大丈夫です!今回は、サーバーやパソコンの「記憶の断片」から、こっそり隠されたサイバー攻撃の痕跡を見つけ出す「メモリフォレンジック」という技術について、一緒に一歩ずつ優しく学んでいきましょう。
今日の主役は、Windowsの心臓部とも言える「レジストリ」と、それをメモリ(RAM)から暴き出すテクニックです。それでは、身近な例えからスタートしますね!
—
1. 家の合鍵と「レジストリの永続化」の切ない関係
突然ですが、あなたの家を想像してみてください。泥棒が家に侵入して、一度は追い払うことができました。でも、もしその泥棒が、いつの間にか「勝手に合い鍵を作って、こっそり玄関の予備の鍵穴に差し込んでいた」としたらどうでしょう?
鍵をかけ直しても、その裏口の合い鍵が存在している限り、泥棒はいつでもあなたの家に自由に出入りできてしまいますよね。
サイバーセキュリティの世界でもこれと全く同じことが起きます。攻撃者がサーバーに侵入したあと、パソコンを再起動しても消えないように「次も自動で起動してね」と仕込んでいく仕組みを「永続化メカニズム(Persistence)」と呼びます。
そして、Windowsが「パソコンが起動したら、このアプリを自動で動かしてね」という設定をこっそりメモしておく場所が、Windowsの頭脳である「レジストリ」なんです。特に有名なのがRunキーと呼ばれる自動実行リストですね。
攻撃者は、このレジストリをこっそり書き換えて「合鍵」を作ります。厄介なことに、彼らは痕跡を消すために、ディスク(ハードディスクやSSD)上のレジストリファイルを隠したり、巧みに書き換えたりします。
ここで私たちが使うのが、電源を切ったときに消えてしまうはずの揮発性メモリ(RAM)を丸ごと保存した「メモリダンプ」です。ディスクが隠蔽されても、犯行当時の生きたメモリの中には、書き換えられたレジストリの「生データ」がそのまま残っていることが多いのです。ここに、私たちSOC(セキュリティオペレーションセンター)アナリストの勝機があります!
—
2. メモリからレジストリハイブを救い出す
「メモリダンプからレジストリを探すって、どうやるの?」って思いますよね。
実は、Windowsのレジストリは、メモリ上では「ハイブ(Hive)」と呼ばれる固まりのデータとして存在しています。SYSTEMハイブやSOFTWAREハイブといった名前を聞いたことがあるかもしれません。
これらをメモリ上から見つけ出し、私たちの手元にファイルとして「抽出(Dump)」してオフラインでじっくり解析するのが、今回のメインテーマです。
現場では、オープンソースの強力な解析ツールである Volatility 3(ボラティリティ・スリー)というフレームワークをよく使います。呪文のようなコマンドを打つように見えますが、やっていることは「メモリという巨大なアルバムの中から、レジストリの写真を探して切り抜く」作業です。
実際に、メモリダンプからレジストリハイブのありか(オフセット)をリストアップし、ファイルとして抽出する際の流れをコマンドの例で見てみましょう。
# ボラティリティ3を使って、メモリダンプからレジストリハイブのリストをスキャンする
# (windows.registry.hivelist.HiveListプラグインを使用します)
python3 vol.py -f memory_dump.raw windows.registry.hivelist.HiveList
このコマンドを実行すると、メモリ上のどこにどのレジストリハイブが存在しているかの住所(オフセットアドレス)がズラリと表示されます。怪しいハイブを見つけたら、次はその中身を私たちの手元にファイルとして抜き出します。
# 特定のオフセットアドレスを指定して、レジストリハイブをファイルとしてディスクに抽出する
python3 vol.py -f memory_dump.raw windows.registry.dumpregistry --offset 0x8a00002b1010
これで、敵が改ざんした「当時のレジストリの姿」をそっくりそのまま手に入れました!
—
3. オフラインで「合鍵」の痕跡を暴く!
抽出したレジストリハイブを、今度はオフライン環境(安全な分析用のパソコン)でじっくりと覗いてみましょう。
攻撃者がよく狙う代表的な永続化のポイントは以下の2つです。
1. Run および RunOnce キー
- パス例:
Microsoft\Windows\CurrentVersion\Run - 意味: ユーザーがログインした瞬間に、指定したプログラムを自動実行させるための「一番人気の合鍵」です。ここに怪しげなスクリプトや、見覚えのない実行ファイルのパスが登録されていないかをチェックします。
2. Windowsサービスの設定
- パス例:
CurrentControlSet\Services - 意味: 画面に見えない裏側で24時間こっそり動き続ける「バックグラウンドワーカー」の設定です。攻撃者は、マルウェアを正規のサービスに見せかけてここに登録し、パソコンが起動した瞬間から裏で悪さをさせようとします。
ここで、Pythonなどのスクリプトを使って、抽出したレジストリハイブから自動的に怪しいRunキーのエントリをスキャンする簡易的なコードのイメージをご紹介します。実務では python-registry などのライブラリを使って解析を自動化することが多いです。
from Registry import Registry
import sys
def check_run_keys(hive_path):
"""
抽出したSOFTWAREハイブからRunキーの登録情報を読み取り、
怪しい自動実行プログラムがないかをチェックするサンプルスクリプト
"""
try:
# レジストリハイブファイルを読み込む
reg = Registry.Registry(hive_path)
# Runキーがよく格納されているパスを指定
run_path = "Microsoft\\Windows\\CurrentVersion\\Run"
print(f"[*] 検査中: {run_path}")
key = reg.open(run_path)
# 登録されている値(値の名前と、実行されるパス)をすべてループで確認
for value in key.values():
print(f" - 項目名: {value.name()}")
print(f" 実行パス: {value.value()}")
# 簡易的な検知ロジック(例:AppData配下や不審な拡張子が含まれていないか)
if "AppData" in value.value() or "Temp" in value.value():
print(" [!] 警告: ユーザーのテンポラリフォルダから実行される不審な自動起動を発見しました!")
except Exception as e:
print(f"[-] エラーが発生しました: {e}", file=sys.stderr)
if __name__ == "__main__":
# 使用例: python parse_hive.py SOFTWARE_hive_dumped
if len(sys.argv) > 1:
check_run_keys(sys.argv[1])
else:
print("使い方: python parse_hive.py <ハイブファイルのパス>")
このように、コードや専用ツールを使って「いつ、誰が、どのプログラムを自動実行するように仕込んだか」を一つひとつ紐解いていくのが、メモリフォレンジックの醍醐味です。
—
一歩ずつ、確実に対策を進めましょう!
いかがでしたでしょうか?
「メモリからレジストリを抽出する」というと、なんだかすごく難しくて自分には無理だと思ってしまうかもしれませんが、基本の仕組みは「家の裏口の合い鍵を探す防犯チェック」と同じです。
1. メモリという揮発性の証拠を確保する
2. ツールを使ってレジストリハイブをファイルとして救い出す
3. オフラインで自動実行設定(Runキーやサービス)の不正な書き換えを暴く
この流れを頭の片隅に置いておくだけで、インシデントが起きたときの視界がパッと明るくなります。セキュリティの道は一日にして成らず。まずはこうした基礎的な概念とツールの使い方に触れながら、少しずつスキルを磨いていきましょうね。
それでは、また次回のセキュリティ解説でお会いしましょう!
コメント