Detecting Firmware vulnerabilities at scale: Intel BSSA DFT case study
September 14, 2021 - Binarly Team

In our previous two blogs, Firmware Supply Chain is Hard(coded) and Attacking (pre)EFI Ecosystem, we described in detail four high severity vulnerabilities that impacted the UEFI system firmware and put a large number of enterprise devices at high risk.

​​Through this research, ​we wanted to raise awareness about this new attack vector. The firmware patch cycles last typically around 6-9 months (sometimes even longer) due to the complexity of the firmware supply chain and the lack of an uniform patching process. The 1-day and n-day vulnerabilities in many cases have a large impact on enterprises since the latest firmware update wasn’t installed or the device vendor had not released a patch yet. Each vendor follows their own patch cycle, even known issues may not be patched until the next firmware update is available.

After constantly finding vulnerabilities in the UEFI ecosystem and realizing it is a huge challenge to patch them industry-wide, we decided to build a platform to help enterprises protect their firmware supply chain.

Binarly developed the Firmware Hunt (FwHunt) detection engine and rule format in partnership with Linux Vendor Firmware Service (LVFS) to detect known threats including vulnerabilities. An experimental version of Binarly open-source FwHunt scanner (uefi_r2) has been included in the June release of LVFS platform (1.3.2). The LVFS platform runs FwHunt rules against *650,000 EFI binaries from ~5000 different firmware uploads from companies like Intel, Dell, HP, Lenovo, and many others. As a result of this June release, we were able to notify potentially impacted vendors before our Black Hat research became public given that the expected impact from CVE‑2021‑0144 was significantly large. To give a perspective on the severity of this vulnerability, most of the high-performance Intel-based client and server platforms were impacted.

As previously mentioned in the blog, the Intel BSSA DFT vulnerability is a reference code vulnerability. This means that Intel should fix it first and provide a patch to the Independent BIOS Vendors (Phoenix, Insyde, AMI, etc.) to embed it in their codebase. Next, the Original Equipment Manufacturers (DELL, Lenovo, HP, etc.) should embed the resulting patch from the IBV into their codebase and release it to their customers. Based on this slow delivery model, how can anyone be confident they are running a firmware that includes the necessary fix?

The Binarly Firmware Hunt (FwHunt) rule format was designed to scan for known vulnerabilities and verify that an affected OEM vendor has patched the issue in its latest update.

In a previous blog post, "Why Firmware Integrity is Insufficient for Effective Threat Detection and Hunting", we explained why legacy approaches don't work. But unfortunately the industry standard for developing detection capabilities for threat hunting is based on YARA rules that are NOT tailored to effectively coverUEFI firmware code specifics. YARA is a good rule format for searching byte sequence patterns using regular expressions with wildcards. However, it only operates at the byte-pattern level, without any knowledge of code semantics.

NVRAM variable names or protocol GUIDs are often initialized on the stack, which makes it more complex to use YARA effectively without introducing false positives. Here is a code snippet from UncoreInitPeim PEI driver where the Intel BSSA DFT vulnerability was been introduced.

Figure1

Due to PEI driver specifics, PPI services calls for communicating between modules (PEIM-to-PEIM Interface (PPI)) requires getting the address of the PPI interface GUID from the stack. Here is an example of SsaBiosVariableGuid:

Figure2

Detecting new and already known vulnerabilities (vulnerable code patterns) at binary code level are two different problems. The main problem Binarly Firmware Hunt (FwHunt) rule based detection service is trying to solve is to point to the potentially vulnerable module and also detect the exact code sequence responsible for the vulnerability to prove the vulnerability exists. YARA originally was created to detect IOCs that identify a threat, where the module which contained the targeted IOC is a malicious module. In our case, the modules which contain the GUIDs or NVRAM variable names responsible for a specific EFI functionality may not be vulnerable due to a patch applied or different vendor code specifics.

It is possible to find the "syscg" and "toolh" NVRAM variables names in both vulnerable and non-vulnerable code bases. In essence, detecting only these two string constants will indicate the Intel BSSA DFT is present in the code but does not guarantee that the vulnerability exists.

Figure3

That is why YARA is insufficient for effective vulnerability detection in general and in firmware in particular. That is exactly why we created Binarly Firmware Hunt and open-sourced it to help the industry solve those challenges at scale.

How Binarly Firmware Hunt works

The typical Firmware Hunt (FwHunt) rule consists of the following YAML code sections:

  • The ‘meta’ section contains the detection module description - includes name of vulnerability (or threat) and URL to the vendor advisory (if applicable)
  • The ‘guids’ section is responsible for the NVRAM variables and EFI protocols GUID’s described as name-value tuples (GUID strings and symbolic names)
  • The ‘string constant’ section is responsible for wide_strings detection
  • The ‘hex_strings’ section is responsible for the code pattern or byte sequence detection
  • The ‘esil’ section is responsible for a semantic approach for detecting code patterns; currently using intermediate representation (IR) called ESIL (Evaluable Strings Intermediate Language).

Here is an example of detecting ThinkPwn vulnerability with FwHunt rule:

ThinkPwn:
  meta:
    name: ThinkPwn
    namespace: ThinkPwn detection tool
    url: https://github.com/Cr4sh/ThinkPwn/
  guids:
    - 1:
      - name: SMM_BASE_PROTOCOL_GUID
      - value: 1390954D-DA95-4227-93287282C217DAA8
    - 2:
      - name: SMM_COMMUNICATE_HEADER_GUID
      - value: F328E36C-23B6-4A95-854B32E19534CD75
  esil:
    - 1:
      - 0x20,rdx,+,[8],rax,=
      - rdx,rbx,=
      - 0,rax,rax,&,==,$z,zf,:=,$p,pf,:=,63,$s,sf,:=,0,cf,:=,0,of,:=
      - zf,?{,X,rip,=,}
      - rax,[8],rcx,=
      - 0x18,rdx,+,r8,=
      - X,rip,+,[8],rdx,=
      - 0x8,rax,+,[8],rip,8,rsp,-=,rsp,=[],rip,=
      - 0,0x20,rbx,+,&=[8],$z,zf,:=,$p,pf,:=,63,$s,sf,:=,0,cf,:=,0,of,:=

Original ThinkPwn detection tool is complex because the detention of this vulnerability is based on a static analysis approach. The FwHunt approach simplifies complex detection approaches and makes this process more scalable to run in a large infrastructure.

Getting back to the detection of CVE-2021-0144: Here is the rule we developed for LVFS to scale the detection for multiple EFI binaries so we could notify the vendors impacted by this vulnerability.

UncoreInitPeimRefCode:
  meta:
    name: INTEL-SA-00525 (CVE-2021-0144)
    namespace: Intel BSSA DFT detection tool
    url: https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00525.html
  guids:
    - 1:
      - name: EFI_PLATFORM_INFO_GUID
      - value: 1E2ACC41-E26A-483D-AFC7A056C34E087B
    - 2:
      - name: EFI_STATUS_CODE_SPECIFIC_DATA_GUID
      - value: 335984BD-E805-409A-B8F8D27ECE5FF7A6
    - 3:
      - name: EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID
      - value: 9A4E9246-D553-11D5-87E200062945C3B9
    - 4:
      - name: EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID
      - value: 2AB86EF5-ECB5-4134-B5563854CA1FE1B4
    - 5:
      - name: EFI_PEI_PCD_PPI_GUID
      - value: 01F34D25-4DE2-23AD-3FF336353FF323F1
  ppi:
    - 1:
      - name: EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID
      - value: 2AB86EF5-ECB5-4134-B5563854CA1FE1B4
      - service:
        - name: LocatePpi
  wide_strings:
    1: syscg
    2: toolh
  hex_strings:
    1: 56e8........593c01....80be....000000
      # 56                                      push    esi
      # E8 .. .. .. ..                          call    x_BiosSsaEnabled
      # 59                                      pop     ecx
      # 3C 01                                   cmp     al, 1
      # .. ..                                   jnz     short loc_FFDE86FD
      # 80 BE .. .. 00 00 00                    cmp     byte ptr [esi+81h], 0
      # .. ..                                   jz      short loc_FFDE86FD
    2: 6a006a0268be00000056e8
      # 6A 00                                   push    0
      # 6A 02                                   push    2
      # 68 BE 00 00 00                          push    0BEh
      # 56                                      push    esi
      # E8 .. .. .. ..                          call    SsaApi

To run the FwHunt detection scanner, first copy the rule file to the rules folder under the uefi_r2 scanner installation folder.

uefi_r2_analyzer.py analyze-image {image_path} -o out.json
uefi_r2_analyzer.py scan --rule {rule_path} {image_path}

uefi_r2_analyzer.py scan --rule ./rules/BSSA_DFT_detect.yml ./test/UncoreInitPeim.efi

Here is successful detection result of FwHunt and uefi_r2 scanner:

Figure4

Binarly Firmware Hunt is an open-source project created to help industry validate that known vulnerabilities have been patched and reduce the supply chain risks in enterprise infrastructure.

The Binarly SaaS platform uses a proprietary agentless approach to help enterprises identify vulnerable firmwares and hardware misconfiguration at scale.

Furthermore, the Binarly analytical platform can detect and classify the nature of the code changes by comparing the update to the latest device snapshot of the firmware to confirm that the fix was properly applied.