In August 2019, I’ve discovered a bug in how the XPS Bios handles a bootable device. This bug allows an attacker with write permission to a bootable device or physical access to the computer to prevent it from booting.
The Dell XPS reads and drops file on the primary disk during the booting and BIOS upgrade process. Namely, it drops:
These files are used by a process called BIOS Recovery Tool. On the XPS 9370, BIOS Recovery 3 is used.
BIOS_PRE.rcvis used for F2/F12 recovery.
BIOS_CUR.rcvis used only during the process of flash update failures. After the successful FW update
BIOS_CUR.rcvis always copied to
BIOS_PRE.rcv is corrupted, the BIOS crashes. Triggering this bug prevents
the laptop from accessing the boot menu and accessing the BIOS. The only way to
recover from the exploit is to unplug the exploited boot device. If the exploit is
done on the internal disk, this means that you need to disassemble the laptop.
When “Bios Recovery from Hard Drive” is disabled, recovery (and the exploit) only works from USB stick / USB hard drive.
A tale of failure
This writeup is not your usual exploit writeup. I am not an experienced attacker, especially not against a blackbox such as my laptop’s BIOS. So how did I end up finding it?
It all started while I was benchmarking my laptop’s internal drive using
randrw instead of
randread and thus overwrote a part of my
own hard drive. This part mostly included my boot partition and the two aforementioned BIOS
Luckily, I already had a live Arch Linux USB key to repair everything. My plan was simple: reboot, fix, reboot. That doesn’t sound so hard!
After rebooting, I could not access a single BIOS Menu. Everything either froze on a black screen, or on “Preparing one-time boot menu”. If I was unable to boot anything or access the BIOS setup, I was not going to be able to fix my problem.
At that time, I didn’t know I found a bug in the BIOS, only that I somehow fucked up so hard that my laptop was bricked. So I contacted the Dell support, because I should not be able to brick my laptop like this! They agreed that it was not supposed to happen and offered me a replacement.
Backups and a surprise
Before sending back my laptop, I wished to recover what I was working on as it had yet to be pushed. So I took the NVMe out of the laptop and put it in another machine to dump a disk image. Right after removing the NVMe, I could access the Bios and even boot on my USB stick.
Was my NVMe broken? From another computer, I could access any file on it. The boot partition was indeed corrupted but the content of the LUKS partition was sane.
Well then, if it’s not hardware, is it something on the drive? I dumped a full disk image on an external HDD, tried to boot it on my laptop and boom. I just reproduced the bug I had earlier on another drive.
I couldn’t miss the chance to play with what I had found so I kept a full disk image as a backup of my data and another as a way to trigger the bug.
Finding the culprit
Now that I had a disk image that triggered the bug, it was time to investigate. At that point, the only information I had were:
- I wrote random bytes on my disk, including in the partitions table, the boot partition, and part of my encrypted disk
- Something on the disk is definitely messing up with the BIOS
- Duplicating the disk image and plugging it in as a USB Disk triggers the bug
I assumed that bytes inside my encrypted partition were not the cause as the BIOS had no reason to read them and they were valid when read from another computer. Hopefully, it is not broken hardware either.
My first guess was that my partitions table was invalid and something broke while enumerating tables. For instance, I might have been listing a partition offset outside of the disk size, or an invalid size.
To verify that, I created a new partition table from scratch and copied the boot partition content (files) and tried to boot.
Spoiler alert: Still broken.
Even better, I did not copy my encrypted partition so the bug was definitely triggered by something inside the boot partition!
Obviously, there was something in my boot partition that triggered the bug. But why would the BIOS read the content of the boot partition? Silly me, I did not know that BIOS recovery from hard drive was a thing. As far as I knew, it might have been coming from anything: an invalid folder name, a corrupted file or even a hard-link to an invalid INode…
Obviously not an invalid hard-link as I just did copy the files and there were no hard-links on this new drive…
I was lacking the experience in this kind of bug so the easiest way for me was to proceed by elimination:
- Step 1: Delete a folder
- Step 2: Try to boot
- If it boots, restore only this folder, and apply Step 1 to the content of this folder
- If it does not boot, simply go back to Step 1
- Repeat until there is only a single file or folder remaining that triggers the bug
I deleted files using this method until I found out that deleting the
/boot/EFI/Dell/Bios/Recovery folder fixed the issue.
At this point, I notified Dell about the bug and sent them the two files that were triggering the bug. The BIOS being closed source, it would be time consuming to find:
- What the format of
BIOS_CUR.rcvwas (looking at Dell’s documentation, it might just be a Windows executable)
- What field in that file triggers the bug
I might have been able to
hexdiff a working file with the broken one, to
highlight the differences. However, that would not have given me a better
understanding of the issue. From there, Dell took over and we now have access to
the result of the investigation: Improper Exception Handling.
- 12 August 2019: Message sent to email@example.com without the PoC
- 13 August 2019: Answer from Dell asking for more details
- 11 September 2019: Message sent to firstname.lastname@example.org with steps to reproduce, including a small disk image and the broken files.
- 12 September 2019: Answer from Dell with the ticket number
- 26 September 2019: Dell confirmed the problem exists
- January 2020: Dell plans to try to release a patch in April
- April 2020: Dell plans to publish the patch end of May
- May 2020: Dell plans to publish the patch beginning of July
- 19 August 2020: Bios 1.13.1 released with the patch
- 29 September 2020: Dell notifies me a Security Advisory was published
- 16 October 2020: Dell updates the CVE score as the CVE does not require physical access, only high privileges
The story might have begun as a scary do your backups story, but it ends without any data-loss and with a reported vulnerability. Overall, it was a lot of fun and a fine addition to my collection.
Perhaps next time we’ll talk about how to destroy the displayed image on my monitor using only a JPEG file or making a video input detected as HDR by squeezing the DisplayPort cable.