Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-46215-POC — Exploit pour CVE-2026-46215, une élévation de privilèges locale par use-after-free dans le DRM GEM du noyau Linux. Utilise des courses, du slab spraying et une réécriture de fichier de type Dirty Pipe pour transformer un utilisateur non privilégié du nœud de rendu en root sans mot de passe. | Kitploit
Outils/GitHubGitHub/0xcyberstan/cve-2026-46215-poc
Escalade de PrivilègesCriminalistique MémoireAnalyse des VulnérabilitésExploitationCTFApprentissage et ÉducationExploitation de Binaires
GitHub0xcyberstan/cve-2026-46215-poc

CVE-2026-46215-POC

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →

À propos

Exploit pour CVE-2026-46215, une élévation de privilèges locale par use-after-free dans le DRM GEM du noyau Linux. Utilise des courses, du slab spraying et une réécriture de fichier de type Dirty Pipe pour transformer un utilisateur non privilégié du nœud de rendu en root sans mot de passe.

Voir le dépôt
1123il y a 2 moisPas encore vérifié
Partager

CVE-2026-46215 : Utilisation après libération de change_handle GEM DRM (élévation de privilèges locale non privilégiée)

Élévation de privilèges locale via une utilisation après libération dans l'ioctl noyau DRM DRM_IOCTL_GEM_CHANGE_HANDLE (drm_gem_change_handle_ioctl, numéro d'ioctl 0xD2). Accessible par tout utilisateur ayant accès à un nœud de rendu (/dev/dri/renderD*, accordé à la session active par systemd-logind sur toutes les distributions de bureau majeures). La chaîne dans ce dépôt transforme l'UAF en root sans mot de passe à partir d'un utilisateur non privilégié.

  • CVE : CVE-2026-46215 (HAUTE, 7.8, AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
  • Introduit : v6.18-rc1, commit 53096728b891 (« drm: Add DRM prime interface to reassign GEM handle », David Francis / AMD), ajouté pour le travail CRIU d'AMD
  • Corrigé dans : 6.18.32, 7.0.9, 7.1-rc3 (amont 5e28b7b94408). L'ioctl est également désactivé en amont dans 7.1 à cause de ce problème et de conditions de course apparentées.
  • Affecté : v6.18-rc1 jusqu'aux versions corrigées ci-dessus

Attribution

Ce bug a été signalé pour la première fois par Puttimet Thammasaeng, qui détient le crédit amont Reported-by sur le correctif. Je l'ai découvert et signalé indépendamment à [email protected] le 2026-04-12. Mon rapport a été reconnu et transmis aux mainteneurs, mais le rapport antérieur est celui crédité en amont. Ce dépôt contient ma propre analyse et mon exploit.

Writeup : https://cyberstan.co.uk

Statut de divulgation

Le correctif se trouve dans les noyaux stables publiés (6.18.32 et 7.0.9 et ultérieurs). Ce dépôt a été publié après que les correctifs ont été largement disponibles.

Le bug

drm_gem_change_handle_ioctl() déplace un objet GEM d'un handle à un autre mais n'ajuste jamais obj->handle_count. Il saute également drm_vma_node_allow/revoke et les callbacks d'ouverture/fermeture du pilote. Comme handle_count reste à 1, un GEM_CLOSE concurrent sur l'ancien handle le fait passer à 0 et libère l'objet alors que le nouveau handle le référence toujours dans l'IDR. Ce handle pendant est l'utilisation après libération, déréférencée plus tard dans drm_gem_object_release_handle().

Chaîne d'exploitation

  1. Mettre en concurrence GEM_CHANGE_HANDLE contre GEM_CLOSE pour obtenir un handle pendant.
  2. Récupérer l'emplacement slab de l'objet libéré avec un tableau pipe_buffer pulvérisé (feng shui msg_msg pour conditionner kmalloc-512, puis tuyaux remplis par splice).
  3. Fuiter pipe_buf_ops via un ioctl d'info du pilote : obj->size (décalage 216) chevauche pipe_buf[5].ops, donnant un pointeur noyau et la base KASLR.
  4. FLINKer le handle pendant pour que obj->name (décalage 224) atterrisse sur pipe_buf[5].flags et mette PIPE_BUF_FLAG_CAN_MERGE (name = 16 = 0x10).
  5. Écrire dans les tuyaux pour fusionner dans le cache de pages et écraser un fichier en lecture seule (style DirtyPipe). La cible est /etc/passwd, root devient sans mot de passe.

Les décalages sont vérifiés via pahole et sont spécifiques à la disposition entre 6.18 et 7.0. Surcharger les définitions GEM_* / PIPEBUF_* pour d'autres noyaux.

Fichiers

  • poc.c – l'exploit. Compiler statiquement avec -lpthread.
  • run_exploit.sh – construit le PoC et un initramfs minimal, le lance dans QEMU.

Prérequis hôte

qemu-system-x86_64, gcc, busybox (statique), fakeroot, cpio, gzip. KVM (/dev/kvm) est recommandé ; la condition de course est bien plus fiable avec.

Construire un noyau de test

L'exploit nécessite une cible vulnérable construite avec des options spécifiques :

  • CONFIG_KASAN doit être DÉSACTIVÉ. KASAN met en quarantaine les slabs libérés et bloque la récupération par pulvérisation de tuyaux, donc l'exploit ne fonctionnera pas contre une construction KASAN.
  • Un pilote DRM qui expose les champs size/name aux décalages attendus : virtio_gpu (utilisé dans la démo) ou nouveau.
  • CONFIG_DRM=y, CONFIG_DRM_VIRTIO_GPU=y, CONFIG_DEVTMPFS=y, CONFIG_BLK_DEV_INITRD=y.

Étapes :

  1. Extraire un arbre source 6.18 à 7.0 (ou tout arbre qui échoue à la vérification de correctif ci-dessous).
  2. Configurer les options ci-dessus et s'assurer que CONFIG_KASAN n'est pas défini.
  3. make -j"$(nproc)" bzImage, produisant arch/x86/boot/bzImage.

La démo démarre avec nokaslr pour que le pointeur fuité soit déterministe. La fuite vainc KASLR par elle-même, donc KASLR activé fonctionne aussi, l'adresse varie simplement à chaque démarrage.

Vérifier si un arbre est vulnérable ou corrigé

Regarder dans drivers/gpu/drm/drm_gem.c, fonction drm_gem_change_handle_ioctl().

Vérification rapide :

root@kitploit:~
awk '/^int drm_gem_change_handle_ioctl/,/^}/' \
    drivers/gpu/drm/drm_gem.c | grep -c handle_count
  • 0 signifie VULNÉRABLE (pas de gestion de refcount).
  • non nul signifie CORRIGÉ.

Par structure :

  • Vulnérable : prend file_priv->prime.lock, un seul idr_alloc(&file_priv->object_idr, obj, ...), puis idr_remove() sur l'ancien handle. Pas de drm_gem_object_handle_get.
  • Corrigé : insertion en deux phases (idr_alloc puis idr_replace(NULL) pour détacher l'ancien handle), l'objet réel n'étant échangé qu'une fois les opérations prime réussies.

Exécuter l'exploit

root@kitploit:~
./run_exploit.sh /chemin/vers/bzImage

Il construit poc.c, l'emballe dans un initramfs, et démarre QEMU avec -device virtio-gpu-pci et nokaslr. Le PoC s'exécute en tant qu'uid 1000 (non privilégié), puis le script affiche /etc/passwd avant et après et vous laisse un shell. Quittez la VM avec poweroff -f ou Ctrl-A X.

Sortie attendue

root@kitploit:~
[!] Race won (iter 977): handle=132049
[!] KASLR: pipe_buf_ops = 0xffffffff82428400
[!] EXPLOIT SUCCESSFUL
[!] FLINK: 16 = 0x10
[*] /etc/passwd:
    root::0:0:pwned:/root:/bin/sh
[!] LPE CONFIRMED
[!] root account is now passwordless

Un fichier /etc/passwd en lecture seule (chmod 444) appartenant à root est écrasé par un processus non privilégié. La ligne root: perd son champ mot de passe.

Fiabilité

  • Environ 99 % par démarrage lors des tests (99/100 sur 100 démarrages frais, plus 53/53 lors d'exécutions antérieures). Le PoC réessaie en interne : en cas de mauvaise fuite, il relance la course pour un nouvel objet pendant plutôt que de ré-pulvériser un emplacement mort, jusqu'à 200 tours, chaque tour durant quelques dizaines de millisecondes. La plupart des démarrages gagnent dès la première course ; le pire observé a utilisé 11 des 200 tours.
  • Rare (environ 1 %) mode de défaillance : une course perdante entrelace l'état du noyau et bloque la VM (gel silencieux, aucun verdict affiché). C'est inhérent à une UAF par course noyau. Si une exécution n'affiche pas de verdict en environ 30 secondes, redémarrez et réessayez.

Confirmer le correctif

Reconstruire contre un arbre corrigé (6.18.32, 7.0.9, 7.1-rc3 ou ultérieur, ou tout arbre passant la vérification de correctif ci-dessus) et réexécuter :

root@kitploit:~
./run_exploit.sh /chemin/vers/bzImage-corrigé

Contre le noyau corrigé, l'exploit ne devrait jamais atteindre « EXPLOIT SUCCESSFUL » : la course ne libère plus l'objet sous le nouveau handle, donc la fuite ne renvoie jamais un pointeur noyau valide.

Avertissement

Publié à des fins de recherche et de défense après le déploiement des correctifs amont. Fourni en l'état. Exécutez-le uniquement sur des VM que vous contrôlez.

Télécharger l’outil