Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
smiiiiiiiiiiiiiiii — Uma interrupção muito muito muito muito muito muito muito longa. | Kitploit
Ferramentas/GitHubGitHub/xoreaxeaxeax/smiiiiiiiiiiiiiiii
Análise de VulnerabilidadesExploraçãoHacking de HardwareSegurança de Hardware
GitHubxoreaxeaxeax/smiiiiiiiiiiiiiiii

smiiiiiiiiiiiiiiii

Uma interrupção muito muito muito muito muito muito muito longa.

Ver Repositório
158528há 2 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

smiiiiiiiiiiiiiiii

Explorando o System Management Mode com uma interrupção muito muito muito muito muito muito muito longa.

Visão geral

Acontece que você pode quebrar o SMM — o ambiente de execução seguro e ultraprivilegiado que roda invisivelmente em segundo plano em cada CPU x86 — com nada mais do que uma instrução de máquina absurdamente longa.

O SMM exige que todos os núcleos estejam em SMM ou fora do SMM ao mesmo tempo. Seu modelo de segurança não funciona sem isso — quando uma thread entra no SMM, ela faz todas as outras entrarem também.

Para quebrar isso, tudo o que precisamos é de alguém ocupado demais para perceber que deveria entrar no SMM.

Funciona mais ou menos assim:

core 0 - start a long instruction
       |
       |
       |
core 1 - invite core 0 to smm
       |
       |
       |
core 1 - enter smm
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - wait for core 0
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
       |
core 1 - give up
core 1 - do secret smm stuff
core 1 - finish smm
       |
       |
       |
core 0 - join smm

Neste ponto, o core 1 está fora da SMM enquanto o core 0 está dentro, permitindo que o core 1 ataque o core 0. Eis o detalhe: para que isso funcione, precisamos de uma instrução muito, muito, muuuuito longa — mais longa do que qualquer instrução jamais deveria levar. A maioria das instruções de máquina em uma CPU moderna é rápida: add leva 1 ciclo. Para fazer o core 1 desistir de esperar pelo core 0, precisamos de uma instrução no core 0 que leve cerca de 4.000.000.000 de ciclos — mais de 1 segundo de tempo real.

O Timeout de Um Segundo

O firmware x86 executa o seguinte código quando um núcleo da CPU entra na SMM:

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

    CpuPause ();
  }

O código aguarda que todos os núcleos entrem no SMM, ou por até 1 segundo, o que ocorrer primeiro. Para fazer com que um núcleo execute código SMM enquanto outro núcleo permanece executando fora do SMM, precisamos que esse núcleo externo permaneça ininterrupto durante o segundo inteiro — um SMI é capturado em um limite de instrução, portanto qualquer lacuna entre duas instruções permite que o SMI pendente puxe o núcleo para o SMM. O atraso, portanto, precisa ser uma única instrução: uma operação ininterrupta que dure mais que o encontro de um segundo.

Prova de Conceito

Existem muitas maneiras de alcançar a instrução proibida de 1 segundo, e a abordagem exata varia de plataforma para plataforma. Mas, em linhas gerais: encontre um endereço MMIO de alta latência e então convença a CPU a ler dele o mais lentamente possível — abuse de uma região não documentada que responde a leituras de forma extremamente lenta, use a carga mais ampla que a ISA lhe oferecer para mover o máximo de bytes possível através dela em uma única instrução, e deixe os outros núcleos disputarem o mesmo barramento para torná-la ainda mais lenta. Uma leitura, uma instrução, e a CPU fica presa segurando-a por boa parte de um segundo.

A prova de conceito fornecida é ajustada para um Zen 3 Ryzen 7 5800H, onde uma carga ampla de xmm a partir de MMIO lento em 0xfcc68860 trava por tempo suficiente para quebrar o encontro de todos os núcleos:

mov     $0xfcc68860, %rsi   ; the target MMIO address
vmovdqu (%rsi), %xmm0       ; the very, very long load

O PoC explora isso colocando dois núcleos um contra o outro. Um núcleo é mantido fora do SMM pela instrução longa — um loop apertado no carregamento muito lento:

/* the victim core: spin on the ~1-second load, too busy to answer the SMI */
for (;;)
    asm volatile ("vmovdqu (%0), %%xmm0" :: "r"(mmio) : "xmm0");

Enquanto isso, outro núcleo arma os contadores SMI por núcleo:

#define MSR_PERF_CTL0  0xc0010200        /* AMD core perf event-select MSR */
#define MSR_PERF_CTR0  0xc0010201        /* the paired 48-bit counter      */

for (int cpu = 0; cpu < ACTIVE_CPUS; cpu++) {
    msr_write(cpu, MSR_PERF_CTL0, 0x43002b);  /* EN | OS | USR | event 0x2b */
    msr_write(cpu, MSR_PERF_CTR0, 0);         /* zero the count            */
}

Em seguida, dispara uma tempestade de SMIs:

asm volatile ("outb %%al, $0xb2" :: "a"(0));  /* kick port 0xb2 -> #SMI    */

E lê o tally de cada core de volta:

/* ...fire the storm, then read every core's tally back... */
uint64_t delta = smi_max - smi_min;
if (delta)
    puts("!!! a core ran outside SMM");

Se as contagens divergirem, isso significa que um núcleo continuou em execução fora do SMM enquanto os outros foram trazidos para dentro — ele perdeu os SMIs que os demais atenderam.

Baixar ferramenta