Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Bei Geräten mit Trusted Platform Module (TPM) lässt sich mithilfe des Nachweises beweisen, dass die Boot-Integrität nicht beeinträchtigt ist. Ferner können mit dem Kontrollierten Startprozess frühere Boot-Funktionszustände erkannt werden.
Immer mehr Gerätetypen, Startladeprogramme und Startstapelangriffe erfordern eine Nachweislösung, um sich entsprechend zu entwickeln. Ein bestätigter Zustand eines Geräts wird durch die Nachweisrichtlinie gesteuert, die verwendet wird, um die Inhalte auf den Plattformbeweis zu überprüfen.
In diesem Artikel finden Sie eine Übersicht über den TPM-Nachweis und die von Azure Attestation unterstützten Funktionen.
Übersicht
Der TPM-Nachweis beginnt mit der Überprüfung des TPM selbst bis zum Punkt, an dem eine vertrauende Partei den Boot-Fluss überprüfen kann.
Im Allgemeinen basiert der TPM-Nachweis auf den folgenden Elementen:
Überprüfen der TPM-Echtheit
Überprüfen Sie die TPM-Echtheit, indem Sie das TPM überprüfen.
- Jedes TPM wird mit einem eindeutigen asymmetrischen Schlüssel, dem Endorsement Key (EK), ausgeliefert. Dieser Schlüssel wird vom Hersteller gebrannt. Der öffentliche Teil dieses Schlüssels wird als EKPub bezeichnet. Der zugeordnete private Schlüssel wird als EKPriv bezeichnet. Einige TPM-Chips verfügen darüber hinaus über ein EK-Zertifikat, das vom Hersteller für den EKPub ausgestellt wird. Dieses Zertifikat wird als EKCert bezeichnet.
- Eine Zertifizierungsstelle (ZS) stellt per EKPub oder EKCert fest, ob das TPM vertrauenswürdig ist.
- Ein Gerät prüft für die ZS, dass der Schlüssel, für den das Zertifikat angefordert wurde, kryptografisch an den EKPub gebunden ist und dass das TPM den EKpriv besitzt.
- Die ZS stellt ein Zertifikat mit einer speziellen Ausstellungsrichtlinie aus, auf der bescheinigt ist, dass der Schlüssel jetzt durch ein TPM geschützt ist.
Überprüfen der während des Bootens vorgenommenen Messungen
Überprüfen Sie die Messungen, die während des Startvorgangs vorgenommen wurden, mithilfe von Azure Attestation.
- Im Rahmen des Vertrauenswürdigen Starts und des Kontrollierten Starts wird jeder Schritt überprüft und im TPM erfasst. Unterschiedliche Ereignisse werden für unterschiedliche Plattformen gemessen. Weitere Informationen zu dem kontrollierten Startvorgang in Windows finden Sie unter Sichern des Windows-Startvorgangs.
- Beim Start wird ein Nachweisidentitätsschlüssel generiert. Er dient dem Nachweisdienst als kryptografischer Nachweis darüber, dass dem verwendeten TPM nach Durchführung der EK-Validierung ein Zertifikat ausgestellt wurde.
- Die vertrauende Seite, kann selber einen Nachweis mit Azure Attestation durchführen, mit dem Messungen, die während des Startvorgangs vorgenommen wurden, überprüft werden können.
- Eine vertrauende Partei kann sich dann auf die Bescheinigungserklärung verlassen, um Zugriff auf Ressourcen oder andere Aktionen zu erhalten.
Die TPM-Bestätigung kann konzeptionell wie im vorherigen Diagramm dargestellt visualisiert werden. Die vertrauende Seite wendet Azure Attestation an, um die Integrität der Plattform und jegliche Verstöße gegen gemachte Zusagen zu überprüfen. Der Überprüfungsprozess bietet Ihnen die Sicherheit, die Sie brauchen, um Workloads auszuführen oder den Zugriff auf Ressourcen bereitzustellen.
Schutz vor böswilligen Boot-Angriffen
Ausgereifte Angriffstechniken zielen darauf ab, die Startkette zu infizieren. Ein Startangriff kann dem Angreifer Zugriff auf Systemressourcen bieten und ihm ermöglichen, sich vor Antischadsoftware zu verstecken. Ein sicherer Start ist eine erste Verteidigungslinie. Durch einen sicheren Start und den Nachweis wird die Funktion auf vertrauende Seiten erweitert. Die meisten Angreifer versuchen, den sicheren Start zu umgehen oder eine unerwünschte Binärdatei im Startprozess zu laden.
Der Remotenachweis ermöglicht es den vertrauenden Seiten, die gesamte Startkette auf Verstöße gegen Zusagen zu überprüfen. Beispielsweise werden bei der Bewertung des sicheren Starts durch den Nachweisdienst die Werte der von der UEFI kontrollierten sicheren Variablen überprüft.
Durch die Instrumente für den kontrollierten Start wird sichergestellt, dass die kryptografisch gebundenen Messungen nicht geändert werden können, nachdem sie vorgenommen worden sind, und dass auch nur eine vertrauenswürdige Komponente die Messung vornehmen kann. Aus diesem Grund ist die Überprüfung der sicheren Variablen zur Sicherstellung der Aktivierung ausreichend.
Azure Attestation signiert den Bericht, um sicherzustellen, dass die Integrität des Nachweises auch zum Schutz vor Man-in-the-Middle-Angriffen gewahrt bleibt.
Es kann eine einfache Richtlinie verwendet werden:
version=1.0;
authorizationrules {
=> permit();
};
issuancerules
{
[type=="aikValidated", value==true] &&
[type=="secureBootEnabled", value==true] => issue(type="PlatformAttested", value=true);
};
Manchmal reicht es nicht aus, beim Start nur eine Komponente zu überprüfen. Das Schutzprofil eines Geräts wird durch Überprüfung ergänzender Features, wie es z. B. die Codeintegrität oder die hypervisorgeschützte Codeintegrität (Hypervisor-Protected Code Integrity, HVCI) und der System Guard Secure Launch sind, ergänzt. Sie müssen auch den Start in Augenschein nehmen können, damit Sie etwaige Verstöße bewerten können und wissen, ob Sie der Plattform vertrauen können.
Im folgenden Beispiel werden die Details zum sicheren Start, zur HVCI und zum System Guard Secure Launch anhand der Richtlinienversion 1.2 überprüft. Darüber hinaus wird sichergestellt, dass der unerwünschte (malicious.sys)-Treiber während des Starts nicht geladen wird:
version=1.2;
authorizationrules {
=> permit();
};
issuancerules
{
// Verify if secure boot is enabled
c:[type == "events", issuer=="AttestationService"] => add(type = "efiConfigVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG' && ProcessedData.VariableGuid == '8BE4DF61-93CA-11D2-AA0D-00E098032B8C']"));
c:[type=="efiConfigVariables", issuer=="AttestationPolicy"]=> add(type = "secureBootEnabled", value = JsonToClaimValue(JmesPath(c.value, "[?ProcessedData.UnicodeName == 'SecureBoot'] | length(@) == `1` && @[0].ProcessedData.VariableData == 'AQ'")));
![type=="secureBootEnabled", issuer=="AttestationPolicy"] => add(type="secureBootEnabled", value=false);
// HVCI
c:[type=="events", issuer=="AttestationService"] => add(type="srtmDrtmEventPcr", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `19`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => add(type="hvciEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_HVCI_POLICY | @[?String == 'HypervisorEnforcedCodeIntegrityEnable'].Value")));
c:[type=="hvciEnabledSet", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=ContainsOnlyValue(c.value, 1));
![type=="hvciEnabled", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=false);
// Validating unwanted(malicious.sys) driver is not loaded
c:[type=="events", issuer=="AttestationService"] => add(type="boolProperties", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `13` || PcrIndex == `19` || PcrIndex == `20`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
c:[type=="boolProperties", issuer=="AttestationPolicy"] => issue(type="MaliciousDriverLoaded", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_LOADEDMODULE_AGGREGATION[] | [? EVENT_IMAGEVALIDATED == true && (equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\malicious.sys') || equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\wd\\malicious.sys'))] | @ != null ")));
![type=="MaliciousDriverLoaded", issuer=="AttestationPolicy"] => issue(type="MaliciousDriverLoaded", value=false);
};
Erweitern des Schutzes vor böswilligen Startangriffen über IMA (Integritätsmessungsarchitektur) unter Linux
Linux-Systeme folgen einem ähnlichen Startprozess wie Windows, und mit TPM-Nachweis kann das Schutzprofil auch über den Start in den Kernel hinaus erweitert werden, indem IMA (Integritätsmessungsarchitektur) verwendet wird. Das IMA-Subsystem wurde entwickelt, um zu erkennen, ob Dateien versehentlich oder böswillig geändert wurden, sowohl remote als auch lokal. Es verwaltet eine Laufzeitmessliste und bietet bei Verankerung in einem TPM-Hardwaremodul (Trusted Platform Module) mit einem aggregierten Integritätswert für diese Liste den Vorteil von Resilienz gegenüber Softwareangriffen. Die jüngsten Verbesserungen im IMA-Subsystem ermöglichen es darüber hinaus, nicht dateibasierte Attribute remote zu messen und nachzuweisen. Der Azure-Nachweis unterstützt den Remotenachweis von nicht dateibasierten Messungen, um eine ganzheitliche Sicht auf die Systemintegrität zu bieten.
Wenn Sie IMA mit der folgenden IMA-Richtlinie aktivieren, können Sie dateifremde Attribute messen und zugleich den Nachweis der lokalen Dateiintegrität ermöglichen.
Mithilfe der folgenden Nachweisrichtlinie können Sie jetzt den sicheren Start (secureboot), die Kernelsignatur, die Kernelversion, die von grub übergebene Kernel-Cmdline und andere wichtige Sicherheitsattribute überprüfen, die von IMA unterstützt werden.
version = 1.2;
configurationrules
{
};
authorizationrules
{
[type == "aikValidated", value==true]
=> permit();
};
issuancerules {
// Retrieve all EFI Boot variables with event = 'EV_EFI_VARIABLE_BOOT'
c:[type == "events", issuer=="AttestationService"] => add(type ="efiBootVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_BOOT']"));
// Retrieve all EFI Driver Config variables with event = 'EV_EFI_VARIABLE_DRIVER_CONFIG'
c:[type == "events", issuer=="AttestationService"] => add(type ="efiConfigVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG']"));
// Grab all IMA events
c:[type=="events", issuer=="AttestationService"] => add(type="imaMeasurementEvents", value=JmesPath(c.value, "Events[?EventTypeString == 'IMA_MEASUREMENT_EVENT']"));
// Look for "Boot Order" from EFI Boot Data
c:[type == "efiBootVariables", issuer=="AttestationPolicy"] => add(type = "bootOrderFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'BootOrder'] | length(@) == `1` && @[0].PcrIndex == `1` && @[0].ProcessedData.VariableData"));
c:[type=="bootOrderFound", issuer=="AttestationPolicy"] => issue(type="bootOrder", value=JsonToClaimValue(c.value));
![type=="bootOrderFound", issuer=="AttestationPolicy"] => issue(type="bootOrder", value=0);
// Look for "Secure Boot" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => issue(type = "secureBootEnabled", value = JsonToClaimValue(JmesPath(c.value, "[?ProcessedData.UnicodeName == 'SecureBoot'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData == 'AQ'")));
![type=="secureBootEnabled", issuer=="AttestationPolicy"] => issue(type="secureBootEnabled", value=false);
// Look for "Platform Key" from EFI Boot Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "platformKeyFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'PK'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="platformKeyFound", issuer=="AttestationPolicy"] => issue(type="platformKey", value=JsonToClaimValue(c.value));
![type=="platformKeyFound", issuer=="AttestationPolicy"] => issue(type="platformKey", value=0);
// Look for "Key Exchange Key" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "keyExchangeKeyFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'KEK'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="keyExchangeKeyFound", issuer=="AttestationPolicy"] => issue(type="keyExchangeKey", value=JsonToClaimValue(c.value));
![type=="keyExchangeKeyFound", issuer=="AttestationPolicy"] => issue(type="keyExchangeKey", value=0);
// Look for "Key Database" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "keyDatabaseFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'db'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="keyDatabaseFound", issuer=="AttestationPolicy"] => issue(type="keyDatabase", value=JsonToClaimValue(c.value));
![type=="keyDatabaseFound", issuer=="AttestationPolicy"] => issue(type="keyDatabase", value=0);
// Look for "Forbidden Signatures" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "forbiddenSignaturesFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'dbx'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="forbiddenSignaturesFound", issuer=="AttestationPolicy"] => issue(type="forbiddenSignatures", value=JsonToClaimValue(c.value));
![type=="forbiddenSignaturesFound", issuer=="AttestationPolicy"] => issue(type="forbiddenSignatures", value=0);
// Look for "Kernel Version" in IMA Measurement events
c:[type=="imaMeasurementEvents", issuer=="AttestationPolicy"] => add(type="kernelVersionsFound", value=JmesPath(c.value, "[].ProcessedData.KernelVersion"));
c:[type=="kernelVersionsFound", issuer=="AttestationPolicy"] => issue(type="kernelVersions", value=JsonToClaimValue(c.value));
![type=="kernelVersionsFound", issuer=="AttestationPolicy"] => issue(type="kernelVersions", value=0);
// Look for "Built-In Trusted Keys" in IMA Measurement events
c:[type=="imaMeasurementEvents", issuer=="AttestationPolicy"] => add(type="builtintrustedkeysFound", value=JmesPath(c.value, "[? ProcessedData.Keyring == '.builtin_trusted_keys'].ProcessedData.CertificateSubject"));
c:[type=="builtintrustedkeysFound", issuer=="AttestationPolicy"] => issue(type="builtintrustedkeys", value=JsonToClaimValue(c.value));
![type=="builtintrustedkeysFound", issuer=="AttestationPolicy"] => issue(type="builtintrustedkeys", value=0);
};
Hinweis: Unterstützung für nicht dateibasierte Messungen ist erst ab der Linux-Kernelversion 5.15 verfügbar
Unterstützung für TPM-Schlüsselnachweis
Zahlreiche Anwendungen basieren auf der grundlegenden Verwaltung von Anmeldeinformationen von Schlüsseln und Zertifikaten zum Schutz vor Diebstahl von Anmeldeinformationen, und eine der wichtigsten Möglichkeiten, die Sicherheit der Anmeldeinformationen zu gewährleisten, ist der Einsatz von Schlüsselspeicheranbietern, die zusätzliche Sicherheit vor Schadsoftware und Angriffen bieten. Windows implementiert verschiedene Kryptografieanbieter, die entweder software- oder hardwarebasiert sein können.
Dies sind die zwei wichtigsten:
Microsoft Softwareschlüsselspeicher-Anbieter: Standardanbieter, der Schlüssel softwarebasiert speichert und CNG (Crypto-Next Generation) unterstützt
Kryptografieanbieter für die Microsoft-Plattform: Hardwarebasiert, die Schlüssel werden in einem TPM (Trusted Platform Module) gespeichert; CNG wird ebenfalls unterstützt
Die Verwendung eines Speicheranbieters dient in der Regel dazu, ein Paar aus öffentlichem und privatem Schlüssel zu erstellen, das mit einem Vertrauensanker verkettet ist. Bei der Erstellung können darüber hinaus weitere Eigenschaften verwendet werden, um bestimmte Aspekte des Schlüsselspeichers, der Exportierbarkeit usw. zu unterstützen. Der Schlüsselnachweis ist in diesem Kontext die technische Möglichkeit, einer antwortenden Seite nachzuweisen, dass ein privater Schlüssel in einer nicht exportierbaren Form intern generiert wurde und verwaltet wird. Ein solcher Nachweis kann gepaart mit weiteren Informationen zum Schutz vor Diebstahl von Anmeldeinformationen und Replay-Angriffen beitragen.
TPMs bieten außerdem die Möglichkeit, nachzuweisen, dass Schlüssel in einem TPM vorhanden sind, was eine höhere Sicherheitsgarantie ermöglicht, die durch Nichtexportierbarkeit, Anti-Hammering und Isolation von Schlüsseln weiter gestützt wird. Ein gängiger Anwendungsfall besteht bei Anwendungen, die ein digitales Signaturzertifikat für Abonnentenschlüssel ausstellen und überprüfen, ob der private Signaturschlüssel der Abonnenten in einem genehmigten TPM generiert wurde und verwaltet wird. Die Tatsache, dass die Schlüssel in einem gültigen TPM vorhanden sind, kann mithilfe einer Richtlinie wie unten leicht mit entsprechenden Nichtexportierbarkeitsflags nachgewiesen werden.
version=1.2;
authorizationrules
{
=> permit();
};
issuancerules
{
// Key Attest Policy
// -- Validating key types
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyType", value=JsonToClaimValue(JmesPath(c.value, "jwk.kty")));
c:[type=="x-ms-tpm-other-keys", issuer=="AttestationService"] => add(type="otherKeysTypes", value=JsonToClaimValue(JmesPath(c.value, "[*].jwk.kty")));
c:[type=="requestKeyType", issuer=="AttestationPolicy", value=="RSA"] => issue(type="requestKeyType", value="RSA");
c:[type=="otherKeysTypes", issuer=="AttestationPolicy", value=="RSA"] => issue(type="otherKeysTypes", value="RSA");
// -- Validating tpm_quote attributes
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyQuote", value=JmesPath(c.value, "info.tpm_quote"));
c:[type=="requestKeyQuote", issuer=="AttestationPolicy"] => add(type="requestKeyQuoteHashAlg", value=JsonToClaimValue(JmesPath(c.value, "hash_alg")));
c:[type=="requestKeyQuoteHashAlg", issuer=="AttestationPolicy", value=="sha-256"] => issue(type="requestKeyQuoteHashAlg", value="sha-256");
// -- Validating tpm_certify attributes
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyCertify", value=JmesPath(c.value, "info.tpm_certify"));
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyNameAlg", value=JsonToClaimValue(JmesPath(c.value, "name_alg")));
c:[type=="requestKeyCertifyNameAlg", issuer=="AttestationPolicy", value==11] => issue(type="requestKeyCertifyNameAlg", value=11);
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyObjAttr", value=JsonToClaimValue(JmesPath(c.value, "obj_attr")));
c:[type=="requestKeyCertifyObjAttr", issuer=="AttestationPolicy", value==50] => issue(type="requestKeyCertifyObjAttr", value=50);
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyAuthPolicy", value=JsonToClaimValue(JmesPath(c.value, "auth_policy")));
c:[type=="requestKeyCertifyAuthPolicy", issuer=="AttestationPolicy", value=="AQIDBA"] => issue(type="requestKeyCertifyAuthPolicy", value="AQIDBA");
c:[type=="x-ms-tpm-other-keys", issuer=="AttestationService"] => add(type="otherKeysCertify", value=JmesPath(c.value, "[*].info.tpm_certify"));
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyNameAlgs", value=JsonToClaimValue(JmesPath(c.value, "[*].name_alg")));
c:[type=="otherKeysCertifyNameAlgs", issuer=="AttestationPolicy", value==11] => issue(type="otherKeysCertifyNameAlgs", value=11);
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyObjAttr", value=JsonToClaimValue(JmesPath(c.value, "[*].obj_attr")));
c:[type=="otherKeysCertifyObjAttr", issuer=="AttestationPolicy", value==50] => issue(type="otherKeysCertifyObjAttr", value=50);
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyAuthPolicy", value=JsonToClaimValue(JmesPath(c.value, "[*].auth_policy")));
c:[type=="otherKeysCertifyAuthPolicy", issuer=="AttestationPolicy", value=="AQIDBA"] => issue(type="otherKeysCertifyAuthPolicy", value="AQIDBA");
};