A FortiGuard Labs How-To Guide for Cybersecurity Threat Researchers
Unified Extensible Firmware Interface (UEFI) is a specification that defines an interface between platform firmware and an OS. In a nutshell, UEFI replaces the BIOS in previous systems. Since UEFI is required for Secure Boot (ever since the Windows 8 operating system released in 2012), virtually all modern PCs come with UEFI firmware.
Naturally, with the growing popularity of UEFI systems, and the fact that UEFI firmwares have even higher privilege than the OS/ hypervisor, adversaries are starting to focus on exploiting this new attack surface. This is evidenced by the UEFI rootkit found recently from the Sednit group.
Consequently, there is a pressing need for security researchers to be able to handle this novel threat. In this blog post, we will show you how.
NOTE: Before delving into the details, we wrote this piece assuming that readers already possess a strong knowledge about UEFI, BIOS, and the boot process, etc. Furthermore, even though static analysis (e.g. using IDA Pro) has its uses, the limitations of static analysis are well known (i.e. it cannot deal with packed samples or encrypted samples, etc.) and that's why this blog will post focus almost exclusively on dynamic analysis. The topic of deep static analysis will be addressed in a future post.
Let's get right into it!
If you have generous budget, then shelling out money to invest in a professional solution is a possible option. One such solution is the Intel Firmware Engine and MinnowBoard Turbot platform combo (pictured below).
Figure 1 Intel® Firmware Engine
The Intel Firmware Engine can be used to flash UEFI firmwares (e.g. contain malware) to the MinnowBoard Turbot platform. One can then use a special debug cable to debug the malware.
Figure 2 MinnowBoard Turbot platform
But what if you are a hobbyist and you don’t have a big budget? Or you are a security researcher who doesn’t want to invest in a new set of tools just for a one-off project?
Well, fret no more, because in this research blog we will show you a solution that gives you the most bang for your buck.
To make a long story short, we found that with an intelligent combination of tools we can use a sandbox to dynamically analyze UEFI malware that same as any traditional malware.
NOTE: As before, we will intentionally gloss over many of the details as we are assuming a sufficient knowledge base and skillset of readers already being in place. However, any background information or details needed can be found in the specification published by the unified EFI forum, so we will not repeat that information here.
We found that we can use Open Virtual Machine Firmware (OVMF) as a sandbox to execute malware. Our intuition is that OVMF is realistic enough to fool any malware into thinking it is running on hardware. This intuition was confimed when we compare OVMF with real world commercial firmwares (example below.)
Figure 3 Supermicro Firmware (B11 DP Purley platforms)
Figure 4 shows the content of the Supermicro Firmware for the B11 DP Purley platforms (Intel® Xeon® Scalable Processors with Intel® C620 Series Chipsets). The hash is 267C9CF2597A23AD957C10553EAF1D8B1196700EAFE67C7999B2CDB4E41995A4. We can then dump the content and compare that to those of OVMF.
Figure 4 Open Virtual Machine Firmware (OVMF)
Now that we have the firmware, we can use QEMU to emulate the UEFI environment. However, our malware analysis process are simply not present in the UEFI environment. Here are some of the unique challenges in an UEFI environment:
In the next section, we will address those challenges in the UEFI preboot environment.
This challenge does not exist in a traditional environment because everything “just works”. But our virtual sandbox (OVMF) is a bare metal OS with just enough services to support the booting of the OSes. Which means it doesn’t support modern file systems like NTFS or EXT4, and hence cannot see the malware files on the analyst’s disk. Furthermore, it does not have a shell from which to invoke the malware.
After much research, we found a solution that kills two birds with one stone. We can create a bootable ISO which also contains a UEFI shell. We can then inject the malware files into this ISO and have OVMF boot into the ISO image. Better yet, we don’t have to create the base ISO image because we found that some Linux distros (e.g. Fedora) already have one. For example, in Fedora 29 this ISO image can be found at /usr/share/edk2/ovmf/UefiShell.iso
Figure 5 Special ISO Image For OVMF
But, much to our chagrin, when we inject the malware files into the ISO image and boot OVMF, our sandbox does not see the malware. How come?
It’s time to put our forensic skills to work. An astute reader may notice that files of ISO start at LBA 748, which suggests that something is hidden at the beginning of the disc. The block size of the file system (ISO 9660) is 2 KB. Let’s do the math: 747 * 2 = 1494 KB
Sure enough, when we use a forensic tool, we notice a section called [BOOT].
Figure 6 1.44 MB Floppy Disk
And the boot volume is a 1.44 MB floppy disk from the “good” old days (FAT12!). Finally, we can inject the malware into this boot volume.
Figure 7 The Boot Volume
Now that we have injected the malware, we need to update the boot record by using UltraISO.
Figure 8 Update The Boot Record
Finally, we can reboot the OVMF sandbox, and now we are greeted by the fully functional UEFI shell. As can be seen, all storage devices are mounted and listed as part of the booting process.
Our volume is mounted at fs0, so we can switch to it like this:
Figure 9 UEFI Shell
We can then invoke the malware like so:
The shell is blessed with way more tools than just the basic ones. For more details, readers are welcome to check out the shell’s official documentations (e.g. Uefi Shell).
Now that we can launch the malware at will, the next goal challenge is how to actually debug the malware. Obviously, we don’t have debug tools “in the box.” An "outside of the box" approach may work, but the key challenge is that qemu is a full system emulator; how do we debug just the part we care about (i.e. malware code)?
We found that we can enable debugging (and the debugging log) to trace the execution of the entire platform:
sudo virsh edit “OVMF"
Figure 10 Tracing OVMF
After rebooting the OVMF, we can see the log is generated nicely as the system boots up.
Figure 11 Entry Point of The Malware
As can be seen here, our log captures the entry point of the malware, which allows us to achieve the final result below.
At long last, we can finally debug and trace the malware. The tool of choice is Gdb. From Gdb we can connect to our virtual sandbox like this:
target remote localhost:1234
Like any solution like this, you are likely to encounter many errors. Through our own trial and error, we found that latest version of Gdb (and qemu) provide a smoother debugging experience.
The key thing here is that we can now set a breakpoint at the entry point of the malware.
Figure 12 Stepping Through the Code
Bingo! From this point, we can trace/debug through the malware code just as we can with traditional malwares.
Since UEFI malware are PE files, they are detected by the FortiGuard Antivirus service. For example, LoJax (Sha256 is 7ea33696c91761e95697549e0b0f84db2cf4033216cd16c3264b10daa31f598c) is detected as “W32/LoJax.A!tr”.
The UEFI environment certainly comes with new challenges. Nevertheless, in this research, we have shown how to dynamically analyze UEFI malware. Our software-based solution is not just cost-effective, but offers interesting benefits like speed (it takes longer to write on real SPI flash and then reboot the entire platform).
Attacking and defending is a constant arms race between the attackers and the defenders. As usual, FortiGuard Labs will continue to monitor novel threat vectors like this one and keep everybody updated.
-= FortiGuard Lion Team =-
Read about the FortiGuard Security Rating Service, which provides security audits and best practices.