LinuxのSMB実装でo3を使ってリモート0-dayを発見
(sean.heelan.io)- LinuxカーネルのSMB3サーバー実装であるksmbdの監査で、OpenAI o3 APIだけを用いてリモートuse-after-free脆弱性CVE-2025-37899を発見し、別途エージェントフレームワークやツールは使っていなかった
- この脆弱性はSMB
logoffコマンド処理中に解放されたsess->userへ別スレッドが引き続きアクセスできてしまう問題で、同時接続とセッション共有状態の両方を見ないと表面化しない - 手動で見つけていたCVE-2025-37778を基準にしたベンチマークでは、o3は100回中8回脆弱性を発見し、Claude Sonnet 3.7は3回、Claude Sonnet 3.5は0回だった
- 入力をすべてのSMBコマンドハンドラーと接続処理コードまで広げた12k LoC / 100k入力トークン条件では、既知脆弱性の発見率は100回中1回に低下したが、同じ結果の中から新たな脆弱性CVE-2025-37899が出てきた
- 誤検知や無意味な出力は依然として多いものの、実際の脆弱性研究で人間がレビュー・検証する価値があるだけの正解が出る確率は高まっている
o3でksmbd脆弱性を見つけた実験
- 監査対象はLinuxカーネル空間でSMB3プロトコルのファイル共有を実装するksmbd
- OpenAI o3モデルを
o3 APIで呼び出しており、別途スキャフォールディング、エージェントフレームワーク、ツール利用はなかった - 発見された脆弱性はCVE-2025-37899で、修正はLinuxカーネルのコミットにある
- 中核の問題はSMB
logoffコマンドハンドラーのuse-after-freeで、参照カウントのないオブジェクトが別スレッドからアクセス可能な状態で解放される構造になっている - この脆弱性を見つけるには、サーバーへの同時接続と、特定状況で共有されるオブジェクトの両方を理解する必要がある
- 公開に議論された事例の中では、この種の性質を持つ脆弱性をLLMが見つけた最初のケースと思われるという評価も含まれている
基準脆弱性 CVE-2025-37778
- まず手動で見つけたCVE-2025-37778を、o3の性能評価用ベンチマークとして使用した
- この脆弱性はKerberos認証経路で、リモートクライアントの
session setupリクエストを処理する際に発生するuse-after-free krb5_authenticateはsess->state == SMB2_SESSION_VALIDであればsess->userを解放する- その後のコードは、
ksmbd_krb5_authenticateが新しい有効値で再初期化するか、-EINVALを返した後はsess->userが使われないという前提に依存している - 実際には、
ksmbd_krb5_authenticateがsess->userを再初期化しないようにすることができ、krb5_authenticateが-EINVALを返してもsess->userへのアクセスは可能である
ベンチマーク構成とプロンプト
- CVE-2025-37778はリモート攻撃面にあり、
sess->state == SMB2_SESSION_VALID条件の誘導、再初期化されない経路、解放後アクセス経路のすべてを判断する必要があるため、ベンチマークに使われた - 脆弱性経路の説明に必要な最小コード量は約3.3k LoCと見積もられた
- 実験入力には
session setupコマンドハンドラーと、そのハンドラーが呼び出す関数群を呼び出し深さ3まで含めた - パケット受信、リクエスト解析、コマンドハンドラー選択、ハンドラー完了後の接続クリーンアップコードも併せて入れ、データ構造の初期化方法に関する推測を減らした
- 最終入力は約3.3k LoC / 27kトークンで、分析対象ファイルはsession_setup_code.promptとして公開されている
- プロンプトには次の条件が含まれていた
- use-after-free脆弱性を見つけるよう指示
- ksmbdの役割、アーキテクチャ、脅威モデルを高レベルで提示
- 未報告より誤検知報告を優先しないよう強く誘導
- プロンプト全体のファイルはo3_finds_cve-2025-37899リポジトリにある
- 実行にはSimon Willisonの
llmツールを使用した
CVE-2025-37778ベンチマーク結果
- 実験ハーネスは同じ問い合わせを100回実行して結果を保存した
- o3はCVE-2025-37778を100回中8回発見した
- 100回中66回はバグなしと判断し、false negativeになった
- 残りの28回はfalse positiveだった
- 比較結果は次のとおり
- Claude Sonnet 3.7: 100回中3回発見
- Claude Sonnet 3.5: 100回中0回発見
- このベンチマークでは、o3はClaude Sonnet 3.7より2〜3倍改善した結果を示した
- サンプルレポートはo3の結果とSonnet 3.7の結果として公開されている
- o3の出力は構造と焦点の面から、人間が書いた短縮版バグレポートのように読めるが、ときに短すぎて明確さを欠くことがある
- Sonnet 3.7の出力は、思考の流れや作業ログに近い形で現れる
すべてのコマンドハンドラーに拡大した実験
- 次の実験では、
session setupハンドラーだけでなくすべてのSMBコマンドハンドラーのコードをo3に与えた - コマンドハンドラーは
smb2pdu.cにあり、ファイルサイズは約9k LoC - すべてのハンドラー、接続設定とクリーンアップコード、コマンドハンドラーディスパッチルーチンを合わせると約12k LoC / 100k入力トークンになった
- この条件でも実験は100回実行された
- o3は既知のKerberos認証脆弱性CVE-2025-37778を100回中1回しか見つけられず、入力トークン数の増加に伴う性能低下が明確だった
- 同じ結果群の中から、従来知られていなかった新しい脆弱性CVE-2025-37899のレポートが見つかった
CVE-2025-37899の脆弱経路
- 新しい脆弱性も
sess->userの解放に関係するが、今回はsession logoffハンドラーで発生する smb2_session_logoffは次の順序で動作するksmbd_close_session_fds(work)を呼び出すksmbd_conn_wait_idle(conn)を呼び出す- セッション状態を
SMB2_SESSION_EXPIREDに設定 sess->userがあればksmbd_free_user(sess->user)で解放し、sess->user = NULLに設定
- o3レポートの脆弱シナリオは次のとおり
- SMB 3.0以降で2本目の転送が既存セッションにバインドされ、
conn->binding == trueになる - Worker-Aが別接続C2でWRITEなどの通常リクエストを処理する
smb2_check_user_session()はwork->sessに既存のstruct ksmbd_sessionポインタを保存し、セッション参照カウントを増やすが、sess->userには別途参照を取らない- Worker-Bが最初の接続C1で同じセッションに対するSMB2 LOGOFFを処理し、
smb2_session_logoff()を実行する ksmbd_conn_wait_idle(conn)はその接続で実行中のリクエストだけを待ち、同じセッションを使う別接続のリクエストまでは待たない- Worker-Aはそのまま動作を続け、
user_guest(sess->user)、ksmbd_compare_user(sess->user, …)、sess->user->uidのようなアクセスを実行し得る
- SMB 3.0以降で2本目の転送が既存セッションにバインドされ、
- タイミング次第では、解放済みslabオブジェクトを指すuse-after-freeになるか、
sess->user = NULLの後で読み取ってNULLデリファレンスによるDoSになる可能性がある
誤った修正案とo3結果の価値
- CVE-2025-37778に対して最初に提案された修正は、
ksmbd_free_user(sess->user)の後にsess->user = NULLを追加する方式だった - CVE-2025-37899のレポートを読んだことで、この修正が不十分であることが明らかになった
logoffハンドラーはすでにsess->user = NULLを行っているが、SMBプロトコルでは異なる2つの接続を同じセッションにバインドできるため、依然として脆弱である- Kerberos認証経路でも、
sess->userが解放された直後からNULLに設定されるまでの短い窓で、別スレッドがアクセスできる可能性がある - o3の一部レポートは同じ誤りを犯していたが、一部はセッションバインディングの可能性により、
sess->user = NULLだけでは十分でない点を捉えていた - false positiveに対するtrue positiveの比率が高いため、すべてのレポートを十分に細かく見直せたかは確実ではないという限界もある
脆弱性研究における実務的な位置づけ
- LLMは創造性、柔軟性、汎用性の面で、従来のプログラム解析手法よりも人間のコード監査者に近い位置にある
- 比較対象としてはsymbolic execution、abstract interpretation、fuzzingが挙げられている
- GPT-4以降、LLMの脆弱性研究への可能性はあったが、実問題では期待されたほどの成果は出ていなかった
- o3はコード推論、質疑応答、プログラミング、問題解決において、実際の脆弱性研究者の性能を高められる程度には機能する
- それでもなお不完全で、無意味な結果を生成して利用者を落胆させる可能性は大きい
- 変わったのは、実問題に適用してみるに足るだけの正解が出る確率が、初めて十分に高くなったという判断である
1件のコメント
Hacker News の意見
小さな点ではあるが、筆者のプロジェクト構成のやり方が有用に見える。システムプロンプト、背景情報、補助指示をそれぞれ
.promptファイルとして作り [1]、llmで実行する方式だLLM のうまい活用にも、ほかのエンジニアリングツールと同じように、体系的で、設計上の制約をバランスよく反映した、思慮深い仕様中心のエンジニアリング思考が必要だということを示している
[1] https://github.com/SeanHeelan/o3_finds_cve-2025-37899
すべて勘に頼った呪文のように見える。「あなたは脆弱性発見の専門家です」「誤検知なしに実際の脆弱性だけを報告してください」といった文言や、モデルがなぜか好むように見えるので偽の HTML タグで整理するやり方などだ。ここにどこがエンジニアリングなのか分からない
ああいうプロンプトは指示ではなくヒントと呼ぶべきだ。現在のあらゆる LLM は、プロンプトが自分の唯一の上位目標、つまり真偽にかかわらず答えを出すことと衝突すると、そのプロンプトを無視する
LLM にプロンプト作成を手伝ってもらうのも驚くほど効果的だ。私のプロンプト片もすべて LLM の助けを借りて設計した
個人的には全部 org-mode ファイルに入れておき、必要なときに ChatGPT の会話へコピー&ペーストしている。より「議論型」のやり取りを好むが、アプローチは同じだ
記事では信号対雑音比がおよそ 1:50 だとしている。筆者はこのコードベースを非常によく知っているので、ノイズの中からシグナルを選り分けるのに適した立場にいる
この部分を自動化するところに本当の成果が出てくるはずなので、引き続き注目したい
新しい最前線の LLM が出るたびに、入力を学習データとして使うモデルは除外して、その面接課題を走らせている。初回で動く回答の割合が一貫して1:10程度にとどまり、自分のミスを見つけさせるには 10 ラウンド以上突っつかなければならないことも多く、驚いた
なので、もっと難解なテーマでこの程度の信号対雑音比になるのは納得できる
結果の幅はかなり広く、近く予定しているカンファレンス発表ですべて公開するつもりなので期待してほしい。この分野の現状をかなりよく示すものになるはずだ
追記: 表現が紛らわしかった
そうした LLM は、何年もそのコードベースで働き、あらゆる特性を身につけた人に近い合成版になるのではないか
長いコンテキストには本当に多くのものを入れられるが、コードベースによってはコードだけですでに 20 万トークンあるので、よく分からない
特に数週間前にここで取り上げられていた RAInk のような二分トーナメント方式ならなおさらで、異なる LLM 間の合意を使う方法もある。ここで Gemini 2.5 PRO を使っていないのは意外だが、私の経験ではこの種の作業には最も強力な LLM だ
この記事で最も興味深く重要な部分は、筆者が各モデルごとに脆弱性検索を 100 回走らせた点だった
私がこれまで大規模言語モデルで試した大半の問題に使おうとしていた計算量よりはるかに多いが、もしかするとモデルはただひたすら回し続けるべきなのかもしれない
推論コストがほぼゼロに近づいたとき、サイバーセキュリティの世界がどうなるのかは分からないが、今日とはまったく違う空間になるはずだ
むしろ贅沢と浪費を祝っていることに近い。世界的な気候変動に直面しているというのに、1950年代のように些細なことに資源を燃やし続けている
ものすごく運が良かったのか、予想どおりGemini 2.5 PROはこの脆弱性をより簡単に見つけられるようだ。成功率が高かったので、次のプロンプトを数回回すだけで十分だった: https://gist.github.com/antirez/8b76cd9abf29f1902d46b2aed3cd...
最近、このようなパターンが繰り返されている
明確な定義と評価関数がある問題なら、LLMに解空間を狭めさせる。LLMはパターンの再構成に非常に強く、答えが既知のものと似たパターンであればうまく機能し得る
この場合、問題は特定の種類のセキュリティ脆弱性で、評価者は専門家だ。規模は違うが、LLMを遺伝的最適化に使う最近の試みと精神的には似ている
“Mathematical discoveries from program search with large language models”も興味深い読み物で、以前HNにも上がっていたと記憶している
https://www.nature.com/articles/s41586-023-06924-6
ただし、この実験だけを根拠にLLMがコードについて推論していると結論づけるのは、個人的には少し無理があると思う
これが本物であってほしいし、curlで繰り返し起きていることと同じでないことを願う
[1] https://daniel.haxx.se/blog/2024/01/02/the-i-in-llm-stands-f...
これがLLMで発見された最初の脆弱性だという主張には確信が持てない。たとえばOSS-Fuzz [0]はファジングでいくつか見つけているし、Big Sleepもエージェント方式で見つけている [1]
[0] https://security.googleblog.com/2024/11/leveling-up-fuzzing-...
[1] https://googleprojectzero.blogspot.com/2024/10/from-naptime-...
記事で言っていたのは、「この脆弱性を理解するには、サーバーへの同時接続と、特定の状況で複数のオブジェクトがどのように共有されるかを推論する必要がある。o3はこれを理解し、参照カウントされていない特定のオブジェクトが、別スレッドからまだアクセス可能な状態で解放される箇所を見つけた。私の知る限り、この性質の脆弱性をLLMが見つけたことについての初の公開された議論だ」ということだった
言いたかったのは、私の知る限り、LLMがその種のバグ、つまり些細ではない量のコードと共有リソースへの同時アクセスに起因するバグを見つけた公開文書としては初めてだという点だ。少なくとも私にとっては、LLMの進歩を示す興味深いしるしだ
ゼロデイ発見の価値を考えると、数百回のAPI呼び出しだけで安定して見つけられるなら、世界中のほぼすべての情報機関がここに資金を注ぎ込むだろう
特に多数の例でモデルを微調整できるならなおさらで、OpenAIのようなところは公開APIでそうしたことはしてくれないだろう
政府機関や他の組織にとっては、当然こうした制約は問題にならない。それ以外の全員にだけ適用されるだけだ。だから人々は、こうした制限のない別のモデルやエージェントを使うようになるだろう
重要なソフトウェアの至るところに多くの脆弱性が存在すると見て差し支えない。今やそれらを見つけられるようになった。コンピューターセキュリティとハッキングに軍拡競争のゲーム理論が適用される状況が始まるだろう。おそらく予想よりも早く来る可能性が高い
カーネル開発者の何人かがこのバグを「検証」したことは分かるが、実際に概念実証を作ってテストした人がいたのか気になる
手順のこれほど核心的な部分なのに、概念実証が完全に抜け落ちている。概念実証がなければ途中でどんな問題が生じるか分からず、したがって悪用可能性や影響を判断できない。少なくとも著者は検証なしにリモートコード実行とは呼ばなかった
しかし、著者と開発者たちが見落としていた、あるいはo3が扱ったと仮定していたが実際にはo3のコンテキスト外にあったパズルのピースが1つあり、それがこの脆弱性自体を無効にするとしたらどうなるのか?
そういうものがあると言っているわけでも、著者の作業を代わりにやる時間を使うと言っているわけでもない。ただ、この報告は完全に検証されたものではなく、今後LLM脆弱性研究の分野で影響力のあるブログ記事になる可能性を考えると、危険な前例のように感じる
個人的には、モデルが生成したどんな脆弱性レポートにも、PoC || GTFOをこれまで以上に厳格に適用すべきだと思う
o3が以前のモデルや他の現行モデルよりはるかに優れているという見方はなお残るし、方法論も興味深い。人々に特定の点へ注目してもらうために、そのような文言を使いたい欲求や必要性は理解できる。これがクリックベイトの問題だ。しかし、どうかもっときちんとしてほしい。概念実証を作り、主張を検証すべきで、怠けてはいけない。脆弱性研究者の研究方法に影響を与え得るブログ記事を書くなら、理論上の仮定ではなく検証を促すべきだ。そうでなければ、検証可能で実証された報告によってシステム理解を深める代わりに、虚偽だがもっともらしい報告が無知を広めることになる
私のプロンプト開発セッションの大半がどのように進むのかを完璧に捉えた、美しい小さな一節がある