서명된 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 파티션에서 로드되므로 큰 문제는 아닙니다.

커널 모듈은 어떻습니까?

커널 모듈은 파일 형식을 기반으로 서명됩니다 modinfo( 알지 sbverify못함 ).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)

이 새 버전에서는 shim 도우미 모듈, 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

관련 정보