
Windowsの未文書仕様を自律型AIエージェントで解析する - セキュリティ研究者の頭脳を再現する試み
目次
- はじめに
- 人間の研究者が持つ強みの分析と、AIへの設計転換
- ワークフローの中核設計と研究環境
- 複数の自然科学分野から借りてきたアイデア
- AIが自分の結論を自分で否定してしまう問題とその対策
- 事例: プロビジョニングエンジンの挙動
- まとめ
1. はじめに
オフェンシブセキュリティ部 高度診断課の松本 一真です。
普段はWebペネトレーションテストやAIアプリケーションの診断などを行っており、業務とは別に、AIを活用した自律的なセキュリティ研究に取り組んでいます。
世界的に著名なセキュリティ研究者たちは、長年の経験と知識の蓄積によって、OSやソフトウェアの文書化されていない仕様やロジック上のセキュリティ課題を見つけてきました。
あの思考過程をAIで再現できないかと考えたことがきっかけとなり、自律型の研究ワークフローを開発しています。本稿ではそのワークフローの設計思想について詳しく解説します。
後半では、このワークフローが実際にどのような研究を行うかのケーススタディとして、Windowsの構成プロビジョニングエンジン(provengine.dll)の挙動を取り上げます。
文書化されていない仕様を、AIがどのように解析し、どのように自らの誤りを訂正したのかまでを追います。
なお、当社では2026年7月にサイバーセキュリティに特化したAI基盤「AIホワイトハッカー byGMO」を構築しており、研究の発信もその一環として進めています。
開示. 本件はすでにMicrosoft Security Response Center(MSRC)へ報告済みです。
Microsoftのサービス提供基準上はセキュリティ境界を越える事象とはみなされず、修正対象とはならないとの回答を受けています。ブログでの公開についても事前にMicrosoftへ連絡し、承諾を得ています。本稿は、この判断を踏まえた上で、ワークフローの設計思想の解説を主眼とし、技術的な事例としてこの挙動を扱うものです。
2. 人間の研究者が持つ強みとAIへの設計転換
2.1 人間の研究者が暗黙に持っている3つのもの
セキュリティ研究コミュニティでは、公開された知見を互いに参照し合い、その上に新しい研究を積み重ねていくのが一般的です。
ワークフローの設計にあたっても、まずProject Zero、SafeBreach、Elastic、Quarkslab、Akamaiなどに所属する著名なセキュリティ研究者たちの公開資料(ブログ記事、カンファレンスの発表資料、論文など)を数十件にわたって精読しました。
「この人たちは、新しいセキュリティ上の問題をどのような過程で見つけたのか」を研究者ごとに追っていくと、ある共通した構造が見えてきました。以下は公開資料からの私の解釈であり、研究者本人の自己認識とは異なる可能性があります。
どの発見も、事後的には「鮮やかな一手」のように見えるのですが、その一手の背景には 暗黙の前提条件が3つ あったように思います。
1つ目は、長年にわたる「気になる挙動メモ」の蓄積です。 Project Zeroのブログ記事の中で、ある研究者は「調査するたびに、興味深い挙動や予想外の挙動を必ずメモしておく」という習慣を公言しています。
10年以上のメモの蓄積があって初めて、ある日の観察が「これは文書化された仕様と矛盾している」と認識することができます。
つまり、一見「直感」に見えるものは、実は長年のメモとの照らし合わせだったのではないかと思っています。
2つ目は、対象領域への深い事前知識です。 たとえばProject Zeroの別の研究者のブログ記事では、レジストリの解析器に特権なしでデータを渡す方法が研究の出発点になっています。
こうした知識は、その研究のために獲得したものではなく、研究者がもともと持っていたものだと考えられます。
仮説を立てる前の段階で、対象について一から学ぶ必要がありませんでした。
3つ目は、別分野の知識が偶然つながった経験です。 Elastic Security Labsの公開記事によれば、ある研究者の着想は「ファイルをネットワーク越しに別のマシンから読み込ませたら、OSが『このファイルは書き換えられない』と信じている前提を崩せるのでは」というものでした。
また、SafeBreachの研究者のブログ記事では、UEFIブートキットのニュースから「他にもダウングレードできるものがあるのでは」と連想したことが述べられています。
いずれも計画されたものではなく、たまたまの出会いから生まれています。
2.2 AIにはこの3つがない
自律的なAIエージェントには、上記の3つがどれもありません。10年分のメモ帳はなく、初めて触れるサブシステムへの事前知識もなく、別分野の知識が偶然つながる機会がありません。
人間の研究の流れをそのまま移植すると、「対象を観察して、仕様と矛盾する挙動に遭遇して、それを解析する」という流れの最初の段階で詰まります。そうした挙動は、狙って出会えるものではないからです。
2.3 「見つける」と「発明する」は別の行為
ここでもう一つ重要な区別があります。既知脆弱性の種類に当てはまるインスタンスを探すことと、まだ誰も名前をつけていない新しい問題のパターンそのものを見つけ出すことは、根本的に異なる知的作業です。
前者は「認識」であり、後者は「発明」に近いです。このワークフローが目指しているのは後者です。
新しいパターンそのものを見つけ出せれば、同じ考え方で別の箇所の研究にも応用でき、セキュリティの向上に広く寄与できると考えています。
なお、後述のケーススタディはこの区分でいえば「認識」寄りの事例であり、「発明(新パターンの発見)」とフェーズGの一般化は本ケースでは未達です。この点は今後の課題として取り組んでいます。
2.4 発想の転換
2.1で述べた研究者たちの事例を見る限り、「仕様と矛盾する挙動に偶然出会って、それを解析する」という流れで成果につながっているケースが多いように思います。
しかしAIには偶然の出会いがない。であれば、偶然の出会いを待つのではなく、仕様と矛盾する挙動をAI自身が自分から探しに行くという設計にすべきだと考えました。
3つの暗黙の武器それぞれに、代わりの仕組みを用意します。
Table 1. 人間の強みとAIが用意すべきもの
| 人間が自然に持っているもの | AIが代わりに用意すべきもの |
|---|---|
| 長年の「気になる挙動メモ」 | 仕様と矛盾する挙動を探しに行く手法の引出し (フェーズC) |
| 対象領域への深い事前知識 | ツールで列挙して把握する仕組み(フェーズB) |
| 別分野の知識が偶然つながった経験 | 複数の分析視点を順番に当てる仕組み(フェーズD) |
3. ワークフローの中核設計と研究環境
AI×セキュリティ研究の領域では、近年Google Project Zeroが開発したNaptime(2024年)や、それをProject ZeroとDeepMindが発展させたBig Sleep(2024年)のように、ファジングでは見つからない脆弱性を推論主導のエージェントで発見する研究が注目されています。Big Sleepはファジングが見逃したSQLiteのメモリ安全性の問題を推論で発見した事例として知られています。
本ワークフローがこれらと異なるのは、対象がオープンソースのメモリ安全性ではなく、クローズドソースのWindowsコンポーネントにおけるロジックや信頼モデルの設計上の問題である点です。
ワークフローは7つのフェーズ(A〜G)で構成しています。それぞれのフェーズに、「何を判断するか」「何をやるか」「次に進むための条件」「脱線を防ぐチェック」を定義しています。
全体の流れとしては、 対象選定(A) → 列挙(B) → 揺さぶり(C) → 仮説構築(D) → 仮説の排除(E) → VM実証(F) → 一般化(G) という構成です。

Fig 1. 7フェーズの全体像
3.1 フェーズA — どこを見るか決める
最初の課題は「何を調べるか」です。対象は膨大にあるので、一つに絞る必要があります。
ここでは、いくつかの問いを順番に当てていきます。
(一例)
- ・特権を持たないユーザーが、特権で動くコードに対して実際に何を入力できるか
- ・広く信頼されているが、セキュリティの観点から十分に調べられていない仕組みはどれか
こういった問いを順番に検討して、研究対象を一つに絞り込みます。
個人的に大事にしているのは、先行研究から借りるのは「思考の動き」であって、特定の脆弱性パターンそのものではないという点です。
既知の脆弱性パターンをそのまま再現するだけでは、このワークフローが目指す方向性とは合いません。
そうではなく、「この研究者がやった『信頼されたメカニズムを反転させる』という思考法を、別の領域に適用してみよう」というアプローチを取っています。
3.2 フェーズB — 対象を列挙できるようにする
人間の研究者は対象の内部構造をすでに知った状態で研究を始められますが、AIにはそれがありません。そこで、「サブシステム全体を調べろ」という漠然とした指示を、「ここにN個の入口があるから、それぞれを調べろ」という具体的な指示に変換します。
たとえばRPCであれば各操作番号、レジストリであれば各キーの一覧、といった形で、ツールを使って対象の全容を機械的にリストアップし、各入口について「誰が書き込めて、誰が高い権限で読んでいるか」を整理します。
3.3 フェーズC — 仕様と矛盾する挙動を自分から探しに行く
ワークフロー全体の中で、最も設計に時間をかけた部分です。 そもそもセキュリティ上の問題はどこに潜んでいるかというと、「開発者が暗黙に仮定していること」と「コードが実際にチェックしていること」の間にある隙間だと考えています。たとえば「このフォルダに書き込めるのは管理者だけ」という仮定があっても、コード上でそのチェックが実際に行われていなければ、そこにセキュリティ上の問題が生まれます。
人間の研究者は長年のメモの蓄積からこうした隙間を思い出せますが、AIにはその蓄積がないため、自分から探しに行く必要があります。
具体的には、列挙した各入口に対して9種類の「揺さぶり」を順番にかけていきます。この9種類は、実際の研究を繰り返す中で有効だった操作を整理・分類したものです。
特に効果が大きかったのは1番(差分)、5番(前提の反転)、9番(パッチ差分からの逆算)の3つで、後述の事例でも1番と5番が発見の起点になっています。
- 2つの状態の差分を取る。 同じであるべき2つの状態を比較して、すべての違いを説明する。たとえば「機能を有効にした場合と無効にした場合」「パッチ適用前と適用後」など。
- 極端な値を入れる。 ゼロ、最大値、想定外に大きな値など、境界付近の入力を試す。
- エラーを意図的に起こす。 メモリ不足の状態を作る、不正な形式だけど受け付けられる入力を送る、後始末をせずに終了する、など。エラー処理のコードには、文書化されていない「前提」が残っていることがあります。
- エラーの出方そのものを手がかりにする。 エラーコードやエラーの出るタイミングから、システムの内部状態を推測する。
- 解析で判明した事実の前提を反転させる。 「このファイルは書き換えられない」という前提があるなら、「もし書き換えられたらどうなるか」と考えてみる。
- 対象を別のカテゴリとして見直す。 たとえば「通知の仕組み」を「権限の異なるプロセス間でデータをやり取りする仕組み」として見直すと、本来の用途では想定されていなかったセキュリティ上の問題が見えてくることがあります。後述の事例でも、プロビジョニングを「信頼されたフォルダからの自動実行の仕組み」として捉え直したことが発見につながりました。
- 復旧や修復の仕組みを調べる。 更新やロールバックの仕組みを列挙して、「移動先の状態を誰が決めているか」「その決定を第三者が書き換えられないか」を確認する。
- 文書化されていない箇所をリストアップする。 文書化されていないものは、他の研究者にも十分に調べられていない可能性がある。
- パッチの差分から逆算する。 修正が入った箇所を見て、修正が見逃している兄弟パターンがないかを探す。この考え方はProject Zeroがvariant analysisとして体系化しているものに相当します。
ここで重要なのは、3回続けて同じ種類の結果しか出なかった場合は、別の揺さぶりに切り替えるというルールを設けていることです。「同じ種類」の判定は、発見された問題が同一の仕組みに起因するかどうかで行っています。
同じ手法を繰り返していると同種の結果に収束するため、意識的に視点を切り替える仕組みにしています。
3.4 フェーズD — 仮説を立てて、複数の説明を用意する
仕様と矛盾する挙動が見つかったら、次はその説明を考えます。
ここで重要なのは、最初に思いついた説明に飛びつかないことです。「署名検証が欠けている」と思っても、実は単にキャッシュが効いていただけだった、研究環境の設定が間違っていただけだった、ということは起こり得ます。
そこで、説明を1つだけ考えるのではなく、3つ以上考えることを必須にしています。そしてそれらを2つに分類します。
- ・よくある原因: キャッシュの影響、研究環境の設定ミス、など
- ・セキュリティ上意味のある原因: 検証が欠けている、隠された操作がある、など
また、別分野の知識が偶然つながる体験の代わりとして、複数の分析視点をあらかじめ用意して、順番に当てていきます。たとえば以下のような視点です。
- ・呼び出し元の身元を偽れないか
- ・名前の解釈が場所によって違わないか
- ・検証と使用の間にデータが変わらないか
- ・誰でも登録できてしまわないか
3.5 フェーズE — 手軽に排除できる仮説から先に排除する
フェーズDで複数の仮説ができますが、全部を同じ深さで検証するのは時間がかかりすぎます。そこで、簡単な確認で「これは違う」と分かるものから先に排除して、残った有力な仮説にリソースを集中させます。
たとえば「そもそも直接アクセスしたらどうなるか」を最初に確認します。直接アクセスが通ってしまうなら、それは単にアクセス制御が存在しないだけで、間接経路を調べる意味がありません。こういった簡単な確認を先にやることで、不要な深掘りを避けます。
3.6 フェーズF — VMで実際に動かして確認する
仮説が生き残ったら、実際にVMで動かして確認します。
このワークフローで一番大事にしているのは、「理屈上うまくいくはず」は発見ではない、ということです。「実際に動かしてこういう結果が出た」というところまで確認して、初めて発見と呼ぶことができます。
3.7 フェーズG — 一般化できるか確認する
最後に、見つかったものが「この一箇所だけの問題」なのか、それとも「同じ構造を持つ場所が他にもある、より一般的なパターン」なのかを確認します。一般的なパターンであれば、同じ考え方で別の箇所にも応用できるため、このワークフローとしてはそちらを目指しています。
同じパターンで3〜5箇所を調べてみて、複数箇所で同様の問題が見つかれば一般的なパターンだと判断できますし、調べた箇所がすべて適切に保護されていれば「この一箇所だけの問題」だったということになります。後者の場合は、正直にそう記録します。
3.8 AIエージェントが操作する研究環境
ワークフローの考え方は上記の通りですが、AIが具体的にどうやって対象のコンポーネントを解析したりVMを操作したりしているのかについても補足します。この点は設計上重要な部分です。
本ワークフローでは、AIエージェントがMCP(Model Context Protocol)を介して以下のツール群を直接操作できる環境を構築しています。
- ・静的解析: Binary Ninja + MCPプラグイン。 関数の逆コンパイル、呼び出し元の追跡、文字列検索などの指示を出し、結果を受け取れるようにしています。
- ・動的解析: VMware上のWindows 11研究VM。 VM内でのコマンド実行、ファイル配置、レジストリ確認、ETWイベント観測などを行えます。
- ・カーネルデバッグ: WinDbg / KDNET。 カーネル空間のデータ構造(プロセスのトークン情報やプールの状態など)を直接確認できます。
- ・動的計装: Frida。 特定のプロセスに対する関数フックやメモリの読み書きを実行できます。
- ・実行記録: TTD(Time Travel Debugging)。 処理を記録し、後から任意の時点の状態を確認できます。
- ・ファジング: MS-RPC-Fuzzer。 独自のハーネスを構築していますが、ロジックや信頼モデルの問題は入力の変異では表面化しづらいため、優先順位は最も低く設定しています。
これらはすべてMCPサーバーとして統合されており、構造化されたAPI呼び出しで操作することで誤操作を防いでいます。
4. 複数の自然科学分野から借りてきたアイデア
ワークフローの設計で参考になったものの多くは、実はセキュリティ研究そのものではなく、それ以外の分野の研究手法でした。「まだ知られていないものをどうやって見つけ、どう正当化するか」という問いに対する、各分野なりの回答を借りてきました。複数の分野から取り入れていますが、特に影響が大きかった4つを紹介します。
4.1 科学哲学: 発見と検証を分ける
一番影響が大きかったのは、科学哲学者Hans Reichenbachが提唱した「発見の文脈」と「正当化の文脈」の分離という考え方です。
仮説を考える段階(発見の文脈)では、飛躍や大胆な推測をむしろ積極的にやるべきだと考えています。ここで慎重になりすぎると、既知の範囲に収まる結果しか出てきません。一方で、検証の段階(正当化の文脈)では、すべてのステップを厳密に裏付けなければいけません。
この2つを混ぜないことが重要で、「発想段階の自由さ」を検証段階に持ち込まない、逆に「検証の厳密さ」を発想段階に持ち込んで発想の幅を狭めない、ということを意識しています。
この区別を導入する前は、エージェントが仮説を立てる段階で「これは根拠が足りないから考えるのをやめよう」と自制してしまい、研究の幅が狭くなるという問題がありました。
もう一つ役に立ったのは、「実験が失敗したとき、仮説全体を捨てる前に、どの前提条件が壊れたのかを特定する」という考え方です。仮説そのものは正しくても、研究環境の設定や実行のタイミングが間違っていれば実験は失敗します。
ワークフローでは、失敗時に仮説をすぐに捨てるのではなく、前提条件を一つずつ確認してから判断するようにしています。実際に、エージェントが「不可能」と判断したものが4回連続で研究環境の設定の問題だったことがあり、この仕組みの重要性を痛感しました。
4.2 対照実験の考え方
一つの変数だけを変えて他を固定し効果を測定する「対照実験」は、経験ある研究者なら暗黙的にやっているものと思われます。しかしAIエージェントは放っておくと複数の条件を同時に変えてしまい、何が原因で結果が変わったのか判別できない検証を行いがちでした。
この手順を明示的に組み込むことで、たとえば「パッケージの署名の有無だけを変えて、他の条件はすべて同じにして、署名の検証が行われているかを確認する」という形の検証を自律的に実行できるようにしました。
「何も起きなかった」という結果も重要なデータです。直接的な方法でアクセスが拒否されたという結果は、間接的な方法が本当にその制限を回避していることの裏付けになります。
実際に、この考え方がなければ、後述の条件付きACE (Access Control Entry; アクセス制御エントリ)の検証で「直接書き込みが通らない」という結果を無意味だと捨ててしまっていたかもしれません。
4.3 複数の候補を並べてから絞り込む
経験あるセキュリティ研究者は、一つの仮説に飛びつかず複数の可能性を検討してから絞り込みます。
これは医学の鑑別診断にも通じる考え方ですが、AIエージェントは放っておくと最初の説明に飛びつく傾向が強いため、「まず3つ以上の候補を挙げてから検証に入る」という手順を明示的にワークフローに組み込む必要がありました。
加えて、通常の鑑別診断ではまず一般的な原因から考えるのが定石ですが、このワークフローの目的は「まだ知られていないパターン」を見つけることなので、むしろ一般的でない原因を意識的に探す方向で設計しています。
この考え方を取り入れる前は、エージェントが「よくある原因」で説明をつけて早期に研究を打ち切ってしまうことが頻繁にありました。
4.4 認知科学: 既知のパターンに引きずられない
認知科学では「既知の解法パターンに固着して、もっと良い解法に気づけなくなる」という現象が知られています。Abraham Luchinsが1942年に報告したEinstellung effectとして知られています。
AIを活用したセキュリティ研究でも同じことが起きると感じていて、「これは○○パターンだ」と思った瞬間に、その認識を意識的に一旦止める仕組みを入れています。
この仕組みがなかった頃は、エージェントが既知のパターンに当てはめた「それらしい」説明をつけて、実は新しいパターンだったものを見落とすケースがありました。
5. AIが自分の結論を否定してしまう問題と対策
ワークフローを実際に動かしてみると、結果の精度が安定しないという課題がありました。
人間が最終チェックをするにしても、エージェントが出してくる結論にノイズが多すぎると、チェックの負荷が大きくなりすぎて回らなくなります。
5.1 自分の結論を自己検証するときの2つの落とし穴
自己検証には、実は2つの正反対の失敗パターンがあります。
1つ目は素通りで、自分の結論を読み返して「よさそうだ」とそのまま通してしまうことです。これは分かりやすい失敗です。
2つ目は過剰な自己否定で、こちらの方が対処が難しいです。根拠のない不安(「これは間違っているかもしれない」「AIの出力だから信頼できない」)で、実は正しい結論を自分で否定してしまうというものです。
実際の研究でも、自信に満ちた批判によって正しい結果が覆されるという現象が知られており、自律的なエージェントはこのリスクが特に高いと感じています。
対策として、結論を変更するには具体的な根拠が必要というルールを設けました。たとえば以下のような根拠です。
- ・コンポーネントのこの部分を見たら違っていた
- ・VMで実行したらこういう結果になった
- ・一次資料のこの記述と矛盾する
こういった具体的な根拠がない限り、結論の変更はできない、という仕組みです。根拠のない不安は「未解決の疑問」として記録はしますが、結論の変更にはつながらないようにしています。
なお、この問題については、Yifei Mingらの研究(“Helpful Agent Meets Deceptive Judge”, 2025)で、自信に満ちた誤った批判が1回のやり取りでAIエージェントの精度を大幅に低下させることが報告されています。このワークフローの自己検証ルールは、この研究結果を設計に取り込んだものです。
5.2 事実の記録を後から書き換えない設計
もう一つ、研究の精度を担保する上で重要な設計があります。
「ある事実をどうやって知ったか(推測したのか、ドキュメントで読んだのか、VMで実証したのか)」という記録を、後から絶対に書き換えないというルールです。
たとえば「署名検証は存在しないと思われる」という推測があり、後にVMで実証されたとします。このとき元の記録を「実証済み」に書き換えるのではなく、実証結果を新しい記録として追加し、そこから元の推測を参照します。
イメージは実験ノートに近いです。研究者は誤った見立てを消しゴムで消さず、取り消し線と日付付きの追記という形で訂正を残します。ノートを最新の正解に整えることが目的ではなく、いつ何を根拠にそう言えるようになったかという過程そのものが記録の価値です。
エージェントでも同様であり、最新の結論だけでなくそこに至る経路を保持します。
推測が検証を経て事実に格上げされること自体は、まったく正当なプロセスです。
問題は、上書きによって格上げの前と後が区別できなくなり、結果として最初から分かっていたかのように見えてしまう点にあります。
科学研究にも「実験結果を見てから仮説を立てる」HARKing(Hypothesizing After the Results are Known、Kerr 1998)と呼ばれる類似のタブーがありますが、これも探索の順序が事後的に塗り替えられ、その結論がどれだけ強い証拠に支えられているのかを読み手が判断できなくなるという点で、同じ構造をしています。
AIエージェントが長時間自律的に動く場合、この種の後付けは意図せず発生しやすく、影響も大きくなります。エージェント自身が過去の推測を実証済みの事実として読み直してしまえば、以降の判断はすべてその上に積み上がります。そのため、これは運用上の心がけではなく、記録の構造そのもの(追記のみ、上書き不可)として防いでいます。
5.3 既知のパターンに引きずられないための歯止め
ワークフローには先行研究や既知の事例を参考資料として含めていますが、これらはあくまで「思考法の教材」であって「当てはめるべきパターン」ではありません。
気をつけないと、「新しいパターンを見つけたはずが、実は既知のパターンを別の場所に当てはめていただけだった」ということが起きます。これを検出するために、3つの質問を用意しています。
- ・私は「考え方の手順」を借りているか、それとも「特定の問題の形」を借りているか?
- ・この発見は、対象の仕組みを調べた結果から来ているか、それとも「どの既知パターンが当てはまるか」から来ているか?
- ・参考にしている事例を完全に忘れても、この発見はたどり着けるか?
5.4 脱線を防ぐための仕組み
長時間にわたって研究を続けていると、いつの間にか当初の目的からズレていることがあります。これを防ぐために、いくつかのチェックを常時走らせています。
たとえば以下のようなものです。
- ・連続して同じ種類の結果しか出ていない場合は、手法を切り替える
- ・検証用ツールの開発に時間をかけすぎて本来の研究が進んでいない場合は、開発を一旦止める
開発過程では、十数回連続で成果ゼロの時期がありましたが、原因を調べてみると、すでに多くの研究が行われている領域にばかり集中していたことが分かりました。
対象の選び方を見直すことで改善できましたが、こうした経験をルールとしてワークフローに反映しています。
6. 事例: プロビジョニングエンジンの挙動
ここまではワークフローの設計思想について述べてきましたが、ここからは実際のケーススタディとして、ワークフローが自律的に発見した「公開ドキュメントに記載された仕様と実際の実装の間にあるギャップ」を技術的に解説します。
なお、本事例は冒頭で述べた通り、MSRCの基準ではセキュリティ境界を越える事象には該当しないと判断されています。本稿でこの事例を取り上げているのは、MSRCへ報告済みかつ公開の承諾を得ている事例であり、ワークフローの出力例として適切なためです。
なお、以降のコード解析および検証はWindows 11 Pro 24H2(Build 26100)上で行っており、provengine.dllのバージョンは10.0.26100.8521です。他のビルドでは挙動が異なる可能性があります。
6.1 構成プロビジョニングの概要
プロビジョニングパッケージ(拡張子.ppkg)は、Windows端末の構成を一括適用するためのファイルです。Wi-Fi接続、アカウント作成、ポリシー適用、アプリケーションのインストール、コマンド実行などをまとめて指定できます。
ここで重要なのは、.ppkgが単なる設定値の集合ではなく、適用時に実行される一連の処理を内包しているという点です。特に「アプリケーションのインストール」と「コマンドの実行」は、適用する主体の権限でそのまま実行されます。
6.2 SYSTEMによる自動適用タスク
タスクスケジューラの\Microsoft\Windows\Management\Provisioning配下には、SYSTEM権限・最上位の実行レベルで動作する4つのタスクが登録されています。
\Microsoft\Windows\Management\Provisioning\Logon
\Microsoft\Windows\Management\Provisioning\RunOnReboot
\Microsoft\Windows\Management\Provisioning\Retry
\Microsoft\Windows\Management\Provisioning\Cellular
これらはログオン時や再起動時に自動実行されます。ユーザーの操作は介しません。
6.3 仕様上のセキュリティモデルとの差
Microsoftの公開ドキュメント(Apply a provisioning package)では、実行時にパッケージを適用する条件として「管理者権限が必要(“requires administrator privileges”)」「パッケージが信頼できるソースからのものかユーザーに確認する」の2点が示されています。
しかしコンポーネントを解析すると、もう一つの適用経路が存在することが分かりました。
適用されたパッケージはC:\ProgramData\Microsoft\Provisioningに保存されます。このフォルダに到達する経路が2つあり、一方にしか検証が存在しません。
- ・経路A(対話的): ユーザーが
.ppkgをダブルクリック → UAC昇格 → 未署名であれば同意を要求。管理者権限と同意の両方が必要です。 - ・経路B(バックグラウンド): スケジュールタスクが
provtool.exe /turn NをSYSTEM権限で起動 → フォルダを走査 → 見つかった.ppkgをすべて適用。SYSTEM権限のタスクであるためUACが介在しないのは当然ですが、焦点はそこではなく、 署名の検証もユーザーの同意確認も行われないという点にあります。

Fig 2. 同一フォルダへ到達する2つの適用経路
6.4 コード解析 ― 署名検証が存在しないことの確認
provengine.dllをBinary Ninjaで逆コンパイルし、バックグラウンド適用経路を追いました。
通常稼働時、対象フォルダは常に走査される。 エンジンは走査対象フォルダの一覧をレジストリに保持しています。
HKLM\SOFTWARE\Microsoft\Provisioning\PackageLocations
"0" = %PROGRAMDATA%\Microsoft\Provisioning
"1".."4" = C:\Windows\Provisioning\...
上記の"0"が一般ユーザー向けのフォルダで、"1"〜"4"はC:\Windows配下です。エンジン内部の分岐を解析すると、"0"のフォルダを走査対象から外すのは初回セットアップ段階(OOBE)に対応する特定の条件下のみのようで、ログオン済みのデスクトップでは常に走査対象に含まれることが確認できました。
走査はファイル拡張子しか見ていない。 エンジンは*.ppkgのパターンでフォルダ内のファイルを検索し、一致したものをすべてパッケージとして取り込んでいます。ファイルの所有者や署名、誰が配置したかは確認していません。
適用前の確認は構造的なものに限られる。 パッケージ単位の処理で行われるのは、以下の3点のみでした。
- パッケージのコンテナを開く処理(署名の確認ではない)
- 内部のパーツを列挙できるかの確認(形式が妥当かどうかの確認であり、署名の検証ではない)
- 特定の組み込みパッケージのスキップ(個別の対応であり、信頼性の検証ではない)
これらの後にSYSTEM権限での適用が行われます。署名を確認する処理は見当たりませんでした。

Fig 3. SYSTEM適用前にエンジンが行う確認フロー
パッケージの検証処理の中身を見ると、内部のデータを順番に列挙して、最後まで問題なく終われば合格とするだけの短い処理でした。署名検証を行うためのAPI呼び出しは、静的解析の範囲では確認できませんでした。
また、後述のテスト2で未署名パッケージがそのまま適用されていることから、実行時にもこの経路で署名検証が行われていないことが動的に確認できています。
補助的な観察として、コンポーネント全体で署名に関連する文字列を検索しても該当がなく、公開ドキュメントに記載のある信頼判定用のレジストリキーもこの適用経路では読まれていませんでした。
ただし署名検証は必ずしも特定の文字列を含むとは限らないため、主たる根拠は上述の動的確認(テスト2)です。
6.5 検証用パッケージの作成
.ppkgはWIMという形式のファイルで、内部にXML形式のメタデータと構成パーツが含まれます。エンジンはパッケージを内部の識別子(GUID)で重複排除するため、既製パッケージをそのまま複製しただけでは「適用済み」と判定されてしまいます。この識別子を新しい値に書き換えることで、エンジンに新規パッケージとして認識させました。

Fig 4. プロビジョニングパッケージの識別子の所在
6.6 実機での検証
Windows 11の研究用VM上で、以下のテストを行いました。
テスト1 ― 一般ユーザー向けフォルダは実際に走査されるか。 既製パッケージの複製を設置し、SYSTEM適用後にWindowsのイベントトレーシング(ETW)で「パッケージの適用」を示すログが記録されることを確認しました。
テスト2 ― 第三者が用意したパッケージを新規として適用するか。 識別子を新しい値へ書き換えたパッケージを設置しました。
ETW id=20: Applying package 'aaa_evil.ppkg'
ID: {cccccccc-6d9d-473b-...}
レジストリに新しいキーが出現:
HKLM\...\Provisioning\Results\{cccccccc-6d9d-473b-...}
SYSTEMは、第三者が用意した未署名パッケージを新規として適用し、結果を記録しました。
テスト3 ― 適用される内容を制御できるか。 電源設定StandbyTimeoutを識別しやすい値13371337に設定したパッケージを適用しました。
STANDBYIDLE before = 0x00000000
STANDBYIDLE after = 0x00cc07c9 (= 13371337)
指定した値がそのまま書き込まれました。
テスト4 ― 影響の上限。 任意のレジストリ書き込みは処理されず、登録済みの構成プロバイダー(CSP)にのみ振り分けられます。ただし、登録済みCSPにはコマンド実行やアプリのインストールを担うものが含まれるため、CSPを経由してSYSTEMでのコード実行に到達できることが確認できました。以下は、.ppkgを設置した後にSYSTEM権限のcmd.exeが起動する様子を記録した実証動画です。
Movie 1. .ppkgを設置した後、SYSTEM権限のcmd.exeが起動するまでの一連の流れ

Fig 5. ファイル設置後の自動適用の流れ
6.7 誰の権限が昇格するのか
当初は「標準ユーザー → SYSTEM」を想定していました。
理由としては、フォルダC:\ProgramData\Microsoft\ProvisioningのACL (Access Control List; アクセス制御リスト)に、対話ログオンユーザーへの書き込み許可が含まれていたためです。
しかし、これは条件付きACEでした。
(XA;OICI;FA;;;IU;(!(WIN://ISMULTISESSIONSKU)))
「WIN://ISMULTISESSIONSKUが偽のときのみ許可する」という規則です。この属性はカーネルが管理する共有メモリ領域内の1ビットで管理されており、OS起動時に確定して稼働中は変わりません。
実際に計測してみた結果がこちらです。
Windows 11 Home (実機) bit 8 = 1 → 書き込み拒否
Windows 11 Pro (実機) bit 8 = 1 → 書き込み拒否
Windows 11 Pro (VM) bit 8 = 1 → 書き込み拒否
Windows 10 Pro (VM) bit 8 = 1 → 書き込み拒否
検証した4環境すべてでこのビットが立っており、条件付きACEは標準ユーザーの書き込みを拒否していました。

Fig 6. 起動時の1ビットによる書き込み可否
したがって、実証できた影響は管理者 → SYSTEMのみということになります。
当初はフラグの名前MultiSessionSkuから「通常のPCならビットは0だろう」と推測していたのですが、実測値はこの推測を否定しました。このビットが通常のクライアント向けWindowsで1になること自体は文書化された挙動であり、名前の直感に反する仕様です。名前から挙動を推測するのではなく、実際に値を計測して確認したことで、当初の誤った推論を修正できました。
6.8 各フェーズとの対応
本事例では、ワークフローの起動は人間が行い、研究対象の選定(provengine.dllの選定を含む)以降はエージェントが自律的に実行しています。各フェーズとの対応は以下の通りです(実際にはフェーズ間の行き来や手戻りも発生しています)。
- A. 「信頼されたフォルダ」前提の設計と、書き込み権限が動的に決まる構造の矛盾に着目
- B. レジストリの
PackageLocationsを列挙し、各locationの書き込み可能な主体を特定 - C. 対話的経路vsバックグラウンド経路の差分と、「管理者が配置したもの」という前提の反転が起点
- D. 「キャッシュ」「設定ミス」などの、よくある原因を含む複数の説明を並べて検証方法を整理
- E. 条件付きACEのビット値を計測し、「標準ユーザー → SYSTEM」の仮説を少ない手間で排除
- F. ETWとレジストリの観測で未署名パッケージの適用を確認し、よくある原因を一つずつ排除
- G. 他の適用経路への一般化は未達。現時点では単一の事例
特に6.7の条件付きACEの件は、初回のACE解釈が不完全だったことを再検証のルールが拾い、推論を修正できた例です。
7. まとめ
本稿では、AIエージェントによる自律的なセキュリティ研究のためのワークフロー設計を紹介しました。
本ワークフローでは、2026年6月の1ヶ月間に41件の研究対象を分析し、そのうち5件をMSRCへ報告しました。うち3件はケース番号が付与され、現在レビュー中のため詳細は非公開です。残る2件はいずれもMicrosoftのサービス提供基準上は修正対象とならないとの回答を受けており、本稿の事例はこの2件のうちの1件です。
報告に至らなかった36件の多くは、仮説どおりの挙動は確認できたものの、既存の防御機構によって影響範囲が限定され、セキュリティ境界を越えるには至らなかったケースでした。
なお、ケース番号の付与は報告が調査対象として受理されたことを示すもので、脆弱性としての認定や修正を意味するものではありません。
対象選定から解析、実機での検証に至るまでの工程は、人の判断を都度挟むことなく動作しています。
一方で、報告に至らなかった36件が示す通り、対象選定の精度が現時点での最大の課題です。
初期は「先行研究で取り上げられていない」という理由だけで対象を選んでいましたが、それだけでは十分に研究されていない領域かどうかは判断できません。
現在は以下の4条件をすべて満たす対象のみを選定しています。
- 影響の大きさ: 構造的に重大な問題につながりうる対象であること
- 到達可能性: 標準ユーザーの権限で実際に入力を渡せることをVM上で確認済みであること
- 研究の蓄積が少ない領域: 個別のコンポーネント単位ではなく、対象が属する領域全体として先行研究が少ないこと
- 有望な構造: ユーザーが制御可能なパスやデータを処理している構造であること
今後は、この選定精度をさらに高めるとともに、個別には影響が限定される事象が組み合わさった場合に何が起きるのかを評価できるようにしたいと考えています。
本ワークフローは、攻撃者側が同種の自動化を手に入れることを前提に、防御側が先にその手法と到達範囲を把握しておくことを目的としています。
報告に至らなかったケースや、途中で誤りだと分かった仮説まで含めて記録しているのも、その到達範囲を防御側が自ら見積もるための材料にしたいと考えているためです。
お知らせ
本稿ではAIを活用した「研究」側の取り組みを紹介しましたが、当社ではAIに関連するセキュリティサービスも提供しています。
AIホワイトハッカー byGMOについて
「AIホワイトハッカー byGMO」は、GMOサイバーセキュリティ byイエラエが構築した、サイバーセキュリティに特化したAI基盤です。
フロンティアAIに、AIの動作を制御・検証する独自のハーネスと、世界トップクラスのホワイトハッカーが実戦で培ってきた知見を組み合わせることで、脆弱性の発見から検証、対策までを高い精度で行えるよう設計されています。
GMOサイバーセキュリティ byイエラエは、この基盤から生まれる研究成果やサービスを「AIホワイトハッカー byGMO」シリーズとして順次公開してまいります。
AIシステムに対するセキュリティ診断について
当社では、AIアプリケーション診断やAIエージェントに対するペネトレーションテストなど、AIシステムに対するセキュリティ診断も提供しています。

筆者情報
松本 一真
オフェンシブセキュリティ部 高度診断課
Webペネトレーションテスト・AIアプリケーション診断・R&D等に従事。
AIを活用した自律的なセキュリティ研究に関心を持っている。
