Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
smiiiiiiiiiiiiiiii — Un interrupt molto molto molto molto molto molto molto lungo | Kitploit
Strumenti/GitHubGitHub/xoreaxeaxeax/smiiiiiiiiiiiiiiii
Analisi delle VulnerabilitàExploitHacking HardwareSicurezza Hardware
GitHubxoreaxeaxeax/smiiiiiiiiiiiiiiii

smiiiiiiiiiiiiiiii

Un interrupt molto molto molto molto molto molto molto lungo

Vedi Repository
1585723 giorni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

smiiiiiiiiiiiiiiii

Sfruttare la System Management Mode con un interrupt molto molto molto molto molto molto molto lungo.

Panoramica

Si scopre che puoi rompere la SMM — l'ambiente di esecuzione sicuro e ultra privilegiato che gira invisibilmente in background su ogni CPU x86 — con niente più di un'istruzione macchina oscenamente lunga.

La SMM richiede che tutti i core siano o nella SMM o fuori dalla SMM allo stesso tempo. Il suo modello di sicurezza non funziona senza questo — quando un thread entra nella SMM, costringe anche tutti gli altri a entrarci.

Per rompere questo, tutto ciò di cui abbiamo bisogno è qualcuno troppo occupato per accorgersi che dovrebbe unirsi alla SMM.

Funziona più o meno così:

root@kitploit:~
core 0 - avvia un'istruzione lunga
       |
       |
       |
core 1 - invita il core 0 alla smm
       |
       |
       |
core 1 - entra nella smm
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - aspetta il core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - molla
core 1 - fa cose segrete nella smm
core 1 - termina la smm
       |
       |
       |
core 0 - entra nella smm

A questo punto, il core 1 è fuori dalla SMM mentre il core 0 è dentro, permettendo al core 1 di attaccare il core 0. Ecco il problema: perché questo funzioni abbiamo bisogno di un'istruzione molto, molto, mooolto lunga — più lunga di quanto qualsiasi istruzione dovesse mai durare. La maggior parte delle istruzioni macchina su una CPU moderna sono veloci: add richiede 1 ciclo. Per far sì che il core 1 smetta di aspettare il core 0, abbiamo bisogno di un'istruzione sul core 0 che richieda circa 4.000.000.000 di cicli — oltre 1 secondo di tempo reale.

Il Timeout di Un Secondo

Il firmware x86 esegue il seguente codice quando un core della CPU entra nella SMM:

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

    CpuPause ();
  }

Il codice attende che tutti i core entrino nella SMM, o fino a 1 secondo, a seconda di quale si verifichi per primo. Per far eseguire a un core il codice SMM mentre un altro core continua a eseguire fuori dalla SMM, abbiamo bisogno che quel core esterno rimanga non interruptibile per l'intero secondo — un SMI viene catturato al confine di un'istruzione, quindi qualsiasi intervallo tra due istruzioni permette all'SMI pendente di trascinare il core nella SMM. Il ritardo quindi deve essere una singola istruzione: un'operazione non interruptibile che sopravviva al rendezvous di un secondo.

Proof-of-Concept

Ci sono molti modi per raggiungere la proibita istruzione da 1 secondo, e l'approccio esatto varierà da piattaforma a piattaforma. Ma, in linea di massima: trova un indirizzo MMIO ad alta latenza, e poi convinci la CPU a leggerlo il più lentamente possibile — abusa di una regione non documentata che risponde alle letture al rallentatore, usa il load più largo che l'ISA ti offre per spostare quanti più byte possibile attraverso di essa in una singola istruzione, e lascia che gli altri core competano per lo stesso bus per rallentarla ulteriormente. Una lettura, un'istruzione, e la CPU rimane bloccata a mantenerla per la maggior parte di un secondo.

Il proof-of-concept fornito è ottimizzato per un Zen 3 Ryzen 7 5800H, dove un load xmm largo da MMIO lento a 0xfcc68860 si blocca abbastanza a lungo da rompere il rendezvous di tutti i core:

root@kitploit:~
mov     $0xfcc68860, %rsi   ; l'indirizzo MMIO di destinazione
vmovdqu (%rsi), %xmm0       ; il load molto, molto lungo

Il PoC sfrutta questo mettendo due core l'uno contro l'altro. Un core viene tenuto fuori dalla SMM dall'istruzione lunga — un loop stretto sul load molto lento:

root@kitploit:~
/* il core vittima: gira sul load da ~1 secondo, troppo occupato per rispondere all'SMI */
for (;;)
    asm volatile ("vmovdqu (%0), %%xmm0" :: "r"(mmio) : "xmm0");

Nel frattempo un altro core arma i contatori SMI per-core:

root@kitploit:~
#define MSR_PERF_CTL0  0xc0010200        /* MSR di selezione evento perf core AMD */
#define MSR_PERF_CTR0  0xc0010201        /* il contatore a 48 bit abbinato      */

for (int cpu = 0; cpu < ACTIVE_CPUS; cpu++) {
    msr_write(cpu, MSR_PERF_CTL0, 0x43002b);  /* EN | OS | USR | evento 0x2b */
    msr_write(cpu, MSR_PERF_CTR0, 0);         /* azzera il conteggio            */
}

Poi scatena una tempesta di SMI:

root@kitploit:~
asm volatile ("outb %%al, $0xb2" :: "a"(0));  /* calcia la porta 0xb2 -> #SMI    */

E legge il totale di ogni core:

root@kitploit:~
/* ...scatena la tempesta, poi leggi il totale di ogni core... */
uint64_t delta = smi_max - smi_min;
if (delta)
    puts("!!! un core è girato fuori dalla SMM");

Se i conteggi divergono, significa che un core ha continuato a girare fuori dalla SMM mentre gli altri venivano trascinati dentro — ha mancato gli SMI che gli altri hanno servito.

Per illustrare meglio questo, possiamo eseguire il proof-of-concept dietro una GUI inutilmente appariscente e del tutto inutile, tracciando i contatori SMI su ogni core, per guardarli eseguire in perfetto sincronismo finché un core estremamente ritardato rompe la loro sincronizzazione richiesta:

Divergenza dei contatori SMI in azione

L'unica garanzia della SMM — che nient'altro giri mentre lei è in esecuzione — crolla davanti a una singola istruzione assurda e lunga.

Sfruttamento

La sicurezza della SMM si basa su un'assunzione semplice: mentre è in esecuzione, nient'altro lo è.

Ci sono 100+ CVE TOCTOU della SMM in giro: un handler della SMM controlla un valore nella memoria condivisa, poi lo usa. Tutto ciò di cui hai bisogno per lo sfruttamento è riscrivere quel valore tra il controllo e l'uso, e sei dentro la SMM. Ma questi problemi restano dormienti e in gran parte non patchati nel mondo reale, a causa di un'assunzione: lo sfruttamento richiede qualcosa che modifichi la memoria condivisa mentre la SMM è in esecuzione, e a causa del rendezvous della SMM nessun core della CPU è fuori dalla SMM per lanciare un attacco. L'unico modo per entrare era una periferica con capacità DMA che scrivesse alle spalle della CPU — accesso fisico, un dispositivo dannoso — quindi l'intera classe viene liquidata come un problema hardware.

La desincronizzazione degli SMI rimuove il prerequisito che manteneva sicura la piattaforma: un core esterno, senza accesso fisico o hardware richiesto, può ora girare mentre la SMM è in esecuzione — e le CVE dormienti diventano sfruttabili dal software.

Mitigazioni

Probabilmente non ce ne sono, ed è questo che rende questo problema un po' più interessante dei problemi SMM tradizionali. Mantieni il timeout, e il rendezvous viene facilmente rotto. Rimuovi il timeout, e un core legittimamente bloccato appende la piattaforma al primo SMI. Aumenta il timeout, e uccidi le prestazioni sulle piattaforme multi-core che sono costrette a mettere a riposo tutti i core a ogni ingresso nella SMM. Non è chiaro quale sia la strada migliore da seguire, o se esista anche solo una strada da seguire.

Fino ad allora, la soluzione consigliata è di non eseguire alcuna istruzione lunga.

Porting sulla tua piattaforma

Il vmovdqu predefinito a 0xfcc68860 nel proof-of-concept è un punto lento su questa macchina — un Zen 3 Ryzen 7 5800H — e probabilmente da nessun'altra parte. Per rompere il rendezvous sulla tua macchina, dovrai riottimizzare l'istruzione lunga così che lo stallo sopravviva al tuo timeout SMM. Alcuni suggerimenti su come fare:

  1. Punta al tuo MMIO. Trova una regione MMIO lenta sulla tua piattaforma con mmiotic.
  2. Allarga la lettura. Passa da -r xmm → ymm → zmm finché lo stallo supera il timeout del rendezvous.
  3. Cambia l'istruzione. Se nessuna singola lettura MMIO è abbastanza lenta, hai bisogno di un'istruzione patologicamente lunga diversa; la asm-hall-of-shame mostra come trovarle.

Compilazione

root@kitploit:~
make          # compila smiiiiiiiiiiiiiiii

Utilizzo

Le impostazioni predefinite sono ottimizzate per una sola macchina. Su qualsiasi cosa tranne un Zen 3 Ryzen 7 5800H, non aspettarti divergenze finché non riottimizzi l'istruzione lunga — vedi Porting sulla tua piattaforma.

Esegui lo strumento per scatenare ripetutamente l'istruzione molto-molto-lunga mentre osservi il contatore SMI di ogni core per una divergenza:

root@kitploit:~
sudo ./smiiiiiiiiiiiiiiii          # predefinito: -r xmm a 0xfcc68860

Flag:

FlagPredefinitoDescrizione
-r xmm|ymm|zmmxmmLarghezza del registro vettoriale per la lettura MMIO temporizzata (16/32/64 byte). Se non viene osservato alcun delta nel conteggio SMI, lo strumento consiglia di passare alla dimensione successiva.
-a <phys-addr>0xfcc68860Indirizzo fisico di destinazione per il loop di temporizzazione MMIO (esadecimale 0x... o decimale).
-h, --help—Stampa l'utilizzo ed esce.

Riferimenti

  • DEF CON 2026 – Weaponizing Uselessness

Autore

smiiiiiiiiiiiiiiii è uno sforzo di ricerca di Christopher Domas (@xoreaxeaxeax).

Scarica lo strumento