osresearch / safeboot

Scripts to slightly improve the security of the Linux boot process with UEFI Secure Boot and TPM support
https://safeboot.dev/
GNU General Public License v2.0
268 stars 28 forks source link

Eventlog mutability attack #139

Open osresearch opened 2 years ago

osresearch commented 2 years ago

There is potentially an attack against eventlogs that takes advantage of the fact that only the PCRIndex and Digest are protected by the signature on the TPM quote, the EventType is not included: https://github.com/google/go-attestation/blob/master/docs/event-log-disclosure.md

After gaining code execution, an adversary could modify the eventlog EventType for all of the earlier events to be EV_UNUSED or some other type that might be ignored by the eventlog parser in the attestation server, and then add new events of the correct type, but with their own digests, to both the log and to the real PCRs. When the attacker generates a quote, the PCRs and the eventlog will be consistent, and the attestation server might be tricked into thinking a different PK or SecureBoot setup is included in the quote.

We verify that the eventlog and PCR in the quote are consistent and valid; we should also be sure that we throw an attestation verification error if there are unexpected event types or if the event types do not match.

osresearch commented 2 years ago

I think this means that we can't have any ignored entries in the log at all; the verifier must have every operation (type and digest) on its allowed-list. This potentially causes a problem for something like dbx, which is an ever growing trash heap of data and likely to be one that we don't care about, but now need to ensure that it's presence in the eventlog doesn't become a way to mask valid PCR extensions.

nicowilliams commented 2 years ago

How does this work without having a collision attack on the digest?

EDIT: Ah, this is a possible bug in PCR/eventlog validators, where they compute the hash extension using all the eventlog entries, but don't check the validity of any individual extensions marked ignore. I.e., when validating PCRs and eventlogs one must not ignore entries marked ignore, and, indeed, one must ignore the entry types since those are unauthenticated.

osresearch commented 2 years ago

Exactly -- the issue is that the validator parsing the eventlog to determine which kernel was loaded. By replacing all of the real boot time event types with ignored events, the attacker with code execution on the system can craft an eventlog and PCR values that match whatever they want.

Using a zero-valued PCR as a "policy cap" to prevent secrets from being unsealed prevents this from working if the attacker gets code execution later on a normal boot after the cap PCR has been extended, although an attacker who can control the system prior to attestation could still bypass this.

I think the dbx issue is not a problem if we've replaced the PK, since Microsoft or whoever can't sign updates to dbx, so it won't be accumulating garbage.

nicowilliams commented 2 years ago

Right, so, one fix is that TPM2_Quote() has a qualifyingData command parameter that can be a digest of all other data the client might send to the server, including the eventlog. This doesn't work when the client is compromised.

The real fix is to the validators, naturally. They MUST NOT ignore ignore entries.

Besides fixing the validators, we could have a specialty validator whose job is to fail if there are entries of unknown types. We still need the types to be accurate though.

nicowilliams commented 2 years ago

Ultimately it seems like the problem is in the PC platform spec: the eventlog entry types should be part of what gets extended into the relevant PCRs.

nicowilliams commented 2 years ago

Currently we use only the nonce (timestamp) as the quote's qualifyingData. We could digest the event and ima logs and the nonce and use that digest as the qualifyingData.