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
smiiiiiiiiiiiiiiii — Une très très très très très très très longue interruption | Kitploit
Outils/GitHubGitHub/xoreaxeaxeax/smiiiiiiiiiiiiiiii
Analyse des VulnérabilitésExploitationHacking MatérielSécurité Matérielle
GitHubxoreaxeaxeax/smiiiiiiiiiiiiiiii

smiiiiiiiiiiiiiiii

Une très très très très très très très longue interruption

Voir le dépôt
15856il y a 22 joursVérifié par Kitploit

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

smiiiiiiiiiiiiiiii

Exploitation du System Management Mode avec une interruption très très très très très très très longue.

Aperçu

Il s'avère que l'on peut casser le SMM — l'environnement d'exécution sécurisé et ultra privilégié qui tourne invisiblement en arrière-plan de chaque CPU x86 — avec rien de plus qu'une instruction machine absurdement longue.

Le SMM exige que tous les cœurs soient soit dans le SMM, soit hors du SMM en même temps. Son modèle de sécurité ne fonctionne pas sans cela — lorsqu'un thread entre dans le SMM, il force tous les autres à y entrer aussi.

Pour casser cela, tout ce dont nous avons besoin est quelqu'un de trop occupé pour remarquer qu'il est censé rejoindre le SMM.

Cela fonctionne à peu près comme ceci :

root@kitploit:~
core 0 - démarre une instruction longue
       |
       |
       |
core 1 - invite core 0 dans le smm
       |
       |
       |
core 1 - entre dans le smm
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - attend core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - abandonne
core 1 - fait des trucs secrets dans le smm
core 1 - termine le smm
       |
       |
       |
core 0 - rejoint le smm

À ce stade, core 1 est hors du SMM pendant que core 0 y est, ce qui permet à core 1 d'attaquer core 0. Voici le piège : pour que cela fonctionne, nous avons besoin d'une instruction très, très, très longue — plus longue que n'importe quelle instruction n'était censée prendre. La plupart des instructions machine sur un CPU moderne sont rapides : add prend 1 cycle. Pour que core 1 abandonne l'attente de core 0, nous avons besoin d'une instruction sur core 0 qui prend environ 4 000 000 000 de cycles — plus d'une seconde de temps réel.

Le délai d'une seconde

Le firmware x86 exécute le code suivant lorsqu'un cœur de CPU entre dans le SMM :

root@kitploit:~
  for (Timer = StartSyncTimer ();
       !IsSyncTimerTimeout (Timer, mTimeoutTicker) && SyncNeeded;
       )
  {
    mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled ();
    if (mSmmMpSyncData->AllApArrivedWithException) {
      break;
    }

    CpuPause ();
  }

Le code attend que tous les cœurs entrent dans le SMM, ou jusqu'à 1 seconde, selon ce qui se produit en premier. Pour qu'un cœur exécute du code SMM pendant qu'un autre cœur continue d'exécuter hors du SMM, nous avons besoin que ce cœur externe reste non interruptible pendant toute la seconde — un SMI est pris à une frontière d'instruction, donc tout écart entre deux instructions laisse le SMI en attente tirer le cœur dans le SMM. Le délai doit donc être une seule instruction : une opération non interruptible qui survit au rendez-vous d'une seconde.

Preuve de concept

Il existe de nombreuses façons d'atteindre l'instruction interdite d'une seconde, et l'approche exacte variera selon la plateforme. Mais, en gros : trouvez une adresse MMIO à haute latence, puis convainquez le CPU de la lire aussi lentement que possible — abusez d'une région non documentée qui répond aux lectures au ralenti, utilisez la charge la plus large que l'ISA vous offre pour déplacer autant d'octets que possible en une seule instruction, et laissez les autres cœurs se disputer le même bus pour la ralentir davantage. Une lecture, une instruction, et le CPU reste bloqué dessus pendant la majeure partie d'une seconde.

La preuve de concept fournie est réglée pour un Zen 3 Ryzen 7 5800H, où une charge xmm large depuis un MMIO lent à 0xfcc68860 bloque suffisamment longtemps pour casser le rendez-vous de tous les cœurs :

root@kitploit:~
mov     $0xfcc68860, %rsi   ; l'adresse MMIO cible
vmovdqu (%rsi), %xmm0       ; la charge très, très longue

La PoC exploite cela en opposant deux cœurs l'un à l'autre. Un cœur est maintenu hors du SMM par l'instruction longue — une boucle serrée sur la charge très lente :

root@kitploit:~
/* le cœur victime : tourne sur la charge d'environ 1 seconde, trop occupé pour répondre au SMI */
for (;;)
    asm volatile ("vmovdqu (%0), %%xmm0" :: "r"(mmio) : "xmm0");

Pendant ce temps, un autre cœur arme les compteurs SMI par cœur :

root@kitploit:~
#define MSR_PERF_CTL0  0xc0010200        /* MSR de sélection d'événement de performance du cœur AMD */
#define MSR_PERF_CTR0  0xc0010201        /* le compteur 48 bits associé      */

for (int cpu = 0; cpu < ACTIVE_CPUS; cpu++) {
    msr_write(cpu, MSR_PERF_CTL0, 0x43002b);  /* EN | OS | USR | événement 0x2b */
    msr_write(cpu, MSR_PERF_CTR0, 0);         /* remise à zéro du compteur            */
}

Puis déclenche une tempête de SMI :

root@kitploit:~
asm volatile ("outb %%al, $0xb2" :: "a"(0));  /* déclenche le port 0xb2 -> #SMI    */

Et lit le total de chaque cœur :

root@kitploit:~
/* ...déclenche la tempête, puis lit le total de chaque cœur... */
uint64_t delta = smi_max - smi_min;
if (delta)
    puts("!!! un cœur a tourné hors du SMM");

Si les compteurs divergent, cela signifie qu'un cœur a continué de tourner hors du SMM pendant que les autres y étaient tirés — il a manqué les SMI que les autres ont traités.

Pour mieux illustrer cela, nous pouvons exécuter la preuve de concept derrière une interface graphique inutilement tape-à-l'œil et totalement superflue, en suivant les compteurs SMI sur chaque cœur, pour les voir s'exécuter en parfaite synchronisation jusqu'à ce qu'un cœur extrêmement retardé brise leur synchronisation requise :

Divergence des compteurs SMI en action

La seule garantie du SMM — que rien d'autre ne tourne pendant qu'il s'exécute — s'effondre face à une seule instruction absurdement longue.

Exploitation

La sécurité du SMM repose sur une hypothèse simple : pendant qu'il s'exécute, rien d'autre ne tourne.

Il y a 100+ CVE de type TOCTOU SMM là dehors : un gestionnaire SMM vérifie une valeur dans la mémoire partagée, puis l'utilise. Tout ce dont vous avez besoin pour l'exploitation est de réécrire cette valeur entre la vérification et l'utilisation, et vous êtes dans le SMM. Mais ces problèmes restent dormants et largement non corrigés dans la nature, à cause d'une hypothèse : l'exploitation nécessite que quelque chose modifie la mémoire partagée pendant que le SMM s'exécute, et à cause du rendez-vous SMM, aucun cœur de CPU n'est hors du SMM pour lancer une attaque. La seule voie d'entrée était un périphérique capable de DMA écrivant dans le dos du CPU — accès physique, périphérique malveillant — donc toute la classe est considérée comme un problème matériel.

La désynchronisation des SMI supprime la condition préalable qui maintenait la plateforme sûre : un cœur externe, sans accès physique ni matériel requis, peut désormais tourner pendant que le SMM s'exécute — et les CVE dormantes deviennent exploitables depuis le logiciel.

Atténuations

Il n'y en a probablement aucune, ce qui rend ce problème un peu plus intéressant que les problèmes SMM traditionnels. Gardez le délai d'attente, et le rendez-vous est facilement cassé. Supprimez le délai d'attente, et un cœur légitimement bloqué suspend la plateforme au premier SMI. Augmentez le délai d'attente, et vous tuez les performances sur les plateformes multi-cœurs qui sont forcées de mettre tous les cœurs en veille à chaque entrée SMM. On ne sait pas clairement quelle est la meilleure voie à suivre, ni même s'il existe une voie à suivre.

En attendant, la solution de contournement recommandée est de ne pas exécuter d'instructions longues.

Portage vers votre plateforme

Le vmovdqu par défaut à 0xfcc68860 dans la preuve de concept est un point lent sur cette machine — un Zen 3 Ryzen 7 5800H — et probablement nulle part ailleurs. Pour casser le rendez-vous sur votre machine, vous devrez réajuster l'instruction longue pour que le blocage dépasse votre délai d'attente SMM. Quelques conseils pour y parvenir :

  1. Visez votre MMIO. Trouvez une région MMIO lente sur votre plateforme avec mmiotic.
  2. Élargissez la lecture. Montez de -r xmm → ymm → zmm jusqu'à ce que le blocage dépasse le délai d'attente du rendez-vous.
  3. Changez l'instruction. Si aucune lecture MMIO unique n'est assez lente, vous avez besoin d'une autre instruction pathologiquement longue ; le asm-hall-of-shame montre comment les trouver.

Compilation

root@kitploit:~
make          # compile smiiiiiiiiiiiiiiii

Utilisation

Les valeurs par défaut sont réglées pour une seule machine. Sur tout autre chose qu'un Zen 3 Ryzen 7 5800H, n'attendez aucune divergence tant que vous n'avez pas réajusté l'instruction longue — voir Portage vers votre plateforme.

Exécutez l'outil pour déclencher à plusieurs reprises l'instruction très très longue tout en surveillant le compteur SMI de chaque cœur pour détecter une divergence :

root@kitploit:~
sudo ./smiiiiiiiiiiiiiiii          # défaut : -r xmm à 0xfcc68860

Options :

OptionDéfautDescription
-r xmm|ymm|zmmxmmLargeur du registre vectoriel pour la lecture MMIO chronométrée (16/32/64 octets). Si aucun écart de compteur SMI n'est observé, l'outil conseille de passer à la taille suivante.
-a <adresse-physique>0xfcc68860Adresse physique cible pour la boucle de chronométrage MMIO (hexadécimale 0x... ou décimale).
-h, --help—Affiche l'utilisation et quitte.

Références

  • DEF CON 2026 – Weaponizing Uselessness

Auteur

smiiiiiiiiiiiiiiii est un effort de recherche de Christopher Domas (@xoreaxeaxeax).

Télécharger l’outil