efiXplorer: Hunting UEFI Firmware NVRAM Vulnerabilities
Binarly’s efiXplorer has become an industry standard to research UEFI Firmware internals.
One major improvement was added to the search and detection logic of one of the major security problems in UEFI firmware - System Management Mode (SMM) call-outs. In addition, the current release aims to reduce false positives and improve results for detecting potentially vulnerable code patterns.
The image below is an example of the detection of a high-impact SMM call-out vulnerability (BRLY-2021-031/CVE-2021-43323) in the Insyde SDK reference code, a serious security issue with previously discussed industry-wide impact.
In a recent blog we discussed the presence of NVRAM vulnerabilities on Lenovo devices. As we keep finding these classes of vulnerabilities at scale in high numbers, we decided to look deeper into how to find and hunt them with efiXplorer.
NVRAM is a very interesting place to look because it’s one of the prevalent attack surfaces exposing very dangerous ways to directly influence the data used by the UEFI firmware is Non-Volatile Random-Access Memory (NVRAM). These attack vectors were already discussed in our research “efiXplorer: Hunting for UEFI Firmware Vulnerabilities at Scale with Automated Static Analysis” at Black Hat Europe 2020.
As shown in the figure below, the Binarly efiXplorer team disclosed the following vulnerabilities in the last 12 months.
|Stack overflow via double GetVariable in DXE driver
Stack-based Buffer Overflow
|Stack overflow via double GetVariable in PEI module
Stack-based Buffer Overflow
|Arbitrary write to memory, which is controlled via NVRAM
|Execution of arbitrary code pointed to by the value of the NVRAM variable
Improper Input Validation
The complexity of the code in UEFI firmware related to NVRAM data is huge. The attack surface opens at early-boot phases and survives even when the operating system gets control.
The image below shows a classic example of a vulnerability that arises from incorrect usage of gRT->GetVariable() API , which leads to a stack buffer overflow during execution.
There have already been multiple reports about the PlatformLang variable issue, but unfortunately, we continue to see related security problems. A vulnerability checker based on efiXplorer plugin that automatically detects a potential misuse of GetVariable() service was released two years ago at Black Hat Europe 2020. The most recent version of efiXplorer includes a more fine tuned vulnerability detection logic to find such vulnerabilities in UEFI firmware.
Let’s dive deeper to understand how efiXplorer works to detect NVRAM related security problems. The efiXplorer contains features to retrieve information about the arguments of EFI services related to GetVariable(), SetVariable(), SmmGetVariable(), SmmSetVariable() and detect vulnerable code patterns that occurs in the result of improper usage of GetVariable API.
To simplify the code analysis process, all information about NVRAM variables is shown on a special window (chooser) with the title efiXplorer: NVRAM. Those features work when used against both individual EFI modules and when analyzing the entire firmware image with efiXloader.
The following information can be extracted from NVRAM services calls and present in efiXplorer: NVRAM window (as shown on previous figure):
- Address of service call
- Variable name
- Variable GUID (Vendor GUID)
- Service (GetVariable, SetVariable, SmmGetVariable, SmmSetVariable)
That simplifies a lot of identification and navigation processes on potentially interesting code places. Also we can use the efiXplorer: services window (chooser) to identify the calls that operate with NVRAM variables and analyze their context.
But when analyzing the whole UEFI firmware image, the number of service calls used to work with NVRAM variables may exceed a thousand. Thus, adding the ability to filter on the arguments of these services was necessary.
Vulnerabilities hunting with “efiXplorer: NVRAM”
Vulnerabilities associated with NVRAM can be divided into the following categories:
- Incorrect use of sequential GetVariable/SetVariable calls, which can lead to arbitrary code execution or memory leaks
- Transfer of pointers via NVRAM, which can cause an arbitrary read/write or execution of arbitrary code
- Transfer configuration flags/values via NVRAM, which can cause the enabling of debug features or the disabling of security features during the boot process
- Usage of incorrect attributes when calling the SetVariable function (for example, if a variable is supposed to have only NON_VOLATILE | BOOTSERVICE_ACCESS attributes, but NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS was passed to the SetVariable function)
Let's take a closer look at all classes of vulnerabilities enumerated above and how we can automate their detection with efiXplorer.
Double GetVariable with DataSize controlled by the attacker
These vulnerabilities occur because the DataSize argument can be modified during the GetVariable call, but this fact may not be taken into account later. See the code from the EDK2 reference implementation for a better understanding of the root cause of these security issues https://github.com/tianocore/edk2/blob/b0fd3097193d9c6825979e57e78e6278163bfd8e/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c#L2480.
This class of vulnerabilities can be automatically detected by efiXplorer in different types of the EFI modules including pre-EFI(PEI), DXE and SMM. On the figure below is the result of the efiXplorer analyzer in the case of the BRLY-2022-027 vulnerability detection which leads to classical stack overflow in pre-EFI boot phase.
However, the heuristics Binarly developed in efiXplorer sometimes can lead to false positives as it happened with the second finding from the previous figure. If efiXplorer detects the issue, it must be manually validated because there are no guarantees it will lead to an exploitable vulnerability.
The double GetVariable detection module is already in use by researchers. Researchers from ESET improved the double GetVariable detection in efiXplorer and found three vulnerabilities in Lenovo firmware.
SentinelOne security researchers are integrating efiXplorer into their firmware threat hunting tool Brick.
As practice shows, security issues related to incorrect use of the GetVariable() and SetVariable() API are still very common in the majority of enterprise devices including servers. Nevertheless, these issues are very reliable and can be exploited by an attacker to execute arbitrary payload code. Binarly researchers have already demonstrated how these vulnerabilities can be exploited by developing proof-of-concepts (PoCs) to show potential impact to vendors.
Here are a few examples for HP (BRLY-2021-005), Insyde/BullSequana (BRLY-2021-021) and HP (BRLY-2021-003) devices. The figure below demonstrates the reliability of such security issues in terms of exploitation.
Transfer of pointers via NVRAM
Passing pointers through NVRAM variables can often have consequences that developers are not aware of. At Black Hat USA 2022, we disclosed two high-impact vulnerabilities in AMI code that are demonstrating the nature of such security problems:
- BRLY-2022-014/CVE-2022-32579 (SbPei) - allows an attacker to write a controllable byte in memory pointed to by an NVRAM variable.
- BRLY-2022-015/CVE-2022-34345 (AMITSE) - allows an attacker to execute code pointed to by an NVRAM variable.
The efiXplorer does not currently provide automated discovery of such vulnerabilities, but the researcher can use efiXplorer to scope and identify potentially vulnerable code patterns as shown on the figure below.
Transfer configuration flags/values via NVRAM
An excellent example of such vulnerabilities are the latest findings by ESET on Lenovo devices. Consider a vulnerability in the BootOrderDxe driver (a detailed description of the vulnerability is provided in the previous blog).
As we can see from the figure, if gRT->GetVariable() will not return any error, the Secure Boot will be disabled, leading to security problems. Thus, to disable Secure Boot on a target system, an attacker could create a 1-byte BootOrderSecureBootDisable NVRAM variable (with a value 0 or 1) from the operating system and reboot the machine. This vulnerability can be exploited from the operating system if hook-based sanity checks in the NvramSmm module are not applied to this variable.
The efiXplorer can help to scope the potential point-of-interest to identify vulnerabilities in EFI modules related to NVRAM variables access attributes as shown on the figure below.
Another way to find and scope such vulnerable code patterns is to use efiXplorer: protocols window (chooser). This approach allow us to pinpoint which modules the potential problems are based to dive deeper to investigate potential security issues as shown on the figure below.
Usage of incorrect attributes when calling the SetVariable function
Let’s dive into the last class of the problems in this blog related to SetVariable() API function. Assume that an NVRAM variable is supposed to have only NON_VOLATILE | BOOTSERVICE_ACCESS attributes, but NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS was passed to the SetVariable() or SmmSetVariable() function. Then, if no filtering (common sanity check) is applied to this variable in SMM, the attacker will be able to change its value from the operating system and such behavior can lead to high-impact security issues.
To scope potentially vulnerable code places we can use efiXplorer. In the image below, efiXplorer identifies and displays the attributes and NVRAM variable names that require extra attention.
Scalable vulnerability analysis requires automation. Binarly REsearch teams are committed to research on identifying problems and providing useful tools for security researchers and product security teams to help fix these repeatable firmware security failures for the industry.
Our backlog is full of new features, so stay tuned for the upcoming releases!