Welcome back to CVE Wednesday! Today we are going to look at CVE-2021-39297. CVE-2021-39297 was originally discovered and reported by Binarly and impacts certain HP PCs. A full write up, including a demonstration of a proof of concept, is available on the Binarly Website as BRLY-2021-003.
Additionally, HP provides a support document here
A Discussion regarding reproducing the vulnerability inspired me to write up this blog post.
Full credit for the discovery of this vulnerability is due to the team at Binarly. I had nothing to do with the discovery of this vulnerability
I reproduced this vulnerability using WSL2 on a Windows 11 laptop. You will need
ovmf installed, and potentially
First, I downloaded a firmware file from HP that the Binarly disclosure listed as vulnerable:
Next I used a script I wrote to extract the DXE firmware volume from the
$ python3 hp-dxe-extract.py Q95_011400.bin
This left me with a directory
volume-0 that contains a directory with the module GUID:
$ ls volume-0/file-c988bded-6977-464d-b714-e61debd2de97/ file.obj section0.pe section1.ui
c988bded-6977-464d-b714-e61debd2de97 is listed in the original binarly advisory as being the vulnerable DXE driver GUID.
Now lets do a checksum:
$ md5sum volume-0/file-c988bded-6977-464d-b714-e61debd2de97/section0.pe f0f53a2f30f91feb32af7b6b8d73353d volume-0/file-c988bded-6977-464d-b714-e61debd2de97/section0.pe
The md5 hash
f0f53a2f30f91feb32af7b6b8d73353d matches the hash listed for this firmware version in the Binarly Advisory. We have the vulnerable
0138.efi file at this point.
I then created a directory
fs to use as my FAT32 ESP.
$ mkdir -p fs/EFI/boot $ cp volume-0/file-c988bded-6977-464d-b714-e61debd2de97/section0.pe fs/0138.efi
Next, we can use OVMF with QEMU to launch into an EFI shell:
$ qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -hda fat:rw:fs -nographic -serial mon:stdio
I ran the EFI shell with QEMU from the CLI using
-nographic because it made pasting in the EFI variable values easy.
From the EFI Shell we can then run
0138 and see the application launch:
The vulnerability stems from handling the EFI variables
Lang, so those need to be set to the values provided in the binarly advisory using the EFI command
It is important to note that the binarly advisory contains a video demonstrating successful exploitation of the vulnerability. However, the video does not capture which firmware file the
0138.efi file was extracted from. As such, the memory layout may differ between the various versions. This means when I attempted to exploit the vulnerability, I received a CPU exception:
!!!! X64 Exception Type - 0D(#GP - General Protection) CPU Apic ID - 00000000 !!!! ExceptionData - 0000000000000000 RIP - 4C07E9E741BA079E, CS - 0000000000000038, RFLAGS - 0000000000000206 RAX - 0000000000000003, RCX - 0000000000000065, RDX - 0000000005F14A70 RBX - 0000000007F10588, RSP - 0000000007F10440, RBP - 0000000007F10578 RSI - 000000000614E018, RDI - E018B82850FF41C1 R8 - 0000000000000003, R9 - 000000000640531E, R10 - 00000000000005F2 R11 - 0000000000000001, R12 - 0000000000000000, R13 - 000000000614FA18 R14 - 000000000605DA00, R15 - 00000000060C2AE8 DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030 GS - 0000000000000030, SS - 0000000000000030 CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000 CR4 - 0000000000000668, CR8 - 0000000000000000 DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000 DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400 GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000 IDTR - 0000000007471018 0000000000000FFF, TR - 0000000000000000 FXSAVE_STATE - 0000000007F100A0
The next steps would be adjusting the exploit data to match up with the specific firmware version I am running against for this write up. If I have time and there is interest, I’ll write another blog post on how to do that later.