A month ago, Binarly’s security research team managed the coordinated disclosure of 16 high impact vulnerabilities in HP devices and 23 additional security defects impacting major enterprise vendors. In less than a year, Binarly disclosed 42 high severity vulnerabilities haunting the UEFI firmware ecosystem, all serious enough to cause arbitrary code execution in System Management Mode (SMM).
The ongoing discovery of these vulnerabilities demonstrate what we describe as “repeatable failures” around the lack of input sanitation or, in general, insecure coding practices. These failures are a direct consequence of the complexity of the codebase or support for legacy components that get less security attention, but are still widely deployed in the field. In many cases, the same vulnerability can be fixed over multiple iterations, and still, the complexity of the attack surface leaves open gaps for malicious exploitation.
These also prove that the majority of enterprise tools available for source code analysis are not suitable for pinpointing firmware-specific security defects. There are multiple reasons, one of the most obvious being the differences in implementations of the memory management functions compared to the non-firmware-specific software. This leads to a false sense of security when no vulnerabilities are detected at source code level.
The complexity of the firmware supply chain leads to an almost infinite source of vulnerabilities. Unfortunately, most outsourcing companies developing firmware code for major device vendors do not have product security teams or sometimes even a single employee dedicated to mitigating security risks. The majority of security practices revolve around the compliance checklists with poorly configured static analysis tools and running an antivirus scan of the entire code base snapshot before release. This fundamental misunderstanding of design failures leads to an expansion of code complexity and keeps devices in a perpetual state of exposure.
One of the best examples of this is the five-year-old AMI UsbRt vulnerability (INTEL-SA-00057) that is still present in newer hardware devices. The UsbRt vulnerability was first discovered in 2016 and named Aptiocalypsis. However, due to the complexity of the code, multiple variants of the bug were subsequently discovered. As we highlighted in our presentation at the OffensiveCon conference, UsbRt bugs have an almost-six-year-old history of successful and repeatable exploitation.
Fast forward to today and the Binarly Platform continues to detect vulnerable versions of AMI UsbRt at scale in enterprise infrastructure, and the number of impacted devices is scary.
It is frustrating to see some vendors providing false claims to customers about the presence of vulnerable code.
“... this portion of AMI source code is now approximately seven years old and no longer featured in current AMI UEFI products.”
As we have discovered, this is clearly not accurate. These vendor tactics work to hide the problems in the short term but unfortunately creates unnecessary security risks for the industry.
The figure below shows the results of a Linux Vendor Firmware Service (LVFS) search query by simply using the UsbRt GUID (04EAAAA1-29A1-11D7-8838-00500473D4EB) where the list of vendors who can potentially be impacted consists of all the major enterprise device manufactures such as Lenovo, Dell, Star Labs, and many others.
Binarly has already partnered with the LVFS project to help protect the supply chain for enterprise devices against known vulnerabilities. The collaboration between CERT/CC, LVFS (Richard Hughes, Red Hat) and Binarly focused on helping scope, at scale, the impacted parties by applying FwHunt rules to detect vulnerable device vendors.
This is the definitive proof that the AMI UsbRt attack vector is widespread in the industry and exposes massive attack surfaces on corporate networks.
This is exactly how our newest Dell vulnerability and disclosure started. A retrospective scan spotted a potentially impacted device, which prompted further investigation.
The Binarly team recommends removing the UsbRt component from further UEFI firmware updates to reduce the attack surface. Because of the code complexity of this component, it is difficult to maintain this code and absorb acceptable security risk.
As usual, we started the disclosure process over the CERT/CC VINCE system to notify multiple impacted parties and coordinate the disclosure process in one centralized place.
As a result of this research, Binarly discovered and reported to Dell three new variants of UsbRt vulnerabilities related to its enterprise devices.
The Dell disclosure information is available at:
DSA-2022-053: https://www.dell.com/support/kbdoc/en-us/000197057/dsa-2022-053
We commend the Dell PSIRT team for its fast response and patch delivery to customers. It took about three months from the issue reporting to the patch release, when the usual timeline with other vendors is close to six months. It is extremely important to reduce the disclosure timeline when we are dealing with known attack vectors such as AMI UsbRt.
The active exploitation of all the discovered vulnerabilities can’t be detected by firmware integrity monitoring systems due to limitations of the Trusted Platform Module (TPM) measurement. The remote device health attestation solutions will not detect the affected systems due to the design limitations in visibility of the firmware runtime.
Let's dive into the root cause of these issues and why they occur so frequently with the same piece of code. The AMI gUsbData structure is so complex that it cannot fit on one screen and contains more than 30 unique fields. The complexity of the code cannot be secure by design, which has been confirmed by the multiple security vulnerabilities (8 CVEs!) reported over the past six years. The gUsbData structure can be manipulated by an attacker outside of the firmware at operating system level. The picture below shows the complexity of the attack surface:
One of the issues (CVE-2017-5721) previously discovered in 2017 exposed the complexity problem of the UsbRt API interface. Take a look at this blast from the past:
The interesting part is how this vulnerability was patched and what mitigations developers applied. The common practice to patch such issues, when the input data is controlled by an attacker, is by applying sanitation barriers to that input data. In the figure below it is shown the ValidateUsbData() function which is responsible for the sanitation of the gUsbData structure.
As we can see below, the implementation of ValidateUsbData() is based on the validation of the input data by computing and verifying the CRC32 checksum from this data:
Since the implementation is based on an inappropriate cryptographic hash function it creates a weakness by design. The CRC32 hash can be spoofed and validation barriers responsible for sanitation can be bypassed by CRC32 spoofing attack. That led to another vulnerability (CVE-2020-12301) discovered a few years later.
Let’s talk about the exploitation complexity of the CVE-2020-12301 vulnerability. There are no differences in the attack vector, but there can be some limitations with Intel-based mitigations. The exploitation steps will be as follows:
This looks like a pretty straightforward way of exploitation of this vulnerability as shows on the figure below:
Another mitigation is SMM_Code_Chk_En (sometimes disabled by developers) which has been developed by Intel and used on newer devices since Kabylake. The easiest way to verify if your device supports this mitigation is to check the bit status in the MSR_SMM_FEATURE_CONTROL register or use the Intel Chipsec tool. The SMM_Code_Chk_En mitigation blocks the execution of code located outside the SMRAM by applying additional validations to prevent a class of vulnerabilities known as SMM call-out.
The details about a SMM_Code_Chk_En bypass have been first spotted in the blog “Code Check (Mate) in SMM” by Bruno Pujos from the Synactiv team. The author discussed the potential ways to bypass this mitigation and propose to use the ROP chain as the most effective attack. Binarly team decided to go further and show the full chain ROP exploit demonstration by exploiting the CVE-2020-12301 vulnerability. What will be different from the previously introduced exploitation steps?
According to our REsearch, finding the ROP gadgets in any existing SMM drivers is quite simple. To construct an effective attack, any SMM driver contains the following gadgets:
mov ecx, 0xe8; mov rax, rdx; jmp qword ptr [rcx + 0x48];
Our goal for a successful exploitation is to read the SMRAM memory region, so we need to find several gadgets that set the values of the RCX, RDX, R8 registers to call the CopyMem function. Given the specifics of the UEFI drivers, this is not a problem. The required gadgets are identified by leveraging the Ropper tool:
Now the final ROP chain looks like the following:- set R8 register value (size for CopyMem)- set RCX and RDX registers values (src and dst buffer pointers for CopyMem)- restore registers values inside InternalLongJump function- new RSP value = leaked RSP value - 8 (because of one POP and two calls)- jump to CopyMem function
The following UsbRt specifics of the attack are applied:- build the data into the controlled memory- change the pointer in the gUsbData structure to point to the crafted data- trigger SW SMI handler with SwSmiInputValue = 0x31
The result of successful exploitation is shown below and the desired bytes from SMRAM at the address stored in RCX are dumped into the console. To accelerate the PoC development, we took advantage of the Intel Chipsec tool. The PoC source code is available on the Binarly Github repository.
Unfortunately for defenders, ROP attacks are extremely easy to develop in SMM because of UEFI firmware specifics and its build process. To achieve a more stable and predictable behavior, firmware developers do not use much compiler optimization or obfuscation methods. That makes the code flow very straight-forward and provides enough space to find reliable gadgets to build the ROP chain.What about Dell UsbRt vulnerabilities?
In terms of AMI UsbRt specifics, the exploitation is not much different from the previous cases discussed in this blog. Let’s take a look at the BRLY-2022-004 vulnerability. In the figure below a Hex-Rays Decompiler pseudocode snippet is shown, where the Struct pointer can be controlled by an attacker and it is not checked if it overlaps with the SMRAM memory. This means that a potential attacker can write the 0xF0 value to a controlled location (Struct[2] = 0xF0) in the SMRAM memory which leads to the execution of arbitrary code in SMM.
Another case study is BRLY-2021-045 vulnerability disclosure where Struct value can be controlled by a potential attacker. If FuncIndex == 15, then the function located at offset 0x30D8 will be called as shown in figure below:
The first argument to the Invoke() function is a pointer to be retrieved from the structure pointed to by gUsbData. An attacker can control a pointer, execute an arbitrary function and pass up to 7 parameters to it. Since there is no check for Struct->SubfuncIndex value and if the value of Struct->SubfuncIndex equal 9 or 10 or 11, it leads to arbitrary code execution in SMM, since gCoreProcTable[9] = gCoreProcTable[10] = gCoreProcTable[11] = 0.
As we demonstrated in this blog, the lack of validation of untrusted inputs which can potentially be manipulated by an attacker and the complexity of the code base leads to repeatable vulnerabilities in the same code again and again.
The purpose of this blog is to raise awareness about these repeatable problems, demonstrating how well known attack vectors can still find their way into the firmware supply chain for newer devices. For all vulnerabilities mentioned in this blog related to AMI UsbRt issues, including those that were not discovered by us, Binarly has publicly released FwHunt detection rules.
The FwHunt detection for all the issues from this blog related to AMI UsbRt vulnerabilities is shown below:
Are you interested in learning more about Binarly FwHunt or Binarly SaaS Platform?Don't hesitate to contact us at [email protected].
The Binarly team is constantly working to protect the firmware supply chain and reduce the attack surfaces of our customers industry-wide by delivering innovative technologies to the market. Based on our experience we understand that fixing the vulnerability for a single vendor is not enough. As a result of the complexity of the firmware supply chain, there are gaps that are difficult to close on the manufacturing end since it involves issues beyond the control of the device vendors.