署名されたUEFIバイナリを確認する方法は?

署名されたUEFIバイナリを確認する方法は?

私のコンピュータでセキュアブートが機能する理由を理解しようとしています。 UEFI設定で有効になっており、すべてが正常に起動してmokutil --sb-state表示されますSecureBoot enabled。しかし、そうしてはいけないようです。私が知る限り、どのように機能するかは次のとおりです。

  1. デバイスの電源を入れると、内蔵ファームウェアが起動し始めました。
  2. ファームウェアはシム(Microsoftが署名したもの)をチェックし、そのシムにジャンプします。
  3. シムはGRUB(配布版から署名済み)を確認し、対応するGRUBにジャンプします。
  4. GRUBは設定、initrd(私の署名箱)、カーネル(配布版からの署名箱)を確認し、カーネルを起動します。
  5. カーネルは、モジュールをロードする前にディストリビューションで署名したモジュールを確認します。

手動で確認しようとすると、有効な署名がある唯一のものはシムです。。 GRUBとカーネルイメージに署名が含まれていますが、検証に失敗します。 initrd および grub 構成が署名されていません。しかし、システムの起動は自信を呼び起こしません。

mokutil私は、、、およびsbverifyを使用しましたosslsigncode。たぶん、これらは正しいツールではないかもしれません。セキュアブートが実際に無効になっている可能性がありますか?できるだけ多くの情報を提供するよう努めます。

これは私がしたことです。

mokutilまず、参照用発行者とサブジェクトを使用して、信頼できる公開鍵の両方をエクスポートして表示しました。

# mokutil --export --pk
# mokutil --export --kek
# mokutil --export --db
# mokutil --export
# for derfile in ./*.der; do
>     openssl x509 -inform der -outform pem -in "$derfile" -out "${derfile}.pem"
> done
# rename 's/.der.pem$/.pem/' ./*.der.pem
# for pemfile in ./*.pem; do
>     echo "$pemfile"
>     openssl x509 -inform pem -in "$pemfile" -text | egrep 'CN ?='
> done
./DB-0001.pem
        Issuer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Root Certificate Authority 2010
        Subject: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Windows Production PCA 2011
./DB-0002.pem
        Issuer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Corporation Third Party Marketplace Root
        Subject: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Corporation UEFI CA 2011
./DB-0003.pem
        Issuer: C = US, O = HP Inc., CN = HP Inc. DB Key 2016 CA
        Subject: CN = HP UEFI Secure Boot DB 2017, OU = CODE-SIGN, C = US, O = HP Inc.
./KEK-0001.pem
        Issuer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Corporation Third Party Marketplace Root
        Subject: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = Microsoft Corporation KEK CA 2011
./KEK-0002.pem
        Issuer: C = US, O = HP Inc., CN = HP Inc. KEK 2016 CA
        Subject: CN = HP UEFI Secure Boot KEK 2017, OU = CODE-SIGN, C = US, O = HP Inc.
./MOK-0001.pem
        Issuer: CN = strib.tech
        Subject: CN = strib.tech
./MOK-0002.pem
        Issuer: CN = Debian Secure Boot CA
        Subject: CN = Debian Secure Boot CA
./PK-0001.pem
        Issuer: C = US, O = HP Inc., CN = HP Inc. PK 2016 CA
        Subject: CN = HP UEFI Secure Boot PK 2017, OU = CODE-SIGN, C = US, O = HP Inc.

その後、これらすべての公開鍵を使用してすべての関連ファイルを確認したいと思いますsbverify

# for imgfile in /boot/vmlinuz-* /boot/initrd.img-* /boot/efi/EFI/devuan/*; do
>     for pemfile in ./*.pem; do
>         sbverify --cert "$pemfile" "$imgfile" &> /dev/null && echo "$imgfile is signed with $pemfile"
>     done
> done
/boot/efi/EFI/devuan/shimx64.efi is signed with ./DB-0002.pem

こんな。理由を確認してみましょう。ここではGRUBイメージをお見せしますが、シムヘルパーモジュールとカーネルイメージも状況は同じです。

# sbverify --list /boot/efi/EFI/devuan/grubx64.efi
signature 1
image signature issuers:
 - /CN=Debian Secure Boot CA
image signature certificates:
 - subject: /CN=Debian Secure Boot Signer 2020
   issuer:  /CN=Debian Secure Boot CA

署名キーで署名されたと主張しますMOK-0002.pem。私にその鍵がないかもしれないか?知っていると、署名と同じファイルに隠されていました。だから取り出しました。

# osslsigncode extract-signature -pem -in /boot/efi/EFI/devuan/grubx64.efi -out signature.pem
Succeeded
# openssl pkcs7 -in signature.pem -print_certs -out intermediate.pem
# openssl x509 -in intermediate.pem -text | grep CN
        Issuer: CN = Debian Secure Boot CA
        Subject: CN = Debian Secure Boot Signer 2020

残念ながら、確認はまだ失敗しています。intermediate.pemを任意の順序で組み合わせたり、MOK-0002.pem以前にごみ箱を削除した場合にも同様ですBEGIN CERTIFICATE

# sbverify --cert intermediate.pem /boot/efi/EFI/devuan/grubx64.efi
Signature verification failed

osslsigncodeには確認オプションもあり、sbverifyよりも多くの情報を提供します。

# osslsigncode verify -in /boot/efi/EFI/devuan/grubx64.efi -CAfile both.pem -verbose
Current PE checksum   : 00183046
Calculated PE checksum: 00183046

Signature Index: 0  (Primary Signature)
Message digest algorithm  : SHA256
Current message digest    : A9BDE7F125657CB9E30974274B8B2762B2AA7CB86D8DE9386A645A49077AAF8E
Calculated message digest : A9BDE7F125657CB9E30974274B8B2762B2AA7CB86D8DE9386A645A49077AAF8E

Signer's certificate:
    Signer #0:
        Subject: /CN=Debian Secure Boot Signer 2020
        Issuer : /CN=Debian Secure Boot CA
        Serial : B55EB3B9
        Certificate expiration date:
            notBefore : Jul 21 15:52:54 2020 GMT
            notAfter : Jul 21 15:52:54 2030 GMT

Number of certificates: 1
    Signer #0:
        Subject: /CN=Debian Secure Boot Signer 2020
        Issuer : /CN=Debian Secure Boot CA
        Serial : B55EB3B9
        Certificate expiration date:
            notBefore : Jul 21 15:52:54 2020 GMT
            notAfter : Jul 21 15:52:54 2030 GMT

CAfile: both.pem
TSA's certificates file: /usr/lib/ssl/certs/ca-bundle.crt

Timestamp is not available

Unsupported Signer's certificate purpose XKU_CODE_SIGN
Signature verification: failed

Number of verified signatures: 1
Failed

おそらく、shimは証明書の使用など、他のすべての重複フィールドを無視できます。私はそれに問題はありません。ただし、これを信用するには、修正されたGRUBイメージで他のエラーを確認する必要があります。問題は、あちこちで数バイトを上書きすると、osslsigncodeがセグフォルトのみ発生することです。

部分的な解決策

私はinitrdをカーネルイメージに含め、GRUB構成をGRUBイメージに含めることができることを知っています。その後、自分のキーで署名できますMOK-0001.pem。したがって、これらの署名を確認できれば、デフォルトでは作業は完了です。カーネルモジュールを検証するのは素晴らしいですが、検証されたinitrdまたはLUKSパーティションからロードされるため、大きな問題ではありません。

カーネルモジュールはどうですか?

カーネルモジュールはファイル形式に基づいて署名されていますmodinfosbverify不明)。osslsigncode

# modinfo iwlwifi | egrep -A12 '^sig'
sig_id:         PKCS#7
signer:         Debian Secure Boot CA
sig_key:        B5:5E:B3:B9
sig_hashalgo:   sha256
signature:      A1:B8:D5:51:C0:C2:80:AD:01:7A:6E:E9:E9:96:E8:BB:4F:53:7F:09:
        1A:62:04:8F:5A:62:97:0C:37:0D:98:17:C4:30:E3:39:9D:4B:FB:7E:
        64:03:69:CA:A6:37:59:8C:F9:05:66:FB:A5:F1:66:88:8B:11:75:05:
        0C:52:8B:A4:44:D7:70:BD:02:9F:29:1C:87:F4:37:15:6F:83:C8:D7:
        2B:BC:CE:F9:9E:D4:D2:23:5A:26:48:A1:C7:43:A7:74:0C:6A:9C:18:
        12:A7:D5:93:F2:D8:0D:9D:28:6F:34:CD:88:79:A1:26:32:D3:9F:BF:
        8F:B7:91:CA:AF:1E:36:96:B0:F8:FA:B9:05:80:A5:E3:5B:5C:BB:A8:
        5B:EC:5D:B6:97:B8:8F:00:99:62:69:19:C5:58:F4:13:D9:3C:5A:C0:
        9F:08:49:43:CF:30:DB:CD:8E:9B:6F:65:21:5E:64:68:5B:33:26:93:
        38:F5:DA:40:B1:F4:5F:E9:A0:E3:C3:10:C6:0C:EA:A1:42:BF:A8:DD:
        59:88:32:E9:7B:4A:2B:0D:89:9D:6F:E7:CE:0D:A6:E9:28:D8:3F:C8:
        B1:4F:FC:DD:35:22:D6:23:C4:86:C3:78:1F:5D:E8:2E:FD:3E:D4:D8:
        CC:30:1D:BF:5A:2C:C2:2E:83:E8:63:CB:1F:D3:7D:FD

modinfoが実際にこれを検証するのか、見つかった署名だけを印刷するのかはわかりません。私は失敗するように.koファイルでランダムなバイトを変更しようとしましたが、署名が原因であるのか、それともELFチェックサムが原因であるのか、エラーメッセージからはわかりません。

# modinfo iwlwifi.ko
filename:       /root/iwlwifi.ko
modinfo: ERROR: could not get modinfo from 'iwlwifi': Invalid argument

修正する

osslsigncodeソースコードを修正したので、署名を確認できるようになりました。問題は、証明書を使用するためにXKU_CODE_SIGNを明示的に無効にすることです。

--- osslsigncode-2.1.orig/osslsigncode.c
+++ osslsigncode-2.1/osslsigncode.c
@@ -2521,12 +2521,6 @@ static int verify_authenticode(SIGNATURE
            goto out;
    }
 
-   /* check extended key usage flag XKU_CODE_SIGN */
-   if (!(X509_get_extended_key_usage(signer) & XKU_CODE_SIGN)) {
-       printf("Unsupported Signer's certificate purpose XKU_CODE_SIGN\n");
-       goto out;
-   }
-
    verok = 1; /* OK */
 out:
    if (!verok)

この新しいバージョンでは、シムヘルパーモジュール、GRUB、およびカーネルを正常に確認できます。これで、grub-mkstandalone組み込みの公開鍵と最小限の構成を使用してGRUBイメージを作成できます。署名確認の有効化そして基本設定をロードします。これはGRUBから読み込まれたすべてのファイルをカバーし、古いGPG分離署名を使用します。これは使用する必要がないことを意味しますCONFIG_INITRAMFS_SOURCE(非常に面倒です)。

Artem S. Tashkinovの答えは、カーネルモジュールの状況を明確にしました。私の考えでは、それはすべてだったと思います。起動可能な署名付きUSBスティックを作成し、そこにキーを保存します。 GRUBを更新するために必要です(頻繁に発生しないでください)。

ベストアンサー1

これは答えではなく、関連性があると考えて追加したいコメントです。

セキュアブートEFIメカニズムただ実行中のバイナリやライブラリ(実行コードなど)の署名を確認しますが、起動を不可能にするそれ以上のものは確認せず、確認することもできません。すべてのオペレーティングシステムは、起動する場所とこの情報のソースを知る必要があります。ユーザーが変更できる署名されていない構成ファイルたとえば、/boot/efi/EFI/Microsoft/Boot/BCDWindows および/boot/efi/EFI/$distro/grub.cfgLinux ディストリビューションの場合。

ほとんどすべての既存のディストリビューションで使用されているLinuxでは、initrd攻撃者がinitrdを修正し、デバイスへのハードウェアアクセスを取得できないようにするすべての保護を完全に迂回する可能性があるため、この状況は少し恐ろしいです。気になる方はぜひお召し上がりくださいただデバイスの暗号化されたストレージと暗号化されたUSBフラッシュドライブから起動します。

最後に、あなたの質問に答えることができず、もう一度申し訳ありません。このコマンドは、システムがセーフブートモードで実行されているかどうかを通知します。

dmesg | grep -i secure\ boot\ enabled

最後に、かmodinfoどうかいいえ署名を確認すると、署名が表示されます。カーネルは確かにこれを行います。以下を使用して任意のバイトを変更した後の結果は次のとおりですhexedit

# modprobe orangefs 
modprobe: ERROR: could not insert 'orangefs': Key was rejected by service

おすすめ記事