ローカルLLMはフォレンジック調査官の夢を見るか?
AIデジタルフォレンジックハーネス「FORENSIA」の設計思想について。
関連スライド(Speaker Deck) FORENSIA: ローカルLLMフォレンジックハーネス
はじめに
不思議なことに、セキュリティインシデントの調査依頼というものは よく金曜日にやってきます (あるいは長期休みの前に)。
望んでセキュリティインシデントを起こす組織などありませんが、おそらく以下のような流れでそうなってしまうことが多いのではないかと考えています。
- 土日の深夜、会社に人がいない時間帯を狙って攻撃者がシステムへ侵入します。
- 月曜日、担当者がシステムの異変に気づきますが、確証が持てず一晩寝かせることになります。
- 火曜日、朝の会議で「システムの様子がおかしいかもしれない」と共有され、社内調査が始まります。
- 水曜日の終わり頃になって、ようやくただの障害ではなくインシデントらしいと諦めがつきます。
- 木曜日、セキュリティベンダーへ相談することになり、あなたの会社にも連絡が来ますが、技術者との間にはレイテンシがあります。
- 金曜日の朝、相談内容がようやくあなたのところまで届きますが、不思議なことに月曜日には報告書を送付する話になっています。調査対象のデータはまだ届いていません。
システムは現在進行形で脅威に晒されています。一刻も早く状況を把握し、原因究明と対策を進めなければなりません。
一方で、インシデント対応には、調査だけでなく封じ込め、復旧、関係者との調整などの作業も数多くあります。 限られた人員を調査作業だけに集中させれば、別の重要な対応が遅れます。
とはいえ、週末も平日も休まず働き続ければ、疲労によって判断の質が落ちることも道理でしょう。
今判断すべきことに集中できるよう、証拠の整理や仮説検証を、眠らず、疲れず、淡々と進めてくれる誰かはいないでしょうか。
あなたの代わりに週末も調査を続けてくれる誰か……
いません。
AIの友達 以外には。
FORENSIA について
上記の背景から FORENSIA を作成しました。
調査対象機器から抽出済みのアーティファクトを読み込んで、ローカルLLMによる調査仮説の生成と検証、レポートの継続的な更新を自動で行います。
図. 調査進捗などを確認できるダッシュボード。
図. 調査結果のレポート
本記事では、このソフトウェアの設計思想について説明します。
私たちの戦場
近年、AIの進化は凄まじいものがあります。
AnthropicもOpenAIも、フロンティアAI と呼ばれるほどの優れたモデルを生み出しています。
ですが、こうしたモデルをセキュリティインシデント調査へそのまま持ち込めないケースは少なくありません。なぜか?
攻撃者が狙うのは、重要で機微な情報を扱う、侵害する価値のあるシステムです。
被害を受け、ただでさえナーバスになっている被害者に対して、「侵害を受けたシステムの情報を外部に送っていいですか?」なんて口が裂けても言えません。
そうでなくとも、防衛やエネルギー、金融など法律によって統制を受けている領域など、保持している情報によっては取り扱いに細心の注意を払わなくてはなりません。
こうしたケースでは、マネージドの生成AIプラットフォーム*1 はもちろん、クラウド基盤へデータをアップロードする*2 ことも難しいです。調査に使った機器を物理破壊して証明書を提出しないといけないケースすらあるのですから。
そもそも、ネットワークにつながった機器上で処理すること自体が、新たなリスクを生みます。侵害された機器を調査するということは、その環境で使われたマルウェアや攻撃コードの正体がわからないままそれを扱うということです。無闇矢鱈に動かして放置していれば、次に画面をみたときにはランサムウェアの脅迫文が表示されているかもしれません。
あなたがインシデントを見ているとき、インシデントもまた、あなたを見ています。
*1 エンタープライズ契約なら学習利用がオプトアウトされているから問題ない、と考えるのは自由ですが、契約というものは反故にするメリットがデメリットを上回れば、必ずしも守られるとは限りません。それが実際に行われるかどうかではなく、そうなる可能性があることを念頭に置く必要があります。
*2 同上。そもそも自分の手元にないデータが正しく扱われていることを、利用者側がどう保証するのでしょうか。それを相手に納得感のある説明ができるのならよいのですが。自身が完全にコントロールできない場所へ機微なデータを置くことは、二次インシデントと変わらないと私は考えます。
設計原則
上記の理由から、このプロジェクトで満たさなければならない要件を定めました。
1. 孤独に戦う
ソフトウェアが、完全にオフラインでも動作し続けることを重視します。ネットワークに繋がれたシステムを週末放置した場合、月曜の朝に見るのはランサムウェアの脅迫画面かもしれません。
2. LLMに過剰な期待をしない
可能なら巨大なモデルを使いたい。しかし、それを動かすための計算機は高価です。常時フォレンジック調査の依頼を受けるような専門組織ならともかく、ときどき調査を行う企業CSIRTのために、何千万円、何億円という設備投資が承認されるとは考えにくいです。
現実的には、消耗品費や小規模な設備予算で購入できる程度の調査機材です。新品でも5-10万円のGPU、個人なら中古で2-3万円に収まるもの。その上で動かせるのは、せいぜい4Bから8B前後の小さなモデルになるでしょう。
「これ調査しといて」とポンとログを渡したところで、彼らは厳格なプロンプトを与えなければ指示を曲解します。長い文章を一度に読ませれば、重要な情報を落とします。そのうえひどく健忘症で、少し前にやりとりしたことも覚えていられません。
なので、LLMに任せるのは「仮説の生成」「検証方針の提案」「レポートの執筆」など、静的に組むことの難しいタスクです。それ以外の関連データの検索や選定などはハーネス側のアーキテクチャで機械的に処理してしまいましょう。
昨今では生成AIに使われっぱなしの人類ですが、数B程度のモデルよりは人間様の方が多少動きが鈍く、多少賢いです。万物の霊長としての誇りを取り戻し、彼らを歯車としてこき使いましょう。
3. 時間は湯水のごとく使う
一度の実行で完璧な結論を出す必要はありません。
人手によるデジタルフォレンジックでもそんなことはしないのですから、AIを使う場合でも同じです。ひとつの仮説に対して何度も推論を重ね、その過程や記憶を可観測性を保ったまま記録します。これによって、ある証跡からなぜその結論に至ったのかをあとから人間/LLMが理解できるようにします。
報告書も最後にまとめて書くのではなく、調査の進行に合わせて継続的に更新します。
ただし、時間をじゃぶじゃぶ使うのと永遠に終わらないのはまったく違います。人手によるフォレンジックだって予算や時間など、どこかでケリをつけないといけないのですから。
複数の仮説を保持し、優先順位を更新しながら、反復的に調査結果をブラッシュアップしていくのが望ましいでしょう。
アーキテクチャ
FORENSIAの中心にあるのは、人手によるフォレンジックでも重要となる、仮説と検証の繰り返しです。
処理の流れを単純化すると、次のようになります。
- 証跡を取り込み、調査可能な形式へ正規化する
- 定義ルールによる検知を起点に、仮説を生成する
- 次に検証すべき仮説を選ぶ
- 実際の証拠を検索し、仮説を検証する
- 結果を判定・記録し、レポートへ反映する
- 未解決の問いを次の調査サイクルへ戻す
このループでは、生成や解釈のように言語モデルが有効な処理だけをLLMに任せます。一方、証拠の検索、優先順位の計算、状態遷移、検証結果の保存など、決定論的に扱える処理はコード側で実行します。
ただし、このループを回すだけでは、弱いLLMはすぐに迷子になってしまいます。
モデルに内包された乏しい知識に基づく根拠のない仮説を事実として扱ったり、文脈を忘れて同じ推論を何度も何度も繰り返すでしょう。
そこで、調査ループを成立させる仕組みとして、次の3本柱を立てました。
- 証拠に束縛された仮説検証
- 構造化された記憶
- 調査過程の監査性
1. 証拠に束縛された仮説検証
LLMが生成した仮説や判定は、それ自体では調査結果になりません。
「このログオンは横展開かもしれない」「このプロセスは攻撃者が実行した可能性がある」といった説明は、どれほどもっともらしくても、確認すべき仮説にすぎません。
そのため、LLMの出力をそのまま事実として保存せず、実際の証拠を検索し、その結果と照合してから状態を更新します。
仮説の判定は、確証(confirmed)、反証(refuted)、判定不能(inconclusive)、検証不能(untestable)、新たな手がかりの発見(newlead)の5状態として管理します。ただし、LLMがconfirmedと答えただけで確定するわけではありません。参照した証拠、証拠同士の独立性、矛盾、そしてその活動を観測できる状態だったかをコード側でも確認します。
証拠がない、という証拠
証拠の検索結果が0件だったとしても、それだけで「その活動がなかった」とは言えません。
LLMが生成した検索クエリが間違っていた、本来証拠はあったが攻撃者によって削除・改ざんされた、そもそも調査対象機器で、その証拠が記録される設定をされていなかった、などさまざまなケースがあるからです。
その証拠が取得されているか、検索対象期間内にあるか、など複数の要素を加味しても存在しなかった場合に初めて、反証の可能性を考慮します。
検知ルールに調査意図を宣言する
仮説の生成をLLMの自由な発想に丸投げしません。
ルールには検知条件だけでなく、何を検知したのか、なぜ重要なのか、その結果として次に何を調べるべきかなどを自然言語で宣言します。条件に一致したという結果だけを渡しても、LLMには、なぜそれを選定したのかが分からないためです。
別にリアルタイムで検知する必要がないのだから、こうした情報を入れ込んでもいいでしょう。
ルール作成者のバイアスが入り込んでしまうことがデメリットですが、モデル知識に起因する頓珍漢なハルシネーションよりは多少マシです。ルールに含まれない背景知識や追加の着眼点は、後述するKnowledgeから補います。
id: windows-security-4624-rdp-logon
query: SELECT ... FROM evtx_events WHERE event_id = 4624 AND logon_type = '10'
finding:
title: RDP logon for {target_user}
hypotheses:
- id: lateral_movement_via_rdp
description: RDP logon from {src_ip} to {computer} may indicate lateral movement
confirm_when: { co_observed_event_ids: [4624], same_host: true, within_minutes: 5 }
refute_when: { zero_rows: true }
follow_up_questions:
- Was this RDP session followed by process execution (4688) on {computer}?
correlate_with:
- { event_ids: [4625, 4768, 4776], rationale: preceding failures or kerberos/NTLM auth }2. 構造化された記憶
AIハーネスで重要なのは、文脈の維持です。FORENSIAでは、Case State / Trace State / Working State の3層で記憶を管理しています。
Case State
現在のケースに何が存在するかを表す状態です。長期記憶。
Single Source of Truthとして取り込んだ証跡に加えて、検知ルールによる発見、生成した仮説、仮説と証拠の対応関係、タスク、レポートの進捗状況などを保存します。
Trace State
なぜ現在の状態に至ったかを表す状態です。追跡記憶。人間にはない概念ですが。
各ステップの入出力、判断、状態遷移、次の調査対象を選んだスコアの内訳などを保存します。
これがあることによって、なぜその結論に至ったかの推論過程をあとから確認することができます。
Working State
現在の処理に必要な文脈だけをLLMへ渡すための状態です。作業記憶。
LLMのセッションごとに揮発してしまう短期記憶と長期記憶の中間といった感じです。
Case StateとTrace Stateから、確認済みの事実、主要なイベント、関連する仮説、未解決の問いなどを抽出し、LLMが扱える大きさへ整理します。すべての証拠や過去の処理を毎回渡すのではなく、その時点の役割と調査対象に必要な情報だけを選んでコンテキストを再構成します。
未確定の情報は仮説ごとに隔離し、別の仮説へ混入させません。 また、これはLLMの文脈を維持するための射影であって、証拠の正本にはなり得ません。
Knowledge
上記3層のStateとは違いますが、RAG的に使用する外付けの記憶です。OKFフォーマットで管理します。
自然言語のほうがHuman-Readableでアップデートもしやすく、集めた文書やWebページをもとにLLMで分類、再整理することも容易だからです。
もちろん、公知の情報であればマネージドのAIサービスを使ってもなんの問題もありませんので、別で管理できる情報はガンガン集めて育てて、必要なときにコピればよいのです。
---
type: knowledge
title: Short title
description: One-line summary. Used for index display and relevance scoring.
tags: [windows, eventlog, logon]
timestamp: 2026-07-13
---
# Body (Markdown)
## Section heading
Sections are selected and injected individually.どの資料をコンテキストへ含めるかは、タグで候補を絞り、タイトル・説明・本文からの関連度でスコアリングして渡します。同じ入力からは同じ資料が選択されるため、なぜLLMがその資料を用いて推論したかを説明できます。
注入したナレッジは該当部分をタグ付けし、命令ではなく参考資料として扱うようプロンプト上の権威境界を明示します。
3. 調査過程の監査性
状態や履歴を保存するだけでは、調査結果を監査可能にしたことにはなりません。結論、解釈、観測、証拠の関係を明示し、レポートから原本まで遡れる必要があります。
どの証拠を見て、どの仮説を検証し、なぜその判定に至り、最終的にレポートへ何を書いたのかを記録します。重要なのは、AIが正しいと信じることではなく、人間があとから正しさを検証できることです。
結論から証拠まで遡れるようにする
調査中に扱う情報は、役割ごとに分けて管理します。
- Evidence:EVTXやMFTなどから正規化された証拠
- Finding:Evidenceから観測された事象
- Hypothesis:これから検証すべき解釈
- Claim:レポートで読者に提示する主張
- Gap:判断に必要な証拠や情報の不足
これらを混ぜてしまうと、まだ検証していない仮説が事実として記憶されたり、単一のログが過度に一般化されて報告書へ書かれたりします。
レポートも調査状態の一部として扱う
レポートは、調査の最後にLLMへ一括生成させる文章ではありません。
表や一覧のように決まった形式で表現できる部分はコード側で生成し、説明や解釈が必要な部分だけをLLMが段落単位で執筆します。各セクションが参照した証拠と、文章中の重要なClaimも記録します。
調査が進んで新しい事実が確定すれば、関連するセクションを更新します。まだ説明できない部分は無理に埋めず、Gapとして次の調査サイクルへ戻します。
証拠は消さず、扱いを状態として残す
分析上、除外すべきデータは(当然ですが)原本には手を加えず、別で管理します。
例えば、異常なタイムスタンプを分析範囲から除外する場合も、その値自体は残したまま、除外した理由を記録します。存在しなかったことにしてしまうと、あとから別の証跡が発見された際に辿れなくなってしまうため、今回はこの理由で分析や表示の対象外とした、という形で記録します。
設計上の選択
ソフトウェアの命名
Forensics-AI で FORENSIA でいいか~と適当に命名しました。
あとは、学生の頃作っていたゲーム名が amnesia とか insomnia とか、ラテン語由来の「状態を表す接尾辞」がついていたので、フォレンジックジャンキー感があっていいかなとぼんやり。
既存ツールとの差異
フォレンジックをLLMで自動化する試みはいくつかあり、有名なのは Mecha Hayabusa などでしょうか。これらは既存の解析ツールをAIで操作し、調査の迅速化を図るものが多いですが、それとはコンセプトが少し違います。
FORENSIAがチャレンジしているのは、処理結果から次の問いを作り、必要な証拠を選び、未解決点を次のサイクルへ繋ぎながら調査を継続するという点です。要は、人間の調査手順を細かく分解して実装するPoCのようなもので、どのようなアーキテクチャにすればよいか、というアイデアを形にしたものです。
また、本来のフォレンジックは必ずしもログのような扱いやすい形で証跡が残存しているわけではなく、欠損・改ざんされている可能性のあるたくさんのごちゃごちゃした証跡を組み合わせて仮説と検証を繰り返すという性質のものなので、最終形はそれを目指している、というのもあります。
既存の検知ルールを流用しない理由
Sigma が最も豊富なルールベースだと思いますが、前述の通り、FORENSIAでは単なる検知ルールではなく、調査の意図や仮説のヒントをルール内に記載しています。
過去の資産を使えるほうがより良いのだとは思いますが、これもナレッジと同じく使いながら育てていく性質のものかなというふうに考えています。
内部でTool Callingをしない理由
これ疎結合にするという観点で自分でも結構迷ったのですが、バックエンドで動かすモデルの選択肢を狭めてしまう可能性があると考えて採用しませんでした。
現時点では、しょぼいPCで動かすにはgemma-4がとても優秀なのですが、それでもTool Callingを安定して使えるかというと非常に怪しいです。
また、「別の良いモデルが出たので乗り換えます」とか、「うちの機器ならKimi-K3余裕で動きますよ」とかそういう場合にロジックを見直さないといけないというのは本末転倒感があるなあと。
自己改善機能を実装しない理由
Hermes Agent のように、間違えた文脈や推論を保存し、次の推論から役立てることができればよいのですが、しょぼモデルにはむりでした。むしろハルシネーションの源になるので、つけるとしてもOptionalにすると思います。
今後の展望
FORENSIAは、まだ開発初期段階にあります。
現時点で目指しているのは、すぐに実務を代替できるほど高精度な調査ツールではありません。まずは、静的なルールや決め打ちの処理だけでは扱いにくい部分を、弱いローカルLLMでどのようにアーキテクチャで補えるか、ということを確かめています。
調査対象を広げる
現在対応している主な証跡は、EVTX、MFT、Prefetchです。いずれも自作のパーサをそのまま利用し、比較的統一した形式で取り込めるため、最初の対象として選びました。
今後は、ブラウザ記録やレジストリなど、より雑多な証跡も取り入れたいと考えています。ただし、すべてを網羅することが目的ではありません。特に、レジストリはキーごとに構造や意味が異なるため、正直、全部やってられません。推論を何度も重ねなくても、より低い労力で、より高い効果を得られる証跡から追加していこうと考えています。
また、複数ホストへの対応も重要です。実際のインシデント調査では、対象が1台だけというケースは多くありません。
これは、単純に1台分の処理を台数分繰り返すのではなく、それぞれのホストを独立した対象として扱いながら、アカウント、IPアドレス、プロセス、時系列などの関係を横断的に調べる必要があり、大きな設計変更になりそうです。だいぶ先かな。
調査の品質をどう測るか
CFReDSのデータを使った手元の試行では、12問中8〜9問程度まで答えに近づくことがありました。ただし、これは特定のモデル(google/gemma-4-e2b)と設定で数回試した範囲の観測であり、固定された公式結果ではありません。
また、正答数だけが増えても、調査全体の品質が向上したとは限りません。
たとえば、ベンチマークの答えに特化した結果、仮説が特定の証跡に偏ったり、根拠を追跡できない文章が増えたり、未確定の推測が記憶へ混入したりすれば、それは改善とは呼べません。
そのため、今後は正答率に加えて、仮説の多様性、記憶の重複、LLMの呼び出し傾向なども含め確認していきたいと考えています。
結論
FORENSIAの開発を通して、弱いLLM特有の課題が色々見えたかなと思っています。
結局のところ、優れた統率者(このツールはそれをハーネス側の機械的アプローチが担う)が必要で、力技でそれを愚直に実装していくか、強いモデルを使って吸収してあげるかという2択になりそうです。
ぶっちゃけローカルLLMはきびちい!!!!
おわり