【注意】このサイトに記載されていることを他人に試すことは「不正アクセス禁止法」に該当する場合があります。詳しくはこちらから

ハッカーがつかうUse-After-Freeとは 解放済みメモリの落とし穴と悪用手法をやさしく解説

ペネトレーションテスト&バグバウンティ

普段の生活で、貸りたものを返してから、また勝手に使ったら怒られますよね。
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言語などで手動でメモリ管理する場面でよく見られます。
解放したメモリは絶対に再利用しないことを守るだけでも、多くのバグを防ぐことができます。