Bypass BIOS/UEFI firmware write protection to write to SPI flash memory

For Bootkit: LoJax, MosaicRegressor, TrickBot, etc., viruses that started to infect firmware gradually increased, so I made notes and organized.
All requests to the UEFI firmware stored in the SPI flash chip on the motherboard will go through the SPI controller, which is part of the Platform Controller Hub (PCH) on the Intel platform. The PCI bus configuration space can be accessed through the PCI device driver to obtain the PCH value.

Use I/O commands to access PCI bus configuration space

The CPU in the system accesses the configuration space register through the device number of the PCI device and the register number in the configuration space.

PCI has three independent physical address spaces: device memory address space, I/O address space, and configuration space.
The configuration space is a physical space unique to PCI. Because PCI supports plug and play of devices, PCI devices do not occupy a fixed memory address space or I/O address space, but the operating system determines the base address of their mapping. When the system is powered on, the BIOS detects the PCI bus, determines all the devices connected to the PCI bus and their configuration requirements, and configures the system. Therefore, all PCI devices must realize the configuration space, which can realize the automatic configuration of the parameters and realize the real plug and play.
To access the configuration space of a PCI bus device, you must first find the device. The basic basis for searching is that the configuration space of each PCI device has a specific device number (Device ID) and vendor ID (Vendor ID), which occupy the 00h address of the configuration space. The purpose of searching is to obtain the bus number and device number of the device. The basic process of searching is as follows: write configuration space with I/O commandAddress register (CONFIG_ADDRESS) CF8h, Make its highest bit is 1, bus number and device are 0, function number and register number are 0, that is to I/O port CF8h80000000h; then use I/O command to read the configuration spaceData register (CONFIG_DATA) CFCh. If the register value does not match the Device ID and Vendor ID of the PCI device, the device number/bus number are sequentially incremented, and the above operations are repeated until the device is found. If you cannot find the device after checking all the device numbers/bus numbers (1~5), you should consider the hardware problem. For multi-function devices, as long as the device configuration register corresponds to the function number value, the rest of the steps are the same as for single-function devices.

CONFIG_ADDRESS register format:
31 bits: Enabled bit.
23:16 bit: bus number.
15:11 bit: device number.
10: 8 bits: function number.
7: Bit 2: Configuration space register number.
1: Bit 0: It is always "00". This is because the CF8h and CFCh ports are 32-bit ports.
Insert picture description here
For example, to find a single-function PCI device with a device number of 9054h and a sales company number of 10b5, the program written in VC++ 6.0 is as follows:

char bus;
char device;
 unsigned int ioa0,iod;
 int scan( )
 {
    
    
 bus=0;device=0;
 for(char i=0;i<5;i++) {
    
    
 for(char j=0;j<32;j++) {
    
    
 bus=i; device=j;
 ioa0=0x80000000+bus*0x10000
 +(device*8)*0x100;
 _outpd(0xcf8,ioa0);
 iod=_inpd(0xcfc);
 if (iod0= =0x905410b5) return 0;
 }
 }
 retrn -1
 }

Call the subroutine scan( ), if the return value is -1, the PCI device is not found. If the return value is 0, the PCI device was found. The bus number and device number of the device are respectively in the global variables bus and device, and these two variables can be used to easily access the configuration space of the device, thereby obtaining the allocated resource information.

The processor system resources are divided into IO resources and MMIO resources, so there are also two PCI/PCIe space address correspondences.

References
Introduction to PCI configuration space
https://www.cnblogs.com/wangshide/archive/2012/05/10/2495150.html
"Detailed Explanation of Windows Development Technology" Chapter 16-PCI Device Driver

BIOS control register BIOS_CNTL

The value of the three fields contained in the BIOS control register (BIOS_CNTL):
1. BIOS write enable (BIOSWE)
2. BIOS lock enable (BLE)
3. SMM BIOS write protection disabled (SMM_BWP).
BIOS Lock Enable (BLE), when this function is enabled, the BIOSWE bit will be locked to 0. However, in reality, this protection mechanism is very fragile. When a request is made to set the BIOSWE bit to 1, BIOSWE will be set to 1 first, which is a big problem. First of all, the firmware developer is required to build a special SMI handler. If it does not, the BLE bit is useless. Second, when there is a race condition vulnerability, even if the SMI handler runs normally, it may allow this mechanism to be completely bypassed. To exploit this vulnerability, the attacker needs to start a thread that continuously sets BIOSWE to 1, while another thread writes data to the SPI flash memory.

In order to solve this problem, a new protection mechanism configured through BIOS_CNTL has been applied. It's on the Intel chipsetPlatform Controller Center (PCH) seriesIntroduced in. If its configuration bit is set, only when all kernels are running in system management mode (SMM) and BIOSWE is set to 1, SMM BIOS write protection disabled (SMM_BWP) can allow BIOS firmware to be writable. This mechanism can effectively protect the system from the impact of race condition loopholes. However, as in the case of BLE, SMM_BWP needs to be activated by firmware. Therefore, firmware that fails to properly configure these mechanisms will expose the system to the risk of unauthorized writing to the BIOS area.

The ReWriter_binary.exe in the Sednit team reads the contents of the BIOS control register to select the correct path. It first checks whether BIOSWE has been set. If it is, then enter the write phase. If BIOSWE is disabled, it will check the value of the BLE bit. If it is not set, it will flip the BIOSWE bit and begin to overwrite the modified firmware. If BLE is set, make sure to disable SMM_BWP and take advantage of the above race conditions. If the SMM_BWP bit is 1, it fails.

Insert picture description here

How can an attacker infect UEFI firmware?

Attackers can infect firmware in many ways, but the most common/obvious methods are listed below:
1. Modify unsigned UEFI option ROMs, these ROMs may not be verified according to the configuration
2. Add/modify DXE drivers
3. , Replace/modify the boot manager (using the fallback boot manager)
4. Modify the fallback boot loader EFI/BOOT/bootx64.EFI
5. Add an auxiliary boot loader
6. Bypass SPI write protection and set sensitive memory bits to Disable protection

From the user space with root authority, use the signature bypass to insert the kernel code, and use the hardware abstraction layer interface to access the system management mode. Then find a way to bypass the SPI protection and write directly to one of the early startup phases listed above.

Read and write SPI flash memory

Sednit's ReWriter_read.exe will retrieve the BIOS area base address and its size on the SPI flash memory. This information is contained in the SPI host interface register "BIOS Flash Primary Region". All SPI host interface registers are memory mapped in the Root Composite Register Block (RCRB), and their base address can be retrieved by reading the correct PCI configuration register. Once the BIOS area base address and size information is obtained, the dump tool will read the relevant content of the SPI flash memory and write it to a file on the disk. The SPI reading sequence is as follows:
Insert picture description here

These operations will be repeated until all data is read from the SPI flash memory. Then, ReWriter_read verifies the size of the dump image. It will parse the mirrored Flash descriptor to obtain the memory range of the BIOS, Gigabit Ethernet (GbE) and Management Engine (ME) areas. Adding the size of these three areas allows the dump tool to calculate the size of the complete content in the SPI flash memory. If the image size is equal to the size information obtained by reading the BIOS Flash main area register, the image is considered valid.

The data in the UEFI image is stored in the form of a volume using the firmware file system (FFS). As the name suggests, it is a file system customized for storing firmware images. The volume contains files identified by GUIDs. Each file usually consists of multiple parts, one of which contains the real PE/COFF executable file, that is, the UEFI image. Use UEFITool to see related information. The SPI writing sequence is as follows:
Insert picture description here

references

An analysis report of a "wild" UEFI rootkit
https://www.freebuf.com/news/185828.html
Introduction to PCI configuration space
https://www.cnblogs.com/wangshide/archive/2012/05/10/2495150 .html
" Windows Development Technology Detailed Explanation " Chapter 16 PCI Device Driver

Guess you like

Origin blog.csdn.net/qq_43312649/article/details/111179517