Re: Is tpm2-measure-pcr really an additional security?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Le 10/03/2025 à 17:27, Adrian Vovk a écrit :
Hello,

On Mon, Mar 10, 2025, 12:06 Mikko Rapeli <mikko.rapeli@xxxxxxxxxx> wrote:
Hi,

On Mon, Mar 10, 2025 at 11:16:25AM -0400, Adrian Vovk wrote:
> Hello,
>
> Just to see if I understand your concern correctly, I'll try boiling it
> down to its simplest, by cutting out the need for two partitions. Here's
> the scenario:
>
> - An attacker replaces the real rootfs with a malicious one that just drops
> to a shell. The attacker keeps a copy of the original real rootfs

This should not be possible without breaking encryption keys from the device.
If the rootfs is not encrypted with device specific keys derived from TPM
measurements or dm-verity where root hash has been hard coded into secureboot
signed UKI binary for the kernel, then the setup is not secure to start with.
If dm-verity image has been tampered it will fail signature checks and fail
to mount.

This is inaccurate. systemd's security model allows for the rootfs to be replaced with a different one. There's no good way to actually prevent that: all partition table metadata is spoofable, including UUIDs and whatnot 

Of course, if you're using dm-verity on the rootfs, the attacker can only replace the rootfs with a copy of itself. But I don't think this is the case here, since the thread started with the presumption that the attacker can replace the rootfs.

To be clear, the partition layout I'm thinking about is: dm-verity protected /usr partitions (A/B copies), and then a separate rootfs partition that exists just to store persistent data (/var, /etc, etc). In this scenario, there's nothing preventing someone from replacing the rootfs partition's contents with anything arbitrary.

> - The system boots, then tries and fails to decrypt the fake rootfs.
>
> - The attacker now starts impeding communication between the TPM and the
> CPU. Potentially by physically interposing on the bus and blocking
> communication. Or by glitching the bus so that the data isn't successfully
> measured. Anyway, the attacker somehow makes TPM measurements fail
>
> - The attacker unlocks their malicious rootfs, and then the system
> continues booting. The attacker now gains control of the system via the
> root shell.

This means that TPM, firmware, kernel or initrd have been compromized at
runtime after their TPM measurements and secureboot signatures have been
verified. A denial of service attack is relatively simple but any code
executions should be grave bugs which need updates to get fixed. An initrd
should have only very limited functionality and no fallback interactive
shells or prompts, or network drivers or daemons.

If you can replace the rootfs (which we've established: you can), then that rootfs can contain whatever you want to gain execution early during boot. It can be as easy as a single symlink in /etc: basic.target.wants/systemd-debug-shell.service

It may be possible to cut down TPM communication and to make systemd and other
service to wait for longer time but it is simpler to freeze RAM and CPU
state and change the rootfs entry with physical attack via JTAG, if such interfaces
are enabled in HW.

The point is to disable the TPM enough that systemd gives up trying to measure pcrphases, and moves on. If it continues booting in that case, there's a big problem

> - The attacker stops impeding the communication between the TPM and the
> CPU. The TPM is still in the same state as it was in the initrd. The
> leave-initrd pcrphase, and the PCR15 measurement of the fake root's volume
> key, are both missing
>
> - The attacker is in control of the system, and the TPM is in the right
> state to unlock the real rootfs. The attacker talks to the TPM to get the
> real rootfs's volume key. Attacker wins
>
> I think, ultimately, this is the same issue as the one you describe. Do you
> think that's correct?
>
> Lennart would have a better idea than I do of what mitigations to this
> would look like. But I suspect that:
>
> - You can't MITM the TPM, since the communication is encrypted
>
> - Other kinds of attacks cause the OS to know that a measurement failed. So
> perhaps we need to very strict about ensuring that measurements happen.
> i.e. By not letting the TPM disappear at runtime, and making sure that
> measurements always succeed (and if it does, failing to boot or something)

TOCTOU, time of check vs. time of use bugs may exists but they should be
very hard to trigger, e.g. require HW debugger level access.

Well, the TPM is supposed to be secure against hardware debugger access, in theory. Ditto with CPUs, and JTAG lockout.

So if there's TOCTOU bugs in our code we need to be robust against them too.

Anyway, I don't think this is a TOCTOU bug. Basically, it seems that we're sometimes OK letting communication to the TPM fail. In which case, an attacker can cause the communication to fail, and we'll be none the wiser

If device specific encryption key leaks, then the data there can be modified
by the attacker. I too fail to see the bug here.

Right, this is what we're trying to avoid.

Basically, the bug is: an attacker does a DOS on the TPM in such a way that systemd boots to the rootfs without measuring the `leave-initrd` pcrphase, or the fake rootfs's pcr15. Once in the rootfs, the TPM doesn't know that it has left the initrd. And that's game over: the attacker stops DOSing the TPM, and extracts the encryption keys for the real rootfs from the TPM.

Yes, you can maybe using MITN in order to make pcrextend exit with 0 exitcode, because the measurement execution is checked in prcextend. Which is not the case in cryptsetup you may just jam the communication. (https://github.com/systemd/systemd/blob/bd0d22c2a5bdbf427c68eab630dc06f55dc96c72/src/cryptsetup/cryptsetup.c#L1085.


Let retry to explain the issue.

crypttab:

root /dev/sda1 tpm2-measure-pcr=yes

var /dev/sda2 tpm2-measure-pcr=yes

root and var enrolled using pcrs=7+11+15


-> Normal situation

1) Just before opening root LUKS:

PCR15=0 or something predictable

cryptsetup is used to open root and update PCR15 thanks to tpm2-measure-pcr=yes


2) Just before opening the var LUKS:

PCR15=hash1

cryptsetup is used to open var and update PCR15 thanks to tpm2-measure-pcr=yes

PCR15=hash2


3) initrd makes the mount of the fs, makes multiple measurements (notably on PCR11 with leave-initrd) then chroots and executes init.


-> Attack situation

1) Just before opening root LUKS:

PCR15=0 or something predictable

cryptsetup is used to open root. in this case /dev/sda1 is a malicious LUKS partition. TPM will not work but if there is no headless=true option, the attacker can unlock it using his password. Just after entering the password, the attacker jams the communication with the TPM making cryptsetup measure_volume_key returning non zero code, but totally ignored by systemd-cryptsetup.


2) Just before opening the var LUKS:

PCR15=0 or something predictable

cryptsetup is used to open var and update PCR15 thanks to tpm2-measure-pcr=yes. but in this case /dev/sda1 is replaced with the original /dev/sda1 partition.

PCR15=hash1


3) initrd makes the mount of the fs, makes multiple measurements (notably on PCR11 with leave-initrd) then chroots and executes malicious init.


Is PCR15 checked against a pre-calculated value saved in the signed initrd before leaving initrd? If it's not the case, then when executing the init from the chrooted malicious partition, the original /dev/sda1 LUKS will be opened and mounted as var.

Aplanas talked about this check in previous conversation, I'm wondering if it is the case currently. Otherwise it may be easy for an attacker to force a measurement drop and foll the initrd like this case.



Best,
Adrian 

[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux