Last month, our friends at ESET discovered a few interesting security vulnerabilities in Lenovo devices that allow attackers to bypass Secure Boot and execute malicious code on the device.
As a standard follow up, the Binarly efiXplorer team conducted an investigation to better understand the root cause of these vulnerabilities reported by ESET. Inexplicably, we discovered that at least two of the vulnerabilities in Lenovo’s LEN-94952 bulletin -- CVE-2022-3430 and CVE-2022-3431 -- remain unfixed on fully patched devices a full month after their official disclosure.
The figure below shows an unfixed vulnerability CVE-2022-3431, where BootOrderSecureBootDisable
NVRAM variable has runtime access and can be modified.
After we realized the fix was not correctly applied to all Lenovo product lines used by Binarly customers, we decided to dive deeper into an investigation. (Note: Binarly's efiXplorer plugin for IDA is very useful for detecting security problems related to unprotected runtime access to NVRAM variables).
In the table below, we scope the product lines still at risk for the previously disclosed CVE-2022-3430 and CVE-2022-3431 bugs.
All these product lines are mentioned in Lenovo’s advisory (LEN-94952) as impacted products, but unfortunately, they are not fixed. There is a considerable gap when vendors have multiple products, and different generations of the same product line are affected. The sole use of source code analysis tools makes it difficult to scope impact and identify all affected code bases.
The CVE-2022-3431 vulnerability is present in the BootOrderDxe module inside the 0c629f5b-aa4a-4951-866c-6f3e933ea5ba EFI protocol interface code. Installation of this protocol is shown in the following figure (func1
contains a vulnerable routine).
Let’s dive deeper into func1
function code, where we confirmed vulnerability with high confidence. As we can see in the following figure demonstrates the pretty straightforward boot order dependency with unprotected NVRAM runtime variables.
Where BootOrderSecureBootDisableAction
specifically looks pretty dangerous, as shown below:
And runtime access to BootOrderDualBootMode
variable implemented as shown below (inside BootOrderDualBootModeAction
function):
Let’s dive into the root cause of the security problems present on the figures before: - If the BootOrderSecureBootDisable
variable is set and the Setup variable has a special flag (EFI_BOOT_TYPE
), the SecureBootDisable
function will be executed. - Or, if BootOrderDualBootMode
is set, then regardless of the value of the Setup variable, the SecureBootDisable
function will be executed.
The SecureBootDisable
function uses the EfiL05SecureBootProtocol
to disable Secure Boot in runtime, as shown in the figure below.
On some of the devices, the vulnerability was patched by completely removing BootOrderSecureBootDisableAction
and BootOrderDualBootModeAction
calls from the interface function:
According to Binarly Platform scan results, the Lenovo IdeaPad devices have still not been fixed in the wild, even though it contains the most recent firmware update.
On other devices, the vulnerability was patched by comparing byte values received from the Embedded Controller (EC).
As we can see from the previous figure, the vulnerable function BootOrderSecureBootDisableAction
will be executed only if the byte received the command by the Embedded Controller (EC) command 0x41 will be equal to 0xEE. This implementation is more complicated for the analysis since it relies on the Embedded Controller's information and most likely contains additional validation for confirming a disabling or enabling BootOrderSecureBootDisableAction
. Binarly REsearch still considers such security functionality for Secure Boot as not secure even with this additional EC logic.
The CVE-2022-3430 vulnerability has a very similar problem to the previous CVE-2022-3431; vulnerable code flows contains in the following function:
Following this code logic, a potential attacker can create L05WSBD {a93bb445-9e02-4a13-a7a9-1c35a80525bf}
NVRAM variable with the following structure:
Action (1 byte)
ResetToSystemMode (1 byte)
RestoreFactoryKeys (1 byte)
If Action == 2 (L05_SECURE_BOOT_DISABLE)
the Secure Boot will be disabled inside the L05SecureBootCallback
function.
This vulnerability was fixed by Lenovo, as shown in the following figure (an additional sanity check for Action
has been added):
According to Binarly Platform scan results, the following Lenovo Yoga and Miix devices have still not been fixed in the wild, even though it contains the most recent firmware update.
It’s important for security defenders to understand that integrity checks do not provide code-level visibility and it’s extremely difficult to scope dependencies based on a binary module's hash. That's especially true when indirect dependencies are buried in code abstraction layers.
Disclosing vulnerabilities and informing customers of risks are the most important part of not leaving devices unpatched for years. Understanding the impact and scope of the affected parties at scale is the most challenging part of each vulnerability disclosure.
This research underscores the complexities that cause security problems in the software supply chain, especially in the world of firmware. Recently, Binarly REsearch has discovered outdated versions of OpenSSL in UEFI firmware, a problem that exposes multiple critical components in system firmware. An excellent example of the complexity of scoping affected devices was HP, which had left 30% of its reported vulnerabilities unpatched a month after our Black Hat USA talk (“Binarly Finds Six High Severity Firmware Vulnerabilities In HP Enterprise Devices”).
Repeatable failures just keep on repeating.