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-2024-21978-poc — Exploit pour la vulnérabilité du firmware AMD SEV-SNP CVE-2024-21978, permettant le déchiffrement de la mémoire arbitraire d'un invité via la corruption mémoire des pages de contexte. | Kitploit
Outils/GitHubGitHub/freax13/cve-2024-21978-poc
Outils de Chiffrement/DéchiffrementCriminalistique MémoireAnalyse des VulnérabilitésExploitationTests d'IntrusionSécurité MatérielleExploitation de Binaires
GitHubfreax13/cve-2024-21978-poc

cve-2024-21978-poc

Exploit pour la vulnérabilité du firmware AMD SEV-SNP CVE-2024-21978, permettant le déchiffrement de la mémoire arbitraire d'un invité via la corruption mémoire des pages de contexte.

Voir le dépôt
93il y a 1 anPas 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

Vulnérabilité du firmware SEV

Ce dépôt contient un exploit pour une vulnérabilité dans le firmware SEV. L'exploit permet de déchiffrer la mémoire arbitraire d'un invité SEV-SNP en cours d'exécution.

Testé sur la version 1.55.16 (la plus récente au moment de la rédaction).

Cause racine

Le champ nv_paddr de la commande SEV_INIT_EX peut être utilisé pour donner un bloc de mémoire au firmware, afin qu'elle puisse être utilisée à la place de la mémoire flash persistante. Si SEV-SNP est activé, cette mémoire doit être dans l'état FIRMWARE. Le firmware vérifie cela une seule fois lors de l'exécution de la commande SEV_INIT_EX. Par la suite, le firmware suppose que cette mémoire est dans l'état FIRMWARE et y écrit sans aucune vérification supplémentaire.

L'hypothèse selon laquelle la mémoire est toujours dans l'état FIRMWARE n'est pas toujours correcte ; rien n'empêche l'hôte de la faire repasser dans l'état HYPERVISOR à l'aide de la commande SNP_PAGE_RECLAIM. Une fois les pages dans l'état HYPERVISOR, elles peuvent passer dans d'autres états, par exemple CONTEXT. Même si les pages ne sont plus dans l'état FIRMWARE, le firmware écrira sur ces pages, brisant ainsi l'intégrité requise par certains états de page.

Exploit

Nous pouvons exploiter cette corruption mémoire en ciblant les pages CONTEXT. Les pages CONTEXT sont une cible puissante, mais il y a quelques problèmes :

  1. Les pages CONTEXT sont chiffrées avec une clé différente de celle des autres mémoires. Par conséquent, il n'est pas facile de contrôler le texte clair même si l'on pouvait contrôler le texte chiffré.
  2. Nous n'avons pas beaucoup de contrôle sur la mémoire écrite par le firmware.

La corruption mémoire remplit effectivement la page CONTEXT avec des données aléatoires, il n'est donc pas facile de corrompre réellement les pages CONTEXT d'une manière utile pour l'attaquant. Pour contourner ce problème, nous pouvons déclencher le bug à plusieurs reprises pour provoquer la corruption et utiliser la commande SNP_GUEST_STATUS pour relire les champs pertinents de la page CONTEXT corrompue jusqu'à ce que nous observions des valeurs utiles.

La commande SNP_DBG_DECRYPT peut être utilisée pour déchiffrer la mémoire d'un invité SEV-SNP avec la politique DEBUG activée. Si nous pouvons fabriquer un CONTEXT de sorte qu'il ait le drapeau DEBUG défini et contienne l'ASID d'un autre invité, nous pouvons l'utiliser pour déchiffrer la mémoire de l'autre invité même si celui-ci n'a pas la politique DEBUG définie.

Il s'avère que SNP_DBG_DECRYPT ignore la plupart des champs de la page CONTEXT ; il ne vérifie que gctx->guest.asid, gctx->guest.policy_snp et gctx->guest.guest_flags. La probabilité que ces champs soient corrects après la corruption mémoire n'est pas élevée, mais elle n'est pas non plus impossible. La bonne nouvelle est aussi que nous pouvons lire tous ces champs à l'aide de la commande GUEST_STATUS.

En conclusion, nous pouvons exploiter le bug avec les étapes suivantes :

  1. Faire passer nv_paddr dans l'état FIRMWARE à l'aide de l'instruction rmpupdate.
  2. Exécuter la commande SEV_INIT_EX.
  3. Faire repasser nv_paddr dans l'état HYPERVISOR à l'aide de la commande SNP_RECLAIM_PAGE.
  4. Créer une ou plusieurs pages CONTEXT à nv_paddr.
  5. Amener le firmware à écrire sur nv_paddr à l'aide de la commande SEV_PDH_GEN. Cela corrompt les pages CONTEXT.
  6. Utiliser la commande GUEST_STATUS pour vérifier si SNP_DBG_DECRYPT réussirait ; sinon, revenir à l'étape 5. Le principal goulot d'étranglement ici est que les ASID sont stockés dans un entier 32 bits, mais il y a beaucoup moins d'ASID valides (509 ou 1006 selon le processeur), il faudra donc un assez grand nombre de tentatives pour y arriver.

L'exploit passe la plupart de son temps sur les étapes 5 et 6. Les chances de réunir toutes les bonnes conditions sont d'environ 1/20 000 000 sur un EPYC Milan et nous pouvons effectuer environ 100 tentatives par seconde, nous nous attendons donc à obtenir les bonnes conditions environ une fois tous les deux jours (Attention : les calculs ne sont que des approximations et j'ai peut-être fait une erreur quelque part, mais anecdotiquement, une fois tous les deux jours semble à peu près juste). Nous pouvons accélérer cela en n'attaquant pas seulement une page CONTEXT à la fois, mais trois pages CONTEXT à nv_paddr, nv_paddr+4096 et nv_paddr+8192 (SEV_PDG_GEN corrompra trois pages). Avantageusement, ces étapes peuvent être effectuées avant de lancer l'invité victime et ne doivent réussir qu'une seule fois pour attaquer un nombre arbitraire d'invités (noter que le PoC n'attaque actuellement qu'un seul invité cependant).

Impact

Bien que je n'aie pas encore pu tester cela, je crois qu'une fois qu'un attaquant a utilisé cette vulnérabilité pour divulguer les clés de communication de la plateforme de machine virtuelle de l'invité, il devrait pouvoir envoyer des messages d'invité au firmware au nom de l'invité et utiliser cela pour demander des rapports d'attestation. Cela viole un principe clé de SEV-SNP selon lequel seul l'invité devrait pouvoir demander des rapports d'attestation.

Atténuation

Quelques commandes (par exemple SNP_RECLAIM_PAGE, SNP_GCTX_CREATE, RING_BUFFER, peut-être plus encore ? peut-être toutes par sécurité ?) qui acceptent une page FIRMWARE devraient vérifier si celle-ci chevauche nv_paddr et échouer si c'est le cas.

Atténuations liées à la mise à niveau

J'ai une autre préoccupation, dont je ne suis pas sûr qu'elle soit valable et j'aimerais beaucoup avoir votre avis : si je comprends bien, le firmware SEV peut être mis à niveau sans interrompre les invités en cours d'exécution. Cela implique pour moi qu'il serait possible de conserver la page CONTEXT corrompue d'une ancienne version vulnérable du firmware vers une nouvelle version corrigée. Serait-il possible de démarrer sur une version vulnérable plus ancienne, d'effectuer l'exploit décrit ci-dessus, de mettre à niveau et de valider le nouveau firmware corrigé, de lancer l'invité avec le nouveau firmware (afin que l'ancienne version du firmware n'apparaisse pas dans le rapport d'attestation), puis d'utiliser la page CONTEXT corrompue créée avec l'ancien firmware pour attaquer l'invité créé avec la nouvelle version ? Un consommateur des rapports d'attestation créés par le nouvel invité serait-il en mesure de savoir que l'ancienne version du firmware était en cours d'exécution à un moment donné avant le lancement du nouvel invité ? Si ce n'est pas le cas, des mesures d'atténuation supplémentaires sont-elles nécessaires pour empêcher que cela se produise ?

Utilisation du PoC

  1. Appliquer les correctifs du dossier linux-patches à la pointe de https://github.com/AMDESE/linux/commits/snp-host-v10. Compiler, installer et démarrer le noyau.
  2. Exécuter le PoC.
    root@kitploit:~
    root@server:~/sev-exploit# cargo run --release
        Finished release [optimized] target(s) in 0.12s
        Running `target/release/sev-exploit`
    Corrupt guest context page so that ASID is in range 1..510
    Smallest ASID: 0x0000001f iterations: 14052175 zeros: 10539628 unique asids: 31500727 elapsed time: 1d 19h 20m 31s
    Creating VM with same ASID
    [03, 00, 00, 00, 00, 00, 00, 00, 11, 0f, a0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, f0, 51, a5, 03, 3f, 69, 6b, 93, e8, d8, 61, 0d, 2e, 5a, 45, f1, ea, 6d, bf, 49, fe, e4, a9, 2d, 8d, af, 76, 5e, 2e, 56, e0, fa, a9, b3, a7, e0, bc, 09, d9, 4f, 28, 5c, 9f, 84, d2, 7e, 34, eb, ea, 3f, 29, 88, 30, 01, 28, 65, 8b, 73, 3c, 84, 00, ae, 4a, 74, a2, 7a, d1, c7, 4f, 63, 7f, 72, 7b, 3b, 2f, 08, b3, 1a, 8c, 99, 1b, ad, b5, 1d, 42, 0b, 4d, 98, d4, 7d, c1, 0b, d6, 2f, b4, 6c, 6b, 51, a2, 92, 17, 3b, 01, e8, 82, 11, 1e, cb, cb, a2, 8f, c9, b0, 52, 1d, 1d, b7, d2, 25, 8d, 32, a9, 7a, 6f, 86, e4, 40, 44, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 80, 00, 88, 00, 00, 00, 00, ee, ff, 00, 00, f0, ff, ff, ff, ff, ff, ff, ff, ff, 3f, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, <cut off zeros>]
    thread 'main' panicked at src/main.rs:170:13:
    not yet implemented: use the leaked secrets to send guest messages
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

Notez qu'il est normal que l'exploit s'exécute pendant une durée importante (de l'ordre de quelques heures si vous avez de la chance, de quelques jours sinon). L'exécution sur un EPYC Genoa sera probablement plus rapide car il y a presque deux fois plus d'ASID valides.

Pendant les étapes 5 et 6, le PoC affiche quelques métriques :

  • "Smallest ASID" : L'ASID le plus petit rencontré jusqu'à présent. Il s'agit simplement d'une métrique de contrôle de cohérence pour s'assurer que nous rencontrons des ASID de plus en plus petits au fil du temps.
  • "iterations" : Cette métrique est incrémentée chaque fois que le bug est déclenché.
  • "zeroes" : Dans environ 1/4 des cas, la page CONTEXT est dans un état où le firmware considère qu'aucun ASID ne lui a encore été attribué. Dans ces cas, SNP_GUEST_STATUS retournera 0 dans le champ ASID.
  • "unique asids" : Une autre métrique de contrôle de cohérence pour s'assurer que les ASID sont aléatoires et ne se répètent pas après un certain temps.
  • "elapsed time" : Durée écoulée depuis le lancement du PoC.

Dans la plupart des cas, la mise hors service des pages CONTEXT corrompues provoque un crash du firmware (très probablement ici). Pour autant que je sache, les crashes du firmware provoquent une réinitialisation de tout le système. Pour éviter de tels crashes, les correctifs du noyau empêchent que les pages CONTEXT soient mises hors service. L'un des inconvénients est que le module noyau ccp ne peut pas être déchargé. Une fois le PoC démarré, tout le système doit être redémarré avant de pouvoir relancer le PoC (que le PoC ait réussi ou ait été interrompu).

Télécharger l’outil
  • Lancer (et éventuellement exécuter) un invité victime en utilisant l'ASID corrompu dans la page CONTEXT corrompue. Garder une trace de la page des secrets. Cela est possible car le firmware SEV suit les ASID actifs en interne et ne vérifie pas les pages CONTEXT actives pour détecter les doublons.
  • Utiliser la page CONTEXT corrompue pour exécuter SNP_DBG_DECRYPT sur la page des secrets de l'invité victime.