【入門編】 メモリフォレンジックにおけるカーネルオブジェクトの不整合解析 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

皆さん、こんにちは!セキュリティの世界へようこそ。インシデントレスポンスやデジタルフォレンジックの現場を長年歩んできた私ですが、今日は少しディープで、けれどとってもエキサイティングな「メモリフォレンジック」の世界にご案内しますね。

「メモリフォレンジック」って聞くと、何だか映画のハッカーみたいで難しそう…って思いますよね。でも大丈夫です!一歩ずつ、身近な例えを交えながら優しく紐解いていきますので、安心してついてきてくださいね。

今日のお題は「DKOM(Direct Kernel Object Manipulation)によるプロセス隠蔽と、カーネルオブジェクトの不整合解析」です。
名前を聞くだけで頭が痛くなりそうですが、要するに「悪いやつらがパソコンの裏側でこっそり隠れんぼしているのを、どうやって見つけ出すか」というお話です。

—

1. 家の鍵と「住民名簿」の例えで理解するプロセス隠蔽

まずは、私たちが普段使っているパソコンの仕組みを、一つの「マンション」に例えてみましょう。

パソコンのメモリ(RAM)という巨大なマンションには、たくさんの「お部屋(プロセス)」があります。ブラウザだったり、エディターだったり、裏で動いているセキュリティソフトだったりですね。そして、管理人室には「住民名簿(プロセスリスト)」というものがあって、「今、このマンションには誰が住んでいて、どの部屋にいるのか」が一覧で管理されています。

通常のプログラムは、新しく入居するときに「ここに住みます!」と管理人さんにちゃんと届け出を出します。だから、住民名簿を見れば一目瞭然ですよね。

悪い泥棒の手口:DKOM(ダイレクト・カーネル・オブジェクト・マニピュレーション)

ところが、悪意ある攻撃者(マルウェア)は、管理人さんに無断でこっそりマンションに居座ろうとします。しかも、住民名簿の名前をマジックで消してしまうんです!

これが DKOM というテクニックです。
彼らは、OSの心臓部(カーネル)にあるデータ構造を直接書き換えて、管理人室の「住民名簿(ActiveProcessLinksなどのリスト)」から自分の名前の載ったカードを外しちゃいます。

管理人室の住民名簿を見ても、「あれ?この部屋は空き部屋だな」となります。タスクマネージャーを開いても、その怪しいプログラムは表示されません。これが「プロセスの隠蔽」です。巧妙でずる賢い手口ですよね。

—

2. でも、管理人室の「裏帳簿」には痕跡が残る!

「じゃあ、完全に姿を消されてしまって、私たちにはもう見つけられないの?」と思いますよね。ここからがフォレンジック・アナリストの腕の見せ所です!

実は、優秀な泥棒であっても、足跡を完全に消し去ることはできません。なぜなら、マンションの管理には「住民名簿」以外にも、別の書類が存在するからです。

具体的には、Windowsのカーネル内には、プロセスを管理するために以下のような複数の異なるデータ構造(オブジェクト)が存在しています。

  • ActiveProcessLinks(住民名簿のリンク): タスクマネージャーなどが参照するリスト。ここから外されると名前が消えます。
  • EPROCESS(部屋の契約書・実体データ): プロセスそのものが動くために必要なメモリ上の実体データ。名簿から名前が消されても、この契約書自体はメモリのどこかにポツンと残されていることが多いのです。
  • HandleTable(鍵の管理台帳): そのプロセスがどのファイルやネットワークの鍵を持っているかを記録した台帳。

攻撃者は「住民名簿」のリンクをプチッと切ることで自分を隠しますが、「部屋の契約書(EPROCESS)」や「鍵の管理台帳(HandleTable)」まで完璧に同期させて消し去るのは、実はものすごく難しいのです。

この「あちこちの書類でジグソーパズルのピースが噛み合っていない状態」を、私たちは「カーネルオブジェクトの不整合」と呼んでいます。これを見つけ出すのが、メモリフォレンジックの醍醐味なんです!

—

3. 実際のメモリ解析:不整合を見つけるPython風擬似コード

それでは、現場のエンジニアやアナリストが、メモリダンプファイルからどのようにこの不整合をあぶり出しているのか、イメージしやすいようにシンプルなコード例(Volatilyフレームワークなどを模した擬似スクリプト)で見てみましょう。

実務ではPythonを使ってメモリ解析ツールを拡張することがよくあります。以下のコードを見てみてください。

# メモリフォレンジックにおけるプロセス不整合検知の概念実習スクリプト
# ※実務でよく使われるVolatility等のフレームワークの内部動作を模したサンプルです。

class MemoryAnalyzer:
    def __init__(self, memory_dump):
        self.dump = memory_dump

    def scan_for_hidden_processes(self):
        print("[*] メモリダンプからEPROCESS(プロセスの実体)の総スキャンを開始します...")
        
        # 1. メモリ全体から「プロセス実体(EPROCESS構造体)」の目印(シグネチャ)を総当たりで探す
        eprocess_list = self.find_all_eprocess_structures()
        
        # 2. タスクマネージャーが見ている通常の「住民名簿(ActiveProcessLinks)」のリストを取得する
        visible_process_pids = self.get_active_process_links_pids()
        
        print(f"[*] 発見されたプロセスの実体(EPROCESS数): {len(eprocess_list)}")
        print(f"[*] 住民名簿に載っているプロセス数: {len(visible_process_pids)}")
        
        print("\n--- 不整合チェック(隠蔽プロセスの捜索) ---")
        
        # 3. 実体はあるのに、住民名簿に名前がないものをあぶり出す!
        for proc in eprocess_list:
            pid = proc['pid']
            name = proc['name']
            
            if pid not in visible_process_pids:
                print(f"[!] 【警告】不整合を検知しました!")
                print(f"    - 隠蔽された可能性のあるPID: {pid}")
                print(f"    - プロセス名: {name}")
                print(f"    - 判定理由: EPROCESS実体が存在しますが、標準のリンクから外されています(DKOMの疑い)\n")

    def find_all_eprocess_structures(self):
        # ダミーの検索結果を返す関数(実際はメモリのプールタグなどをスキャンします)
        return [
            {'pid': 4, 'name': 'System'},
            {'pid': 644, 'name': 'svchost.exe'},
            {'pid': 1337, 'name': 'evil_hidden_malware.exe'} # ← 隠されているプロセス!
        ]

    def get_active_process_links_pids(self):
        # 住民名簿に登録されているPIDのリスト(悪意あるプロセスはここから外されている)
        return [4, 644]

# 解析の実行
if __name__ == "__main__":
    analyzer = MemoryAnalyzer("C:\\investigation\\ram_dump.raw")
    analyzer.scan_for_hidden_processes()

このコードのポイントは、「名簿(ActiveProcessLinks)を見るのではなく、マンションの部屋の契約書(EPROCESS)を直接しらみつぶしに探して、名簿と突き合わせる」というアプローチをとっている点です。

表向きのリストをどれだけ綺麗に改ざんしても、メモリという物理的な空間にデータが残っている限り、この「突き合わせ(クロスビュー解析)」を行えば、隠された不正なプロセスをポロリと見つけ出すことができるのです。

—

4. 日々の開発やインフラ運用に活かせる教訓

「うちはフォレンジックエンジニアじゃないから関係ないよ」と思われるかもしれませんが、実はこうしたサイバー攻撃のからくりを知ることは、日々の開発やインフラ構築にも大きなヒントを与えてくれます。

1. 「目に見えるもの」だけを信用しない
セキュリティ対策でも、OSのタスクマネージャーやダッシュボードに「異常なし」と出ているからといって、すべてを信じ込んではいけません。ログの監視や、外部の視点からの監査(EDRの導入など)を組み合わせることが大切です。
2. ログの整合性を担保する
アプリケーション開発においても、データベースのマスターデータと、キャッシュやログとの間でデータが食い違っていないか(不整合がないか)を定期的にチェックする仕組み(整合性チェック)を作っておくことが、不正検知やバグの早期発見につながります。

—

まとめ

今回は、DKOMによるプロセス隠蔽と、カーネルオブジェクトの不整合解析という、ちょっとコアでディープなテーマを解説しました。

難解なセキュリティ用語も、「家の鍵」「住民名簿」「部屋の契約書」という例えに置き換えてみると、攻撃者がやっていること、そして私たちがどうやってそれを見つけ出すのかが、スッと頭に入ってきたのではないでしょうか?

セキュリティの世界は奥が深く、攻撃者とのイタチごっこですが、こうした基礎的な仕組みの理解を積み重ねていくことで、確実に対応スキルが身についていきます。焦らず、一歩ずつ知識を広げていきましょう!

それでは、また次回のセキュリティ解説でお会いしましょう。安全なデジタルライフを!

コメント

タイトルとURLをコピーしました