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-53360-POC — PoC pour CVE-2026-53360 : lecture/écriture hors limites du tas déclenchée par l'invité dans la gestion des changements d'état de page KVM SEV-SNP (PSC). | Kitploit
Outils/GitHubGitHub/0xcyberstan/cve-2026-53360-poc
Criminalistique MémoireAnalyse des VulnérabilitésExploitationSécurité MatérielleExploitation de Binaires
GitHub0xcyberstan/cve-2026-53360-poc

CVE-2026-53360-POC

PoC pour CVE-2026-53360 : lecture/écriture hors limites du tas déclenchée par l'invité dans la gestion des changements d'état de page KVM SEV-SNP (PSC).

Voir le dépôt
13il y a 2 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-53360 : Dépassement de tas PSC SEV-SNP de KVM

Preuve de concept pour une lecture et une écriture hors limites dans le tas (heap out‑of‑bounds) dans la gestion du changement d’état de page (PSC) SEV‑SNP de KVM. Un invité SEV‑SNP malveillant force le noyau hôte à parcourir un tableau d’entrées PSC au‑delà de la fin de son allocation de slab. Cela divulgue la disposition des objets kmalloc-cg-32 voisins et écrit une petite valeur contrôlée dans ceux-ci, et l’invité peut le répéter aussi souvent qu’il le souhaite.

Article complet : https://cyberstan.co.uk/sev-snp-oob/

CVECVE-2026-53360
ComposantSupport hôte KVM SNP, arch/x86/kvm/svm/sev.c
Introduit9b54e248d264 (première gestion PSC KVM SNP, mai 2024, ~v6.10)
Corrigédb3f219 (mainline, mai 2026, Cc: stable), étiqueté Fixes: 4af663c
Signalé[email protected], 8 avril 2026
AffectéChemin hôte SEV‑SNP uniquement. KVM n’active pas PSC pour les invités SEV‑ES simples.

Impact

Tout invité SEV‑SNP peut corrompre le tas du noyau hôte et lire des informations sur sa disposition en envoyant une requête PSC malformée. Il s’agit de la direction invité → hôte : SEV‑SNP est conçu pour protéger l’invité d’un hôte non fiable, mais l’hôte doit quand même se défendre contre un invité malveillant, et ce gestionnaire ne le fait pas.

Prérequis

Cela nécessite du matériel SEV‑SNP réel. Cela ne peut pas être reproduit sur Intel, et la virtualisation imbriquée ne vous donnera pas d’invité SNP.

Matériel :

  • Une puce serveur AMD EPYC avec SEV‑SNP : Milan (7003) ou plus récent, c’est‑à‑dire Genoa (9004), Bergamo, Siena ou Turin. SEV‑SNP est du silicium exclusif EPYC. Il n’est pas présent sur Ryzen ou Threadripper, et il n’y a pas d’équivalent Intel ici (Intel utilise TDX).
  • Matériel nu. Une instance cloud nue fonctionne aussi (Vultr, AWS *.metal, Hetzner AX et similaires).
  • Dans le BIOS, activez SEV, SEV‑ES, SEV‑SNP, SME, IOMMU et SVM. Les clouds nus gérés activent généralement ces options par défaut.

Noyau hôte :

  • Compilez‑le avec KASAN pour que les accès hors limites soient signalés. Sans KASAN, le bogue corrompt toujours la mémoire hôte, mais il n’est pas affiché. Testé sur 6.11.11.
    root@kitploit:~
    CONFIG_KASAN=y
    CONFIG_KASAN_GENERIC=y
    CONFIG_KVM=y
    CONFIG_KVM_AMD=y
    CONFIG_KVM_AMD_SEV=y
    CONFIG_CRYPTO_DEV_SP_PSP=y
    
  • Démarrez avec SNP activé et KASAN en mode multi‑coup pour que chaque accès soit enregistré :
    root@kitploit:~
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • Confirmez que l’hôte est prêt :
    root@kitploit:~
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

Espace utilisateur hôte :

  • Un QEMU compatible SNP. Le QEMU standard ne gère pas SNP, compilez donc le fork AMD :
    root@kitploit:~
    git clone https://github.com/AMDESE/qemu.git
    cd qemu && git checkout snp-latest
    mkdir build && cd build
    ../configure --target-list=x86_64-softmmu && make -j$(nproc)
    
  • Firmware OVMF SNP depuis https://github.com/AMDESE/AMDSEV/releases.

Invité :

  • N’importe quel invité Linux qui démarre sous SNP, avec build-essential et linux-headers-$(uname -r) installés pour pouvoir y compiler le module.

Le bogue

Les invités SEV‑SNP communiquent avec l’hôte via le GHCB, une page partagée de 4 Ko. Une requête PSC définit SW_EXITCODE à SVM_VMGEXIT_PSC (0x80000010), pointe SW_SCRATCH vers un descripteur et place la longueur du descripteur dans SW_EXITINFO2.

Le descripteur est un struct psc_buffer : un en‑tête de 8 octets suivi d’un tableau d’entrées de 8 octets. Il n’y a pas de champ de comptage explicite. L’hôte traite les entrées de hdr->cur_entry à hdr->end_entry, toutes deux contrôlées par l’invité.

root@kitploit:~
struct psc_hdr {
        u16 cur_entry;
        u16 end_entry;
        u32 reserved;
} __packed;                     /* 8 octets */

struct psc_entry {
        u64 cur_page    : 12;
        u64 gfn         : 40;
        u64 operation   :  4;
        u64 pagesize    :  1;
        u64 reserved    :  7;
} __packed;                     /* 8 octets */

Un invité GHCB v2+ est censé garder sa zone scratch à l’intérieur du tampon partagé de 2032 octets du GHCB, afin que l’hôte puisse réutiliser son mappage existant. (2032 - 8) / 8 = 253 entrées tiennent, ce qui correspond au maximum du protocole VMGEXIT_PSC_MAX_COUNT (253). Ce nombre n’a de sens que lorsque le tampon est réellement le tampon partagé.

Si l’invité pointe la zone scratch en dehors du GHCB, l’hôte ne peut pas utiliser son mappage, donc setup_vmgexit_scratch() alloue un tampon séparé de la taille demandée par l’invité. SNP ne devrait jamais emprunter ce chemin, mais rien ne l’empêche :

root@kitploit:~
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);   /* len == exit_info_2, contrôlé par l'invité */

len vient directement de l’invité, et GFP_KERNEL_ACCOUNT place l’allocation dans les caches kmalloc-cg-N comptabilisés par cgroup. Demandez exit_info_2 = 24 et vous obtenez une allocation de 24 octets dans l’emplacement kmalloc-cg-32 de 32 octets : de la place pour l’en‑tête plus deux entrées. Tout ce qui dépasse entries[1] est la mémoire d’un autre objet.

Ensuite, snp_begin_psc() vérifie le nombre d’entrées par rapport à la constante du protocole, et non par rapport au tampon réellement alloué :

root@kitploit:~
idx_end = hdr->end_entry;

if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {   /* vérifie 253, PAS la taille du tampon */
        snp_complete_psc(svm, ...);
        return 1;
}

for (idx = idx_start; idx <= idx_end; idx++) {
        entry_start = entries[idx];       /* OOB dès que idx >= 2 */
        ...
}

Avec un tampon de 24 octets, il n’existe que deux entrées, mais la vérification autorise end_entry jusqu’à 252. Mettez‑le à 252 et la boucle parcourt environ 2 Ko au‑delà de l’allocation, à travers les objets slab voisins.

Primitives

Chaque pas au‑delà de la fin réinterprète les 8 octets suivants de la mémoire slab comme un psc_entry et les exécute dans le code PSC. Cela donne trois choses :

  1. Oracle de lecture. L’hôte lit le qword adjacent uniquement pour le décoder, extrayant entry.gfn et entry.operation de la mémoire que le tampon ne possédait pas. C’est la lecture hors limites (slab-out-of-bounds) que KASAN détecte.
  2. Écriture contrainte. Si l’entrée décodée semble valide et est distribuée comme un KVM_HC_MAP_GPA_RANGE, le code de terminaison écrit dans le même emplacement OOB : entries[idx].cur_page = entry.pagesize ? 512 : 1. Une ou deux petites valeurs dans les 12 bits de poids faible d’un mot que l’invité choisit, répétable.
  3. Oracle d’échec. Si l’entrée ne se valide pas, la réponse dans SW_EXITINFO2 signale l’index auquel elle s’est arrêtée. En augmentant end_entry une par une, on divulgue, slot par slot, si la mémoire adjacente a été décodée comme une opération nulle ou comme quelque chose qui a échoué, ce qui suffit pour trouver les limites des objets et distinguer zéro de non‑zéro.

Chaque VMGEXIT réalloue le tampon scratch, donc des requêtes répétées atterrissent dans différents slots de la free list et permettent à l’invité de balayer les voisins plutôt que de rester bloqué sur un seul. Mis ensemble, cela donne une divulgation de la disposition du tas, l’écriture contrainte ci‑dessus, et une use‑after‑free entre les requêtes.

Ce que fait le PoC

trigger.c est un module noyau invité. Chargez‑le dans un invité SEV‑SNP et il exécute quatre étapes contre l’hôte depuis un simple insmod :

  • Étape 1 sonde 48 entrées hors limites une par une et construit une carte du tas hôte (mémoire voisine zéro ou non‑zéro).
  • Étape 2 prouve que l’écriture OOB persiste entre les VMGEXIT en écrivant cur_page dans un voisin zéro et en confirmant qu’une requête ultérieure le saute.
  • Étape 3 déclenche une requête avec end_entry=200 et mesure jusqu’où la lecture OOB atteint avant de rencontrer des données non‑nulles.
  • Étape 4 déclenche 200 requêtes avec entries[3..10] hors limites, chacune déclenchant un rapport KASAN sur l’hôte.

Le module alloue une page, la marque déchiffrée avec set_memory_decrypted(), l’utilise comme zone scratch et construit manuellement la requête PSC GHCB. Il se termine avec -EAGAIN pour ne pas rester chargé.

Construction et exécution

1. Lancer un invité SNP

Ajustez les chemins OVMF et du disque à votre configuration :

root@kitploit:~
qemu-system-x86_64 \
    -enable-kvm -cpu EPYC-v4 \
    -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
    -object memory-backend-memfd,id=ram1,size=4G \
    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=0x30000 \
    -smp 4 -m 4G \
    -bios OVMF_SNP.fd \
    -drive file=guest.qcow2,format=qcow2,if=virtio \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

2. Compiler et charger dans l’invité

Copiez trigger.c et Makefile dans l’invité, puis :

root@kitploit:~
make
insmod trigger.ko

Le module vérifie d’abord la présence de SEV‑SNP via CPUID et refuse de s’exécuter ailleurs. Il exécute ses quatre étapes et se décharge (init retourne -EAGAIN, donc il ne reste jamais résident).

3. Surveiller l’hôte

Sur l’hôte :

root@kitploit:~
dmesg | grep -E "KASAN|BUG|snp_begin_psc"

Sortie attendue :

root@kitploit:~
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199

BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199

The buggy address belongs to the object at ffff888XXXXXXXXX
 which belongs to the cache kmalloc-cg-32 of size 32

Un seul insmod a produit 73 rapports KASAN sur l’hôte de test (62 slab‑out‑of‑bounds, 7 slab‑use‑after‑free, 4 use‑after‑free), tous contre kmalloc-cg-32. Hôte de test : AMD EPYC 7443P, Ubuntu 24.04.4, noyau 6.11.11 avec KASAN, invité sous QEMU AMDESE (snp-latest).

Le correctif

Le correctif upstream rejette toute zone scratch hors GHCB pour GHCB v2 et ultérieur dans setup_vmgexit_scratch(), ce qui épingle le tampon à une taille fixe connue, empêchant la boucle de dépasser la fin :

root@kitploit:~
  } else {
+         /* GHCB v2 exige que la zone scratch soit dans le GHCB. */
+         if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
+                 goto e_scratch;
+
          /*
           * La mémoire de l'invité doit être lue dans un tampon noyau, donc
           * limitez la taille

Ces quatre lignes sont db3f219. Elles font partie d’une série plus large qui limite également le nombre d’entrées par rapport à la taille réelle du tampon et relit le descripteur avec READ_ONCE(), ce qui ferme une variante de décalage dans le tampon et une race time‑of‑check/time‑of‑use dans le même gestionnaire.

Fichiers

FichierDescription
trigger.cModule noyau invité qui exécute les quatre étapes du PoC
MakefileCompile trigger.ko avec le noyau invité en cours d’exécution

Dépannage

  • not an SEV-SNP guest : QEMU n’a pas été lancé avec sev-snp-guest, ou le SNP hôte est désactivé.
  • QEMU SEV-SNP not supported : vérifiez /sys/module/kvm_amd/parameters/sev_snp, les paramètres BIOS et les options de démarrage.
  • QEMU LAUNCH_START failed : le PSP n’est pas initialisé. Vérifiez dmesg | grep psp et CONFIG_CRYPTO_DEV_SP_PSP=y.
  • Pas de sortie KASAN : vérifiez CONFIG_KASAN=y et kasan_multi_shot sur la ligne de commande de l’hôte.

Avertissement

Cela corrompt la mémoire du tas du noyau hôte, déclenche KASAN et peut planter l’hôte. Exécutez‑le uniquement sur un hôte de test jetable que vous contrôlez, dans une VM que vous possédez. Ne l’exécutez pas sur une infrastructure partagée ou de production.

Références

  • Article : https://cyberstan.co.uk/sev-snp-oob/
  • CVE‑2026‑53360 (suivez le commit db3f219 sur linux-cve-announce)
  • Correctif : db3f219, auteur Mike Roth, revu par Tom Lendacky, commit par Paolo Bonzini
  • Introduit : 9b54e248d264 ; correctif étiqueté Fixes: 4af663c
  • Spécification GHCB, section 2.1 (SW_SCRATCH doit être dans le tampon partagé du GHCB)

Licence

trigger.c est sous licence GPL‑2.0, correspondant à son MODULE_LICENSE. Voir LICENSE.

Télécharger l’outil
LICENSEGPL‑2.0, correspondant à MODULE_LICENSE du module