[systemd-devel] Is tpm2-measure-pcr really an additional security?
Diorcet Yann
diorcet.yann at gmail.com
Mon Mar 10 18:25:40 UTC 2025
Le 10/03/2025 à 17:27, Adrian Vovk a écrit :
> Hello,
>
> On Mon, Mar 10, 2025, 12:06 Mikko Rapeli <mikko.rapeli at linaro.org> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20250310/ab084fb9/attachment-0001.htm>
More information about the systemd-devel
mailing list