[BRLY-2022-014]
Arbitrary write vulnerability in PEI module leads to arbitrary code execution during PEI phase.
BINARLY efiXplorer team

Summary

BINARLY efiXplorer team has discovered a arbitrary write vulnerability in PEI module allowing a possible attacker to execute arbitrary code during PEI phase.

Vulnerability Information

  • BINARLY internal vulnerability identifier: BRLY-2022-014
  • Intel PSIRT assigned CVE identifier: CVE-2022-32579
  • AMI PSIRT assigned CVE identifier: CVE-2022-40246
  • FwHunt rule: BRLY-2022-014
  • CERT/CC assigned case number: VU#158026
  • CVSS v3.1: 7.2 High AV:P/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Affected Intel firmwares with confirmed impact by Binarly team

Device/Firmware File Name SHA256 (File PE32 section) File GUID
Intel NUC M15 BCTGL357 v0072 (Latest) SbPei d827182e5f9b7a9ff0b9d3e232f7cfac43b5237e2681e11f005be627a49283a9 c1fbd624-27ea-40d1-aa48-94c3dc5c7e0d

Potential impact

A potential attacker can write one byte by arbitrary address at the time of the PEI phase (only during S3 resume boot mode) and influence the subsequent boot stages. This can lead to the mitigasions bypassing, physical memory contents disclosure, discovery of any secrets from any Virtual Machines (VMs) and bypassing memory isolation and confidential computing boundaries. Additionally, an attacker can build a payload which can be injected into the SMRAM memory.

Vulnerability description

The pseudocode for vulnerable function is shown below.

  • function address: 0xFFAC3E32
  • this function is notifier for EFI_PEI_END_OF_PEI_PHASE_PPI
int __cdecl EfiPeiEndOfPeiPhaseNotifier(EFI_PEI_SERVICES **PeiServices)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  if ( ((*PeiServices)->GetBootMode(PeiServices, &BootMode) & 0x80000000) == 0
    && BootMode == BOOT_ON_S3_RESUME
    && ((*PeiServices)->LocatePpi(PeiServices, &EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID, 0, 0, &Ppi) & 0x80000000) == 0 )
  {
    DataSize = 4;
    if ( (Ppi->GetVariable(Ppi, L"AmiCspGlobalNvsPtrVar", &gVariableGuid, 0, &DataSize, &Data) & 0x80000000) == 0 )
    {
      Ptr = Data;
      PcdPpi = LocatePcdPpi();
      *Ptr = PcdPpi->Get8(0xF2);
    }
  }
  __outbyte(0x43, 0x54);
  __outbyte(0x41, 0x12);
  return 0;
}

As we can see from the pseudocode, in the case of BOOT_ON_S3_RESUME boot mode, the PCD byte for tocken number 0xF2 will be written by address specified in the NVRAM variable AmiCspGlobalNvsPtrVar.

Potencial attacker can overwrite the value of the NVRAM variable AmiCspGlobalNvsPtrVar thereby controlling the address at which the fixed byte will be written (on the tested platform, PcdPpi->Get8(0xF2) will return 0x01).

The value of the AmiCspGlobalNvsPtrVar variable is set in the AmiCspGlobalNvsDxe (file GUID: 5bd4977a-580f-4f1a-b3c2-5198e6dcbeea) DXE driver with attributes EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS. This happens during the main boot, so before entering S3 mode, the attacker cannot change the value of the AmiCspGlobalNvsDxe variable programmatically.

However, attacker able to rewrite NVRAM region on SPI flash with programmer:

  • this can be done while sleeping (it is enough to change the value of the variable and not change the attributes of the variable)
  • this can be done while with the device turned off (in this case, the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute must be present)

Exploitation steps

This vulnerability has been tested on the Windows 10 operating system.

Below are the steps to reproduce.

  • Make sure that the operating system supports the S3 sleep mode (powercfg /a)

  • If the S0 Low Power Idle mode is enabled instead of S3, you need to create the following registry value:

    Subkey Value Name Value Type Value Data
    HKLM\SYSTEM\CurrentControlSet\Control\Power PlatformAoAcOverride REG_DWORD 0
  • Sleep

  • Change the NVRAM variable AmiCspGlobalNvsPtrVar value by hardware overwriting the SPI flash memory

    • the new value is a pointer that you need to rewrite at the end of PEI phase
  • Wake up

Disclosure timeline

This bug is subject to a 90 day disclosure deadline. After 90 days elapsed or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.

Disclosure Activity Date
Intel PSIRT is notified 2022-05-04
Intel PSIRT confirmed reported issue 2022-07-28
Intel PSIRT assigned CVE number 2022-07-28
Intel PSIRT provide patch release 2022-08-01
BINARLY public disclosure date 2022-08-10

Acknowledgements

BINARLY efiXplorer team