Branch Privilege Injection:分岐予測器の競合状態を悪用!
引用元:https://news.ycombinator.com/item?id=43974891
研究者のブログ記事と論文へのリンクだね。
ブログ: https://comsec.ethz.ch/research/microarch/branch-privilege-i…
論文: https://comsec.ethz.ch/wp-content/files/bprc_sec25.pdf
影響の説明だよ。
研究者のRüeggeさんが言うには”時間かければメモリ全部の内容を読み出せる”
”繰り返しエラー起こして毎秒5000バイト以上読み出せる”
だから攻撃されたらCPUメモリの情報全部が悪いやつの手に落ちるのは時間の問題だ、ってさ。怖いね。
もし大した性能向上じゃないなら、なんでこんなひどいバグを導入したんだ?
いや、大したことないってわけじゃないよ。投機的実行は普通、分岐の多さによるけど、コードを10~50パーセントも速くするんだ。
ありがとう!記事のタイトルについてるURLをブログ記事に変えてくれると嬉しいな。今のプレスリリースは役に立たなさすぎ。
これにはソフトウェアとハードウェアが協力する必要があるね。特に、セキュリティコンテキストが違うスレッドは同じコアに割り当てちゃダメ。これを保証できれば、fenceとかflushとかの状態クリアはカーネル呼び出しとかプロセスの一生が終わるときだけに限定できる。そうすれば、キャッシュとか投機的実行のメリットは、実際に重い処理をやってるものにはそのまま残せて、サイドチャネルリークの心配もなくなるよ。
オッケー、上の https://ethz.ch/en/news-and-events/eth-news/news/2025/05/eth… からブログ記事の方に変えたよ。
最近のプロセッサのパイプラインは何十サイクルも深いんだ。
分岐予測がないと、次に実行する命令を常に知ってる必要がある。
だから、今の命令をデコードして、それが分岐やジャンプじゃないってわかるまで何もフェッチできない。
もっと深刻なのは、もし分岐だったら、命令の実行が終わって、分岐するかわかるまで何十~何百サイクルも止める必要がある。
毎回の分岐でそんなに止まってたら、今の性能は絶対出ないよ。
そんなプロセッサが欲しいなら、マイクロコントローラー買えば?
それでもまだかなり控えめな見積もりだよ。全ての分岐の前に lfence を入れたら、たぶん10倍くらい遅くなる。
みんな、どう思う?うん、ダイレクトリンクはクリックを減らせるけど、元のタイトルの方が一般読者には分かりやすかったと思うんだ。私はプロのカルマ稼ぎじゃないし、dangさんの立場なら同じように調整しただろうけど、変更後にアップボート率が75%も下がったのを見ると、ちょっとキツイとは言わざるを得ないね。
気持ちはわかるよ。でも開発者たちは、あふれる3rd partyのnpmモジュールの魔女の呪文をnginxで提供するのに苦労してるんだ。security labelled cgroupベースのマイクロ(ナノ?)コンピューティングサービスを安全に設計・開発して、様々なセキュリティレベルのテキストを推論できるようにするなんて、95%のコーダーには無理ゲーだし、1%のトップ開発者でも超大変だろうね。いっそプロセッサを直す方が良くない?
そうだね…これが簡単に避けられることだと思ってる人は、ブランチ予測がない使いたいプロセッサを探し回ってみるといいよ。明るい面としては、90年代に行くことになるから、ずっと良い音楽シーンを楽しめるだろうね。
修正がパフォーマンスを著しく低下させるなら、「ただ」ではない、トレードオフだよ。プロセッサ単体では緩和が必要かどうか判断する仕組みがないから、どこでもすべてに影響を与えざるを得ないんだ。今は2025年で、セキュリティは私たちの世界の一部なんだから、後からボルトオンしようとするんじゃなくて、プロセッサとソフトウェアの相互作用について考える方法に最初から焼き付ける必要があるね。私たちはその教訓をインターネット向けのソフトウェアで何十年も前に学んだ。ここでも学ぶべき時が来たんだ。
もちろん、ここにはちょっとしたチキンと卵の関係があるよね:もし(動的な)ブランチ予測がなかったら、私たち(コンパイラとか)は予測しないCPUにとって速いコードを出すだろうね(そして多分、予測するCPUにとっては遅くなる)。それが10倍の差を少し緩和するんじゃないかな。
でも、ブランチ予測は必ずしも複雑なロジックを必要としないんだよ。もしちゃんと覚えてるなら(20年前に論文を読んだきりだけど)、単純なヒューリスティック、「後方への相対分岐はすべて実行、でも前方と絶対分岐は実行しない」っていうのでも、当時の最先端実装の70~80%のパフォーマンスを達成できたらしいよ。
これでJavaScriptが私のパスワードマネージャーのデータベースを漏洩させるのをどうやって防げるの?
もちろんそれは知ってるよ。でも、このバグの修正(Intel CPUにセキュリティホールいくつあった?)で性能ロスが数%しか出ないなら、どうやってそれを正当化できるの?そこに根本的な問題があるんじゃないの?
ソフトウェア書くのがそんなに怠惰じゃなかったら、どれだけ改善されるんだろうね。ハードウェアが「十分良い」って期待するんじゃなくて、マシンから最大限のパフォーマンスを引き出して、無駄な肥大化を避けるためにちゃんとコードを書けばさ。
問題は間接分岐にあるんだよ。ほとんどの分岐は直接分岐だからね。
まあね。CPUがやってることをコンパイラに任せるのはうまくいかないって、何度も証明されてきたと思うよ、最近だとItaniumとかね。
全体的にってこと? それとも分岐予測に限定して? もしそれが全部本当なら、20〜30%のパフォーマンス低下って話になるの?
”こういう風に動くプロセッサが欲しいなら、マイクロコントローラーを買え”
ARM Cortex-R5FとかCortex-M7とか、いくつか名前を挙げると、これらにも分岐予測器ついてるんだけどね ;)
静的な分岐予測器を持つことはまだできるよ。それは驚くほど良いカバー率なんだ。これが素晴らしいアイデアだって言ってるわけじゃなくて、ただ指摘してるだけだけどね。
IBM Stretchには分岐予測があったよ。90年代初頭のPentiumにもあった。パイプライン処理においてはどんな場合でも大きな利点なんだ。
”Branch Privilege Injectionは非Intel CPUに影響しますか?”
いいえ。私たちの分析では、評価したAMDとARMシステムでは問題は見つかりませんでした。
それに見合うだけの価値はあるの?全てがOrange Book(DoD 5200.28-STD)のClass B1システムみたいになる必要はないでしょ。
めっちゃ良い記事だった!要点まとめね.予測更新が分岐完了後に遅れること,ディスパッチや特権レベル変更命令が予測器の更新を待たないこと,これらは理にかなってる.でも,特権レベル変更の件は,予測時とコミット時のレベル一致保証がないと,異なる特権レベル間で予測状態が混ざる可能性があるのが気になる.パイプライン中の”現在の特権レベル”って曖昧だから難しそう?
Kaveh Razavi の名前を見れて嬉しいな!彼,僕が Vrije Universiteit にいたときアムステルダムで教えてたんだよ Hardware Security って授業,マジでやばいくらい面白くて,この記事みたいな内容を深く掘り下げてたんだ.
このコース(あと Vrije のマルウェアのやつ)を数年前にチェックしたことあるんだけど,その頃はコースに関する公開情報がほとんどなかったんだよね.公式な録画とかノートってオンラインにあるか知ってる?事前にサンクス.
僕が知る限り,コース資料は公開されてないんだ. VUSEC グループのコースでは実習課題がすごく重要で,残念ながらコースのインフラがないとリモートでやるのは難しいんだよね. 君が言ってた Binary and Malware Analysis のコースは, Dennis Andriesse の本 ”Practical Binary Analysis” をベースにしてるから,興味あるならその本を手に入れるといいかも.
もっとコメントを表示(1)
あーそうだ,彼がボットネットをどうハッキングしたかっていうゲスト講義もしてたな!詳しくはここ見てみて: https://krebsonsecurity.com/2014/06/operation−tovar−targets−...もうずいぶん前の話だけどね
委託学生って手があるよ.料金は状況次第. Vrije のコース内容を大まかに教えるね: Hardware Security では Flush/Reload, Spectre, Rowhammer とか研究論文の実装・読解. Binary & Malware Analysis は IDA Pro, Taint analysis, Intel PIN, Triton を使った解析・クラッキング. Computer & Network Security は Web/App/Network Security(パケットスニファ作成, Kevin Mitnick 攻撃),Cの脆弱性探し(stack/heap overflows, format strings bugs).実践的で超濃い内容だった. Binary/Network security は hackthebox.eu おすすめだけど, Hardware security の代替は知らないな.
うわー,詳しい回答マジサンクス.委託学生として登録できるか見てみるよ,でも多分リモートは受け付けてないだろうな.そういや,当時めっちゃモチベーション高かったんだね.かなり大変だったろうけど,乗り越えたんだね.おめでとう!
どっちもSpectre V2は悪用してるけど、やり方が違うんだよ。俺の考えだとね:
Training Solo:
- Kernelに入って(権限レベルを変えて)、disclosure gadgetへブランチを誤予測させるように”自己学習”させてメモリを漏洩させる。
Branch predictor race conditions:
- trained branch predictorの更新がまだ処理中のうちにKernelに入って、その更新が間違った権限レベルに関連付けられるようにする。これでまたKernel内のブランチをdisclosure gadgetにリダイレクトして、メモリを漏洩させるんだ。
もしCPUのbranch predictorが、バッファ境界とかコードの権限レベルをチェックできる情報をすぐ持てたら、こういうのはもっと簡単に防げたはずなのにね。でも、それはC言語プログラマーの手からvoid*を無理やり剥ぎ取って、ポインタに大事な情報を持たせるようにならないと実現しないみたいだ。
あるいは、みんなが問題の範囲をもっとよく理解して、脆弱性があるからって直接攻撃につながるわけじゃないって気付くべきだよ。投機的実行のExploitは、低レベルコードを実行できるコンピューターに直接アクセスできる場合だけ現実的で、JSコードでブラウザから任意の秘密を漏洩できるわけじゃない。Exploitする価値があるシステムは、許可されていない任意のコードが実行されないシステムであるべきだ。個人的には、パフォーマンス向上が体感できるから、全ての緩和策を無効にしてる。
> JSコードを書いてブラウザで動かして、任意の秘密を漏洩させられるわけじゃない
SpectreやMeltdownってまさにそれだったじゃん。この攻撃が現代のブラウザでも動くかは不明だけど、SharedArrayBufferは再び有効になったし、既存のSpectre/Meltdown対策でこの攻撃が防げるかも不明だよ。
>個人的には、パフォーマンス向上が体感できるから、全ての緩和策を無効にしてる
おめでとう、あなたのマシンではJSコードが暗号キーを読み取れる可能性が高いね。
インターネットからの任意コードを実行しない内部システムなら、一部の緩和策を無効にするのは理にかなってるね。ビルドサーバーとか、ロードバランサーとか、ステートレスなAPIサーバーとか、他のテナントと共有されてない物理マシンのVMじゃない限りは。
JSを有効にしたウェブブラウザを使ってる時点で、”インターネットからの任意コード”を実行してることになるんだよ。
> みんなが問題の範囲をもっとよく理解するべき
あなたこそ理解してる?Dragnet攻撃で個人的に影響されないって知ってるの?
だって、あなたのこの主張:
> JSコードを書いてブラウザで動かして、任意の秘密を漏洩させられるわけじゃない。
Spectreにとっては真実じゃなかったんだから。オリジナルのSpectre論文はJSを攻撃ベクターとして有名に挙げてる。もし全ての緩和策を本当に無効にしてるなら、その穴をまた開けてるってことだよ。だから:
> これを使える唯一現実的な方法は、低レベルコードを実行できるコンピューターに直接アクセスできる場合だけだよ。
俺は低レベルのKernelエンジニアだけど、これが一般的なケースで真実だとは知らないね。JITも”低レベルコード”を生成してるんだよ。これが十分じゃないってどうしてわかるの?
> 問題の範囲を理解してる?Dragnet
問題はそれが俺に影響するかじゃなくて、リスクがどれくらいかだよ。リスクは非常に低いって断言できる、俺の方がこの分野をよく理解してるみたいだから。
> オリジナルのSpectre論文はJSを攻撃ベクターとして有名に挙げてる。
たとえるなら、攻撃ベクターは特定の種類の武器、Exploit実行は戦争。Log4Shellは携帯ショットガンみたいに簡単だけど、Spectre/Meltdownは環境に強く依存するブービートラップ。JSのキャッシュタイミングは難しい。もちろん絶対確実はないが、ブラウザコードは公開されてるからブラウザの脆弱性は低い。
まさにこれが、ほとんどのインフラボックスではやらないことだよね?もしボックス上の全てのソフトウェアを合理的に信頼できるなら、アドバーサリーコードがマシン上で実行された影響から守る多くの緩和策は不要になる。
一方、アドバーサリーがボックス上で低権限RCEを取得した場合、SpectreやRowHammerのようなものを悪用すれば、権限レベルを昇格させるのに役立ち、他のインフラへの攻撃をより簡単に仕掛けることができる。
それ、どうやって役に立つと思ってんの?ソフトウェアの話じゃなくてハードウェアの話だよ。ポインタ変えてもトランジスタは変わんないし。君が求めてるのは、ロード/ストアごとにバウンダリ情報を持つ”拡張アドレス”を通るみたいなハードウェア。つまり80286のセグメンテーションのこと。あれあったけど、君の求めることは無理だったじゃん。だってセグメントディスクリプタをロードするソフトがミスしないわけじゃないからね。”ただのポインタ”だから、同じ間違いをするんだよ。
『おめでとう、JSで暗号キー読まれるかもね。AIに仕事取られるの怖がってるわけだ(笑)』全然違うって。JS変数からキー取るには1. サイトにJSコードを注入する方法を見つける(今難しい)2. 特定のメモリアドレスを知る必要がある(変数名ランダムだし)3. キャッシュがエビクトされる必要(プロセッサ依存、Webアプリの状態も)JSだとメモリレイアウト推測して、分岐予測器訓練も必要で時間かかる。だから、キャッシュ攻撃より物理的に強盗に遭う方がよっぽど可能性高いって。Spectre/Meltdownみたいに、この手の攻撃は実世界であまり見ないよ。特定のプロセッサ狙って、任意のコード実行できないと、キャッシュタイミング攻撃を正しく動かすの超難しいから。
えー、Same-Originとかインジェクション攻撃が前提ってのが分かんないな。どっかのリンク踏んで適当なサイト見るだけでいけないの?
君は、特定のサイトのデータに興味があって、同じサイトで攻撃する必要があるって考えてるみたいだけど、この脆弱性はシステム内のどこでもメモリ読めちゃうんだよ。PoC(https://www.youtube.com/watch?v=jrsOvaN7PaA)は/etc/shadowをメモリから探してダンプしてるのを見せてる。JSでできるかは分かんないけど、もしJSでできるなら、他のサイトにコード入れたり、アドレス知る必要なんてないんじゃないかな?(もしJSで無理なら、この話は無意味だけどね)
それは、他のサイトのデータが入ってるJS変数なんてないんだから、そのサイト自身が置いた秘密を盗むだけに制限されるでしょ。
『システム内の任意のメモリを読み取れる』
PoCはコンパイルされたCコードだよね。システムで動くCコードと、ブラウザの中で動くJSコードが違うってこと、説明いる?
そうだよ、この脆弱性は最悪、システム内のどこでもメモリ読めちゃうって話だろ?特定のサイトとかブラウザの中だけじゃなくて。
うん、前のコメントでも言ったけど、ちょっと君のコメント読み違えてたわ。インフラ系の箱で「マシンの全て持ってる」みたいなのは本当。でも、例えばDBサーバーの注意もね。信頼レベル違うアカウントが使う共有DBサーバーはヤバいかも、ストアドプロシージャとかある場合。結局、誰でもアクセスしていいわけじゃないデータが箱にあるなら、超注意しないとね。
それって使えるgadget次第じゃないの?CもJSもマシンコードになるんだし。個人的には、最悪の場合、カーネル近くまで行って(PoCがシステムコールでやるみたいに)、タイミングサイドチャネルでカーネルのメモリを誤予測させて漏洩させられない、なんて信じないね。最近のカーネルはほとんどの物理メモリをマップしてるし(64bitだと楽だしね)。詳しい理由はここに書いたよ: https://news.ycombinator.com/item?id=43991696
自分の誤解を認めつつ、多くのPCは任意コード実行しないと思ってる人でも影響受けるよ。DBサーバーもstored procedures(PL/SQLみたいなやつ)とかで任意コード実行に注意しないとね。
ちょっと違うよ。この脆弱性は直接アドレスできるメモリを読むんだ。任意コード実行できるなら理論的には全メモリ空間だけど、ASLRとか仮想メモリで実際は難しい。JSはもっと制限多くて、任意のアドレスにポインタでアクセスできないんだ。
JSにはシステム上の任意メモリにアクセスできる仕掛けはないよ。配列の境界外はできるけど、JSエンジンの翻訳層があるから生のメモリは直接扱えないんだ。web assemblyでもね。
サプライチェーンリスクもそうだし、多層防御って考え方も大事だよね。物理的に分けるのが一番シンプルかな。この手の攻撃は、ひとつの仕事だけしてる専用マシンにはあんまり関係ないんだ。
JS無効にしたら? HTMLだって表現力は低いけど「インターネットからの任意コード」みたいなもんだし。
JSコードが攻撃のために任意メモリを指す実際のポインタを作らないといけない理由がまだよくわかんないな。良性の適当な整数値をカーネルに渡して、それがポインタとして使われるコードに誤予測させるんじゃないの? このリンクに詳しく書いてあるよ: https://news.ycombinator.com/item?id=43991973
このスレッド読んでるとさ、“single-tenant”って言葉の意味を脆弱性との関連でかなり誤解してる人が多い気がするな。
ハードウェアウォレットいっぱいあるのに、今どき誰が自分のPCに暗号キー置いとくかな?
Spectre素人だけど、有効なポインタは絶対必要? 実際には動かないコードでも、それをポインタとして使うコードに誤予測させればいいだけじゃない? 論文のC PoCはsystem callを仕掛けに使って、良性の値がチェック前に誤予測した情報漏洩コードでポインタとして使われる例を示してる。JSから直接system callは無理だけど、良性の値が間接的に渡されて、別のカーネルパスでポインタとして使われる誤予測が起きる可能性はないの? 物理メモリのほとんどはカーネル空間だから、それができればほぼ任意メモリに影響できるはず。難しいのはわかるけど、不可能? Spectreってヤバすぎるから、ハードウェアで直さないと、単に難しくなるだけで、十分難しいの? ASLRは論文で破ってるよ。
もっとコメントを表示(2)
JSだと配列超えてどのくらい先が必要か分かんないし、最初の値のメモリ位置も不明。割り当てられた場所から後ろ向きに読めるけど、運良くキャッシュ追い出せて他のアプリをかわせたとしても、残るのはランダムな値で鍵は特定不能。Cコードならメモリを直接参照できるからなんとかなるんだけどね。
Intelのセキュリティ勧告だよ:https://www.intel.com/content/www/us/en/security-center/advi…
AMDのハードウェアにも似たような穴あるのかな?投機的実行って、共有プロセッサ空間じゃパッチ当てるのめっちゃ難しい脆弱性っぽいから、AMDはどうやって避けてるんだろうって気になる。
著者のブログ記事によるとね:
>Branch Privilege Injectionは非Intel CPUに影響ある?
>いいえ。評価したAMDとARMシステムでは問題は見つかってないよ。
情報源:https://comsec.ethz.ch/research/microarch/branch-privilege-i…
簡単に言うと、AMDが(脆弱性を)避けてるわけじゃないよ。投機的実行のサイドチャネルって一つの脆弱性じゃなくファミリー全体なんだ。今回のはIntelだけみたいだけど、Meltdownと同じで。でもAMDもオリジナルのSpectreには脆弱性があったんだよ。
厳密には投機的実行自体は脆弱性じゃなく、今の高性能CPUには必要な仕組みなんだ。でも複雑だからエンジン内のバグは多い。
AMDやARMにも似たバグあるはず。Intelで見つからなかった期間を考えてみてよ。唯一の解決策は、現代システムじゃコード隔離できないって認めること。これは一部企業のビジネスモデルに打撃だろうね。
>現代システムじゃコード隔離できないって認めるのが唯一の解決策
VMをハードウェアコア(SMT含む)に固定するのは、今回のケースを直す?これで多くのサイドチャネル攻撃に対処できたと思ってた。
理想的じゃないけど、ハイエンドCPUのコア数が増えてる時代には悪くないよね。
これカーネルメモリ読めるなら、VMはホストカーネルとか中のセキュリティキー読めちゃうんじゃない?
あと、コアピンニングで攻撃が同じコアの別CPUアクセスに限定されるってのも、サイドチャネル攻撃ではあんまり聞かない話だけど。
たぶん違うんじゃないかな。
このエクスプロイトは共有されてるメモリをウォークできるって感じみたいだけど?
でも、自分が動いてるコアでアクセスされてないメモリを外に出せるの?
ブランチ予測器って物理コアごとに一つだと思ってたし、この手のサイドチャネル攻撃は同じコアで別権限ドメインでやってることから漏れるんだとばっかり。
僕が言いたかったのは、こういう脆弱性を作らずにパフォーマンス向上を実現するのが難しい機能だってことだよ。
この脆弱性の解決策は僕には直感的だよ。
ブランチ予測器の更新をキューに入れる時に現在の権限レベルをスナップショットして、それがプロセッサの内部バッファを流れる間ずっとそのスナップショットも一緒に持たせるんだ。
ソフトウェアでもありそうな問題だし、同じ解決策だよね?
それ、実はうまくいかないんだよね。
分岐条件の評価は権限更新の場所から遠い場合も。
更新する「現在の状態」はなく、後でどうだったか認識するだけ。
CPUでデータ持ち運びは高コスト。
命令ポインタも使えない原因。
リタイア時更新も考えられるけど、それも危うい。
リタイアキューでの追跡やレジスタ確認が必要で、可能だけど少し難しいんだ。
(引用:こういう隙間を埋めるにはプロセッサのマイクロコード特別なアップデートが必要で、BIOSかOSアップデートでWindowsの累積アップデートに含まれるはず)
なんでWindowsだけ?Linuxユーザーはどうなるの?
IntelはLinux向けマイクロコード更新をここ
https://github.com/intel/Intel-Linux-Processor-Microcode-Dat…
で配布してるよ。
ディストリビューションはそこから自動で取ってきて配布する設定になってる。
ただ、これらの特定の緩和策がもう入ってるかは、専門家じゃないから分からないんだ。
研究者たちはこれが CVE-2024-45332 って言ってるよ。
INTEL-SA-01247 がその CVE をカバー。
Microcode release 20250512 でその INTEL-SA が緩和済みらしい。
詳細はこの辺見てみて。
https://github.com/intel/Intel-Linux-Processor-Microcode-Dat…
https://www.intel.com/content/www/us/en/security-center/advi…
Ubuntu 24.04.2 で確認するとこんな感じだよ。dpkg -l | grep microcode
ii amd64-microcode 3.20231019.1ubuntu2.1 amd64 Processor microcode firmware for AMD CPUs
ii intel-microcode 3.20250211.0ubuntu0.24.04.1 amd64 Processor microcode firmware for Intel CPUs
ii iucode-tool 2.3.1-3build1 amd64 Intel processor microcode tool