高度な攻撃手法

UAF(Use-After-Free) ゆーえーえふ(ゆーずあふたーふりー)

メモリ破壊バッファオーバーフローヒープ脆弱性エクスプロイトメモリ安全性
UAFについて教えて

簡単に言うとこんな感じ!

一度返却した部屋(メモリ)に、鍵を返し忘れてこっそり入り続けるイメージだよ!プログラムが「もう使わない」と返したはずのメモリ領域を、攻撃者が乗っ取って悪用する脆弱性なんだ。ブラウザやOSへの侵入でよく使われる危険な手口だよ!


UAF(Use-After-Free)とは

UAF(Use-After-Free) とは、プログラムがいったん解放(free)したメモリ領域を、その後も参照・操作し続けてしまう脆弱性のことです。「解放後使用」とも呼ばれます。メモリ管理のミスによって生じるバグの一種で、攻撃者に悪用されると任意のコードを実行させられてしまう、非常に危険な脆弱性です。

プログラムはメモリを動的に確保(アロケート)し、使い終わったら解放(フリー)します。しかし解放後も、その領域を指す ダングリングポインタ(dangling pointer) が残っていると、プログラムは誤ってその領域を操作し続けます。攻撃者はこの隙を狙い、解放されたメモリに悪意あるデータを配置し直すことで、プログラムの制御を奪います。

UAFはWebブラウザ、PDF・Office文書ビューア、OS内部など、複雑なメモリ管理を行うソフトウェア全般で発見されており、CVSSスコア9.0超え の致命的な脆弱性として報告されるケースも珍しくありません。


UAFが発生する仕組み

UAFは以下の3ステップで成立します。

ステップ内容例え
① Allocate(確保)プログラムがヒープ領域にメモリを確保し、ポインタで指し示すホテルにチェックイン、鍵を受け取る
② Free(解放)メモリを解放するが、ポインタはそのアドレスを指したままチェックアウト、でも鍵を返し忘れる
③ Use(再使用)解放済み領域を誤って参照・書き込みしてしまう空き部屋に不正入室、荷物をすり替えられる

攻撃シナリオの流れ

[正常なプログラム]
  obj = malloc(size)   ← ①メモリ確保
  ptr = obj            ← ポインタをセット
  free(obj)            ← ②メモリ解放
  ※ ptr はまだ同じアドレスを指している(ダングリングポインタ)

[攻撃者の介入]
  malloc(size)         ← 同サイズで別データを割り当て直す
  → 解放された領域を悪意あるデータで埋める

[脆弱なプログラム]
  ptr->method()        ← ③解放済み領域を参照 → 攻撃コードが実行される!

C++における仮想関数テーブル(vtable)乗っ取り

C++では、オブジェクトの関数呼び出しに vtable(仮想関数テーブル というポインタ群を使います。UAFによってvtableのポインタを偽物と差し替えると、攻撃者が用意したコードに実行を誘導できます。これが実際の攻撃で多用される典型パターンです。


歴史と背景

  • 1990年代〜 C/C++の普及とともに、ダングリングポインタに起因するバグが認識されはじめる
  • 2000年代前半 ブラウザの高機能化(JavaScriptDOM操作)とともにヒープ領域の操作が複雑化し、UAF脆弱性が増加
  • 2010年 IE6/7のUAF脆弱性(CVE-2010-0249)を用いた「Operation Aurora」がGoogle等を標的に攻撃。UAFが国家級の高度攻撃(APT)に使われることが広く知られる
  • 2012〜2016年 Chrome、Firefox、IE、Flashを標的にしたUAF脆弱性が毎年多数報告。CVSSスコア9.x台の致命的なものも頻出
  • 2017年以降 Windows Kernel・macOS・Linux内部のUAFが増加。特権昇格(Privilege Escalation)の手口として多用される
  • 2019年 CVE-2019-1367(IE)、CVE-2019-0808(Windows Kernel)など複数のゼロデイUAFが標的型攻撃で使われる
  • 2021年以降 Rustなどメモリ安全な言語の採用が業界全体で加速。GoogleはChromiumへのRust採用を進め、Androidも同様の方針を表明

UAFと他のメモリ脆弱性の比較

脆弱性の種類発生箇所概要危険度
UAFヒープ領域解放済みメモリの再使用★★★★★
バッファオーバーフロースタック/ヒープ領域外への書き込み★★★★★
ダブルフリーヒープ領域同じメモリを二重解放★★★★☆
ヌルポインタ参照どこでも無効アドレスへのアクセス★★☆☆☆
整数オーバーフロー演算処理計算結果の桁あふれ★★★☆☆
UAF 攻撃の流れ ① Allocate malloc() でメモリ確保 ptr → [Object: 0x1000] ② Free free() でメモリ解放 ptr → [????:0x1000](危険) ③ Realloc(攻撃者) 同サイズで悪意データを配置 [0x1000] ← 偽vtable ④ Use(脆弱なコード) ptr→method() を呼び出し → 偽vtableを参照してしまう ⑤ 攻撃者の任意コード実行 / 特権昇格 シェル奪取・マルウェア設置・情報漏洩へ

対策技術の比較

対策概要効果限界
ASLRメモリ配置をランダム化エクスプロイトを困難に情報リークと組み合わせると回避可能
CFG / CFI制御フローの正当性を検証vtable乗っ取りを防止実装コストが高い
ヒープサニタイザー解放済みメモリへのアクセスを検出開発時のバグ検出に有効本番環境では性能低下
メモリ安全言語(Rust等)言語レベルで所有権を管理UAFをコンパイル時に防止既存C/C++コードの書き換えコストが高い
GCベース言語(Java等)ガベージコレクタが管理ダングリングポインタが発生しないGCのオーバーヘッド

関連する規格・RFC

規格・番号内容
CWE-416MITREによるUAFの共通脆弱性タイプ定義(Use After Free)
CWE-119バッファ境界外メモリ操作の上位カテゴリ

関連用語