ペネトレーションテスト&バグバウンティ
普段の生活で、貸りたものを返してから、また勝手に使ったら怒られますよね。
Use-After-Freeは、もう使わないって言ったのに使っちゃう危険なミスです。
Use-After-Free(UAF)とは
プログラムで「メモリを利用」と宣言すると、コンピュータはそのための空間(メモリ)を準備します。使い終わったら、「利用終了」と言って、そのメモリを解放します。
この解放をせずにずっとメモリを使い続けると、無駄にメモリを使ってしまいます。
でも逆に、「利用終了」としてメモリを解放したのに、うっかり誤って使ってしまうことがあります。
これが「Use-After-Free」で、「すでに解放(free())されたメモリ」を、再び読み書きしてしまう危険なバグです。
これにより、予期しない動作や、攻撃者によるコード実行(RCE)が可能になります。
なぜUse-After-Freeは危険なのか
解放された領域は、次のmalloc()で他のデータに再利用される可能性があります。
それを知らずに古いポインタを使うと、他の変数を上書きしたり、機密情報を読み取ったりできます。
Use-After-Freeは権限昇格・サンドボックス脱出・Webブラウザの攻撃などに頻繁に使われます。
難しいですね。簡単に説明すると・・・
1.学校でロッカーを借りたとします。
2.使い終わったので、ロッカーを返しました(=free)。
3.でも次の日、またそのロッカーを勝手に開けて中身を入れました。
でももうそのロッカーは別の人が使っているかもしれません!
勝手に中に入れると、他人の持ち物を壊してしまうかも。
これと同じことが、コンピュータの中でも起きてしまいます。
もっとわかりやすく説明すると
※イメージです。(^^;
発生原因とC言語の例で理解しよう
1.プログラム
ファイル名はたとえば use_after_free.c にします。
nano use_after_free.c
下記のコードを貼り付けて、Ctrl + O → Enter → Ctrl + X で保存します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *data = malloc(32);
strcpy(data, "機密データ");
free(data); // メモリを解放
printf("再利用中: %s\n", data); // ← これは危険!
return 0;
}
この例では、free()したポインタ data をまだ使っています。
このあと他の変数でメモリが再利用されると、予測できないバグや情報漏洩が発生します。
2.コンパイル
gcc -o use_after_free use_after_free.c -no-pie -fno-stack-protector
3.実行
./use_after_free
この実行結果について
再利用中: :◆
は、Use-After-Freeの典型的な症状です。
なぜ変な文字(:◆)が表示されたかと言うと、
free(data); によってメモリを解放したあと、printf("再利用中: %s\n", data); で、「もう使ってはいけない場所」を読み取ろうとしたためです。
実際の攻撃例とエクスプロイト手法
・tcache poisoning + Use-After-Free により、任意のメモリアドレスに書き込み可能。
・解放後にチャンクを再確保して、攻撃用のデータを書き込む。
Use-After-Freeを防ぐには
対策方法 |
説明 |
free()後にポインタを NULL にする |
二度使いを防ぐ |
メモリ管理ライブラリを使う |
smart pointerやValgrindで検出可能 |
ASAN(AddressSanitizer)を使う |
実行時にUse-After-Freeを検出してクラッシュさせる |
ダングリングポインタに注意 |
解放されたポインタを他の変数に残さない |
ハッカーがつかうUse-After-Freeとは 解放済みメモリの落とし穴と悪用手法をやさしく解説のまとめ
Use-After-Freeは、一度free()で解放したメモリ領域を、うっかりもう一度使ってしまう危険なバグです。これにより、思わぬ動作やデータ破壊、さらには攻撃者によるコード実行が起こる可能性があります。C言語などで手動でメモリ管理する場面でよく見られます。
解放したメモリは絶対に再利用しないことを守るだけでも、多くのバグを防ぐことができます。