世界を動かす技術を、日本語で。

LinuxカーネルにおけるKernel-hack-drillとCVE-2024-50264の悪用

概要

  • CVE-2024-50264 はLinuxカーネルのAF_VSOCKに存在する 極めて難解な特権昇格脆弱性
  • Race conditionUAF(Use-After-Free) が悪用の中心で、再現・利用が非常に困難
  • 脆弱性の発見から Pwnie Award 2025 受賞までの経緯と PoC開発の試行錯誤
  • kernel-hack-drill プロジェクトの役割と、従来手法との違い
  • 脆弱性の技術的詳細、制約、典型的な攻撃手法、失敗例までを解説

CVE-2024-50264 Linuxカーネル特権昇格バグの分析とPoC開発記

  • CVE-2024-50264 は、LinuxカーネルAF_VSOCKサブシステムに存在する race conditionによるUAF脆弱性
  • 脆弱性は2016年8月のコミット(06a8fc78367d、Linux v4.8)で導入
  • connect()システムコール 中にPOSIXシグナルが割り込むことで、 virtio_vsock_sockオブジェクト が解放後に利用される
  • 非特権ユーザー でもユーザ名前空間なしでトリガー可能、危険度が高い
  • メモリ破壊 はカーネルワーカー(kworker)によるUAF書き込みで発生

脆弱性発見から公開まで

  • 2021年にAF_VSOCKのバグを発見し、 CVE-2021-26708 として公開
  • 2024年4月、カスタムsyzkallerで再度AF_VSOCKをファジングし新たなクラッシュを発見
  • KASAN無効化 により即時null-ptr-derefとなり、当初は重要性を見逃す
  • 2024年秋、再調査で有望な結果を得るも、 Hyunwoo Kim (@v4bel)とWongi Lee (@qwerty) による先行公開(CVE-2024-50264)に衝突
  • 彼らのパッチで自作PoCが再びnull-ptr-deref化、バグ衝突の苦い経験

脆弱性の技術的詳細

  • virtio_vsock_sock (80バイト)はkmalloc-96スラブキャッシュから割り当て
  • UAF書き込みはkworkerがkfree()直後に実行、 タイミングが極めてシビア
  • connect()をPOSIXシグナルで割り込む必要
    • SIGKILLはプロセスが死ぬため不適
    • signal 33(NPTL内部用) をtimer_createで発火、プロセスを殺さずにraceを誘発
  • UAF発生時、 virtio_vsock_sock.peer_buf_alloc/peer_fwd_cnt にユーザ空間から値を書き込める
  • tx_lockがゼロでないとspin_lock_bh()でハング、実用的なUAF原語の構築が困難

攻撃・利用上の制約

  • クライアント/サーバー両virtio_vsock_sockが同一スラブキャッシュから割り当て、 クロスキャッシュ攻撃が難しい
  • UAF発生後すぐにkworkerがnull-ptr-deref、 通常のヒープスプレーが効かない
  • Ubuntu Server 24.04は CONFIG_SLAB_BUCKETS=y、CONFIG_RANDOM_KMALLOC_CACHES=y でヒープスプレー耐性強化
  • cred構造体(被害オブジェクト候補)は割り当てサイズが異なり、 UAFオフセットの制約 あり
  • credをUAFしてもtx_lock位置が非ゼロとなりカーネルハング、 攻撃に不向き

先行研究の攻撃手法

  • @v4bel & @qwertyの手法は極めて複雑
    • BPF JITスプレー で物理メモリを占拠
    • SLUBStickテクニック でスラブ配置を制御
    • Dirty Pagetableテクニック でページテーブルエントリを書き換え
    • BPFコードに特権昇格ペイロードを挿入し、ソケット経由で実行

kernel-hack-drillによる新アプローチ

  • PoC exploitを単純化 するため、UAF書き込み先の被害オブジェクトを再検討
  • ヒープスプレーを諦め、 クロスキャッシュ攻撃 に挑戦
  • cred構造体を被害対象に選ぶが、 実用的なexploit primitive構築に失敗
  • これらの試行錯誤を通じて、 CVE-2024-50264の難易度とPwnie Award受賞理由 を痛感

脆弱性攻撃の障壁とPoC開発の教訓

  • 再現性の低さタイミング依存性カーネル保護機構 の多重障壁
  • 先行研究の複雑さに対し、 新たな攻撃経路の模索 が必要
  • kernel-hack-drill の活用で、独自アプローチの検証が可能
  • 失敗事例から学ぶ、 カーネルエクスプロイト開発の現実的困難
  • 今後の攻撃手法開発 やカーネル防御強化への知見提供

まとめ

  • CVE-2024-50264 は、現代カーネル脆弱性の中でも 最難関級のエクスプロイト対象
  • 再現難易度・攻撃制約・保護機構 の三重苦
  • kernel-hack-drill のようなツールによる新規アプローチの重要性
  • 失敗事例・先行研究の複雑さ から学ぶ、現代カーネルセキュリティ研究の最前線

Hackerたちの意見

うわ、時間がないな。20分間読んでたけど、そろそろ仕事に戻らないと、笑。この記事が「使い終わった後の使い方」について、制限や次のステップを詳しく説明してるのが好きだな。普通なら2部構成とか4部構成になりそうなのに、これ一気に書かれてるのがすごい。半分くらいは集中して読めたけど、これをコースとかで再現したら楽しそう。あと、特定のコードの実行時間を遅くできるって知らなかった。

「進む道が辛いだろうと確信して、バグを棚上げした。」バグを直す代わりに?セキュリティ研究者がバグを修正するインセンティブが壊れてるか、Linuxへの修正の寄付が壊れてるか、どちらかだね。ユーザーが操作できるサブシステムをRustで書き直すのは、早くやってほしいな。

著者はロシア人で、Positive Technologiesに勤めてるみたい。そこの会社は制裁リストに載ってるね。

セキュリティ研究者はバグを修正することはめったにないよ。自分の仕事だとは思ってないし、バグを見つけたり悪用したりするのとは全然違うスキルが必要だからね。

そうだよね、実際、潜在的に悪用可能なバグを放置する方が、セキュリティ研究者にとっては早めにパッチを当てるよりも良いインセンティブがある。例えば、ルート権限の昇格があれば、いろんなAIサンドボックスやCIサンドボックス、Androidアプリのサンドボックスからバグバウンティがもらえる可能性があるし、他にもいろいろある。もし、たぶん悪用できないカーネルクラッシュがあったら、せいぜいCVEがもらえるくらいで、それすらもらえないかもしれない。どうしたらいいと思う?Googleがすべてのカーネルバグを潜在的な悪用と見なして、Linusにコミットごとに10万ドル渡して、彼を地球で一番金持ちにするべき?

「バグを直す代わりに?誰かが楽しみのために何かをするなんて、神様が禁じてるよ…」

これを見て、自分がどれだけ無力なのか実感した。真剣なエクスプロイト研究者の才能と能力に超感心してる!

Googleのプロジェクトゼロのブログを読むのが大好き。すごく謙虚な気持ちになる。私がプログラミングを始めた頃はすごく低レベル(x86アセンブリ)だったけど、今はその世界からかなり遠くに来ちゃった。

練習すれば、すぐに上達するよ。ほんとに、身につけられるスキルセットだからね。

興味深いテーマだけど、他の人もこの文章が読みづらいと感じてる?言葉の選び方や文の構造に何か…プロっぽくない感じがする。

英語が彼の母国語じゃないの?それが理由かもね。

私もネイティブスピーカーじゃないから、あくまで参考程度に聞いてほしいんだけど、フレーズのリズムの問題だと思う。作家はフレーズの長さや複雑さを使って、スピード感や落ち着きを作り出すことができるんだよね。リズムが変わらず、似たような長さのシンプルな文が続くと、しばらくするとロボットみたいに聞こえる。「このコマンドを実行します。それからこの問題が発生しました。これが別の何かを引き起こしました。問題に対処しました。別のことが起こりました。今、対処しています。」これは著者への批判ではなくて、あなたの感じた理由が気になったから確認しただけなんだ。

私はこれが明確で心地よい読み物だと思ったよ。あなたの気になる点はよくわからないけど、人それぞれだよね。「プローズっぽくない」って、むしろ褒め言葉に聞こえる。

「いいえ、私はタスクを終わらせる人を雇います。競争が終わっても…これはエピックだ!!! 写真を読むだけでもこの投稿にアップボートする価値がある。これにダブル投票できたらいいのに。競争の枠を超えた人間の創意工夫を示している。素晴らしい!!!」

SLAB_VIRTUALのパッチが止まったのはすごく残念だった。実際、大きな反対意見はなかったし。最近、kmallocをパーティション分けするためにclangの新しいアロケートトークンを使おうとするパッチが出たけど、これがこのエクスプロイトに対して何か違いを生むとは思えないな。https://lore.kernel.org/lkml/20250825154505.1558444-1-elver@...

LinuxカーネルにRustのようなよりメモリ安全な言語を使ったら、こういったエクスプロイトに対してもっと安全になるのかな?

パッチをちらっと見ただけだけど、「もっと安全」というのは少なくとも方向性としては正しいね。カーネルがunsafeコードを使う可能性があるから、理論的にはまだ可能だけど、このコードが直接unsafeで書かれることはないと思う。

なんとも言えないね。Rustでは技術的に防がれている「書き込み後の自由」があるけど、選ばれた抽象化によるかな。安全でない部分の欠陥を突くような似たような攻撃が出てくる可能性は十分あると思う。だから、悪用するのは難しくなるはずだし、カーネルコードの大部分が「安全な」抽象化を使っていることを強制するのも簡単になるはず。

... より良い型システム、衛生的なマクロ、そしてもちろん、もっと静的解析(Rustの借用チェッカーみたいな)も必要だね。安全な抽象化を書きやすくして、テストや検証もしやすくなるすべてが役立つんだ。