Return-to-libc攻撃とは
Return-to-libc攻撃は、
コンピュータセキュリティにおける攻撃手法の一つで、バッファオーバーランの
脆弱性を悪用します。この攻撃では、プログラムのコールスタック上のリターンアドレスを、攻撃者が意図する別の
サブルーチンのアドレスに書き換えます。さらに、スタック上の引数に相当する位置も操作することで、書き換えられた
サブルーチンを呼び出します。
攻撃の巧妙な点は、プログラムに悪意のあるコードを注入することなく、既存の関数を呼び出すだけで攻撃を実行できる点にあります。特に
Unix系システムでは、
C言語のランタイムライブラリとして「libc」という共有ライブラリが広く利用されており、このライブラリには攻撃に利用しやすい多くの機能が含まれています。例えば、`system()`関数は、引数として与えられた任意のプログラムを実行できるため、攻撃の標的になりやすいです。
バッファオーバーラン攻撃では、通常、攻撃者は任意のアドレスに制御を移すことができます。しかし、return-to-libc攻撃では、常にリンクされている`libc`ライブラリ内の関数を呼び出すことが多いため、「return-to-libc」という名前で呼ばれています。これは、攻撃者が制御をlibcライブラリ内の関数に戻す(return)ことから来ています。
攻撃のメカニズム
1.
バッファオーバーランの発生: プログラムの
脆弱性(例えば、バッファサイズを超えるデータの書き込み)を利用して、バッファオーバーランを発生させます。
2.
リターンアドレスの書き換え: バッファオーバーランによって、コールスタック上に存在するリターンアドレスを、攻撃者が制御したい`libc`内の関数のアドレスに書き換えます。
3.
引数の操作: 必要に応じて、スタック上の引数も書き換え、呼び出される関数に適切な引数を渡せるようにします。
4.
関数の実行: 書き換えられたリターンアドレスによって、`libc`内の関数が実行され、攻撃者の意図する処理が行われます。
防御方法
Return-to-libc攻撃は、従来のバッファオーバーラン攻撃とは異なり、スタックに実行コードを書き込む必要がありません。そのため、NXビットなどの技術でスタック上でのコード実行を禁止しても、この攻撃を防ぐことはできません。以下に、主な防御方法を示します。
1.
スタック保護 (Stack Smashing Protection): スタックの内容の破壊を検出し、必要に応じて破壊されたセグメントを復旧することで、この種の攻撃を防御します。具体的には、スタックフレームにカナリア値を挿入し、関数のリターン時にこの値が書き換えられていないかを確認します。
2.
ASLR (Address Space Layout Randomization): 実行プログラムの各モジュールのコードが配置されるアドレスをランダム化します。これにより、攻撃者はターゲットとなる関数のアドレスを予測することが困難になり、攻撃成功の確率を大幅に下げることができます。特に
64ビットシステムでは、ランダム化できるアドレス空間が広いため、ASLRの効果は非常に大きいです。しかし、
32ビットシステムでは、ランダム化されるアドレス空間が狭く、総当たり攻撃によって短時間で攻撃が成功してしまう可能性があります。
関連事項
- - バッファオーバーラン: メモリのバッファ領域に、意図されたサイズを超えるデータを書き込んでしまう脆弱性です。これがReturn-to-libc攻撃の起点となります。
- - スタックオーバーフロー: コールスタックが容量を超えてデータが書き込まれる状態を指します。バッファオーバーランによって発生することがあります。
- - NXビット: スタック領域などの特定のメモリ領域でのコード実行を禁止するハードウェア機構です。バッファオーバーランによるコード実行を防ぐことができますが、Return-to-libc攻撃には効果が限定的です。
- - PaX: Linuxカーネルのパッチで、アドレス空間のランダム化などを実装したセキュリティ機能です。ASLRの前身とも言えます。
参考文献
- - Shacham, Hovav; Page, M.; Pfaff, B.; Goh, E. J.; Modadugu, N.; Boneh, D. "On the Effectiveness of Address-Space Randomization" (PDF). Proc. of CCS 2004.
外部リンク