
Exploit pour CVE-2024-21980 ciblant le firmware AMD SEV afin de déchiffrer la mémoire arbitraire des invités SEV-SNP mis hors service via un bypass de l'application du tampon de commande.
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 après qu'il a été désaffecté.
Testé sur la version 1.55.16 (la plus récente au moment de la rédaction).
Le firmware SEV possède une table appelée master_handler_table contenant des pointeurs de fonction pour toutes les commandes, avec quelques propriétés supplémentaires pertinentes pour les commandes. Deux de ces propriétés supplémentaires sont cmd_buf_type et snp_cmd_buf_enforcement. cmd_buf_type détermine si le tampon de commande doit être copié vers et/ou depuis la mémoire hôte. snp_cmd_buf_enforcement détermine si ces opérations de copie doivent être soumises à des vérifications confirmant que la mémoire soutenant le tampon de commande est dans l'état FIRMWARE ou DEFAULT. Les commandes pour lesquelles cmd_buf_type est CMD_BUF_OUTPUT_ONLY, CMD_BUF_INPUT_AND_OUTPUT, ou CMD_BUF_INPUT_AND_OUTPUT_ERROR devraient toutes avoir snp_cmd_buf_enforcement défini à true. Sinon, l'écriture en retour de la sortie de la commande pourrait causer une corruption de la mémoire dans la zone couverte par le RMP. snp_cmd_buf_enforcement est true pour toutes ces commandes sauf une - SEV_MCMD_ID_ATTESTATION : Cette commande a cmd_buf_type défini à CMD_BUF_INPUT_AND_OUTPUT_ERROR, mais a aussi snp_cmd_buf_enforcement défini à false. En conséquence, il est possible d'exécuter SEV_MCMD_ID_ATTESTATION avec un tampon de commande pointant vers une mémoire couverte par le RMP et que cette mémoire soit corrompue une fois la sortie écrite en retour.
Je ne vois pas pourquoi SEV_MCMD_ID_ATTESTATION aurait besoin d'être une exception, il me semble plausible que cela puisse être une erreur de frappe/de copier-coller.
SEV_MCMD_ID_ATTESTATION n'écrit que dans un seul champ length (4 octets) dans le tampon de commande, donc ce sont les seuls octets que nous pouvons utiliser pour corrompre la mémoire. SEV_MCMD_ID_ATTESTATION écrit toujours la même valeur - 0x000000d0. Heureusement, il n'y a pas d'exigences d'alignement sur le tampon de commande, donc nous pouvons décaler le tampon de commande de manière répétée pour corrompre une plus grande plage de mémoire contiguë. Nous allons utiliser cela pour corrompre les 16 premiers octets d'une page de contexte d'invité avec un motif statique. Ces 16 premiers octets contiennent la graine de clé UMC, donc en la forçant à une valeur statique, nous pouvons forcer la clé de chiffrement de l'invité à une valeur statique.
L'exploit fourni ici est largement basé sur celui que j'ai fourni pour SWPSIRT-2684/CVE-2023-31355.
Pour exploiter la vulnérabilité, nous pouvons exécuter les étapes suivantes :
SEV_MCMD_ID_ATTESTATION. Gardez cet invité en cours d'exécution.0x2000 pour l'invité victime. Toute autre adresse dans la zone couverte par le RMP ferait également l'affaire, bien qu'une adresse fixe soit utile pour le débogage.0x2000 pour l'invité attaquant. Cela doit être la même adresse que celle utilisée à l'étape 1.SNP_DBG_ENCRYPT pour déchiffrer la mémoire de l'invité victime en utilisant la page de contexte de l'invité attaquant. Cela réussira car l'invité victime et l'invité attaquant partagent une graine de clé UMC.L'impact ici devrait être au moins le même qu'avec SWPSIRT-2684. Il n'est pas clair pour moi à ce stade si ce bogue peut être utilisé pour déchiffrer la mémoire d'un invité en cours d'exécution avant qu'il ne soit désaffecté.
snp_cmd_buf_enforcement devrait être défini à true pour SEV_MCMD_ID_ATTESTATION.
Fait intéressant, les correctifs de support hôte Linux KVM n'ont pas besoin d'être mis à jour car ils listent déjà SEV_CMD_ATTESTATION_REPORT dans sev_cmd_buf_writable comme une commande qui nécessite que son tampon de commande soit dans l'état FIRMWARE. Des changements peuvent ou non être nécessaires pour d'autres hyperviseurs.