Using UEFI to inject executable files into BitLocker protected drives

Grzegorz Tworek
3 min readSep 9, 2019

To keep important things clear: BitLocker is a Windows-based full volume encryption solution. It encrypts every single sector of the volume, acting on the lowest possible layer — encrypting the data just before being written to the hardware and decrypting freshly it immediately after reading. BitLocker is considered relatively secure (including FIPS certification) and one of the main purposes is to protect data “at rest”, when the Operating System cannot guard it. In practice it means, BitLocker is totally transparent for computer users, but if you try to play the data offline (mounting the disk drive to another machine, booting from USB stick etc.) — you realize everything is encrypted. The beauty of the solution is highly related to a method how BitLocker manages encryption keys, but we will not cover it here as totally irrelevant to the main topic. Just to wrap it up: when the OS is running it protects unauthorized users from manipulating critical data, and when the OS is not working — the data is encrypted an you cannot manipulate it too.

Having the landscape described, we can quickly realize that injecting a file into encrypted partition looks like the bad guys Holy Grail. After we launch it with high privileges (a challenge on its own), we can disarm some protections, create new admins, transfer the disk content over Internet etc. Of course, it should be not allowed if we want to keep the computer protected. Injecting a file into disk is impossible before booting due to encryption and after the boot, when encryption is transparent, the OS does not allow us to drop the file into sensitive locations allowing an execution with high privileges. Problem solved.

And what if not?

Here comes the Session Manager (smss.exe) — one of the key components of the Windows OS. Of course, it stays on the encrypted volume and uses the data protected with BitLocker. With one noteworthy exception I am covering below. The OS startup process includes couple of steps such as:

  • Loading registry hives
  • Initializing OS parameters such as safe boot etc
  • Lauching boot time part of chkdsk
  • Performing file operations postponed till reboot
  • Logging drivers if enabled
  • Initializing data related to Known Dlls
  • Initializing pagefile(s)

Etc.

One of the steps to be performed relies on a NtQuerySystemInformation() function (depreciated by Microsoft) with a 0x85 as a parameter. This parameter is not documented but according to the information provided within PDB symbol files, it may be interpreted as SystemPlatformBinaryInformation. NtQuerySystemInformation() scans UEFI tables stored within hardware memory looking for a piece of data with properly constructed headers. If such pattern (“WPBT”, length, revision and a checksum) is found, the structure is passed to the smss.exe. And here the magic begins.

  • Smss.exe stores the piece of UEFI memory within a file called wpbbin.exe.
  • Smss.exe takes execution parameters (command line) from the same UEFI block.
  • The wpbbin.exe is checked for integrity with IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY.
  • The wpbbin.exe is executed.
  • UEFI is notified about the execution status.

The whole process is surprisingly well documented by Microsoft.

What does it mean in practice? If you have fully encrypted drive and you want to access the OS, use UEFI and wait for Session Manager to do the rest. You have to prepare an .exe file (using only ntdll.dll, without Win32API calls), sign it an put into UEFI table. It is not something regular home user can do, but at the same time, it means that the bar keeping bad guys off the encrypted drive is hung significantly lower than we used to think.

I’d suggest that it is the high time check if %systemroot%\system32\wpbbin.exe exists in your system.

And a second later you can create your own file (empty one is good enough) and mark it read only. Smss.exe can overwrite an existing file, but does not check or reset such simple thing as the R attribute.

Good luck!

--

--