From 52a55517499500d00448720800987d88147bad1d Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 22 Jun 2023 11:18:49 +0100 Subject: [PATCH] [uefi] improve revoked UEFI bootloader reporting * Remove duplicates from Microsoft's SKUSiPolicy.p7b * Also display the number of revoked from embedded * Also use Microsoft's official capitalization for SKUSiPolicy.p7b's target path --- src/hash.c | 11 ++++++++++- src/pki.c | 8 ++++++-- src/rufus.c | 7 ++----- src/rufus.h | 3 ++- src/rufus.rc | 10 +++++----- src/wue.c | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/hash.c b/src/hash.c index 862544c0..79d84316 100644 --- a/src/hash.c +++ b/src/hash.c @@ -2117,7 +2117,7 @@ BOOL IsFileInDB(const char* path) return FALSE; } -int IsUefiBootloaderRevoked(const char* path) +int IsBootloaderRevoked(const char* path) { uint32_t i; uint8_t hash[SHA256_HASHSIZE]; @@ -2132,6 +2132,15 @@ int IsUefiBootloaderRevoked(const char* path) return 0; } +void PrintRevokedBootloaderInfo(void) +{ + uprintf("Found %d officially revoked UEFI bootloaders from embedded list", sizeof(pe256dbx) / SHA256_HASHSIZE); + if (ParseSKUSiPolicy()) + uprintf("Found %d additional revoked UEFI bootloaders from this system's SKUSiPolicy.p7b", pe256ssp_size); + else + uprintf("WARNING: Could not parse this system's SkuSiPolicy.p7b for additional revoked UEFI bootloaders"); +} + #if defined(_DEBUG) || defined(TEST) || defined(ALPHA) /* Convert a lowercase hex string to binary. Returned value must be freed */ uint8_t* to_bin(const char* str) diff --git a/src/pki.c b/src/pki.c index 887afbcf..1419c854 100644 --- a/src/pki.c +++ b/src/pki.c @@ -888,8 +888,12 @@ BOOL ParseSKUSiPolicy(void) } // We are only interested in 'DENY' type with PE256 hashes if (FileRuleHeader->Type == CI_DENY && FileRuleData->HashLength == PE256_HASHSIZE) { - memcpy(&pe256ssp[pe256ssp_size * PE256_HASHSIZE], FileRuleData->Hash, PE256_HASHSIZE); - pe256ssp_size++; + // Microsoft has the bad habit of duplicating entries - only add a hash if it's different from previous entry + if ((pe256ssp_size == 0) || + (memcmp(&pe256ssp[(pe256ssp_size - 1) * PE256_HASHSIZE], FileRuleData->Hash, PE256_HASHSIZE) != 0)) { + memcpy(&pe256ssp[pe256ssp_size * PE256_HASHSIZE], FileRuleData->Hash, PE256_HASHSIZE); + pe256ssp_size++; + } } pbRule = &pbRule[sizeof(CIFileRuleData) + ((FileRuleData->HashLength + sizeof(DWORD) - 1) / sizeof(DWORD)) * sizeof(DWORD)]; } diff --git a/src/rufus.c b/src/rufus.c index 722ce82e..8cf95d29 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1635,7 +1635,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) uprintf("Warning: Failed to extract '%s' to check for UEFI revocation", efi); continue; } - r = IsUefiBootloaderRevoked(tmp); + r = IsBootloaderRevoked(tmp); if (r > 0) { MessageBoxExU(hMainDialog, lmprintf(MSG_339, (r == 1) ? lmprintf(MSG_340) : lmprintf(MSG_341, "Error code: 0xc0000428")), @@ -2063,10 +2063,7 @@ static void InitDialog(HWND hDlg) "one. Because of this, some messages will only be displayed in English.", selected_locale->txt[1]); uprintf("If you think you can help update this translation, please e-mail the author of this application"); } - if (ParseSKUSiPolicy()) - uprintf("Found %d revoked UEFI bootloaders from this system's SKUSiPolicy", pe256ssp_size); - else - uprintf("WARNING: Could not parse this system's SkuSiPolicy"); + PrintRevokedBootloaderInfo(); // Detect and report system limitations if (ReadRegistryKeyBool(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Policies\\Microsoft\\FVE")) uprintf("WARNING: This system has a policy set to prevent write access to FIXED drives not using BitLocker"); diff --git a/src/rufus.h b/src/rufus.h index 7705d2a7..dddb5851 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -704,7 +704,8 @@ extern BOOL HashFile(const unsigned type, const char* path, uint8_t* sum); extern BOOL PE256File(const char* path, uint8_t* hash); extern BOOL HashBuffer(const unsigned type, const uint8_t* buf, const size_t len, uint8_t* sum); extern BOOL IsFileInDB(const char* path); -extern int IsUefiBootloaderRevoked(const char* path); +extern int IsBootloaderRevoked(const char* path); +extern void PrintRevokedBootloaderInfo(void); extern BOOL IsBufferInDB(const unsigned char* buf, const size_t len); #define printbits(x) _printbits(sizeof(x), &x, 0) #define printbitslz(x) _printbits(sizeof(x), &x, 1) diff --git a/src/rufus.rc b/src/rufus.rc index 9203bdef..c6a5df6a 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.2.2054" +CAPTION "Rufus 4.2.2055" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -392,8 +392,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,2,2054,0 - PRODUCTVERSION 4,2,2054,0 + FILEVERSION 4,2,2055,0 + PRODUCTVERSION 4,2,2055,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -411,13 +411,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.2.2054" + VALUE "FileVersion", "4.2.2055" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.2.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.2.2054" + VALUE "ProductVersion", "4.2.2055" END END BLOCK "VarFileInfo" diff --git a/src/wue.c b/src/wue.c index e95c925c..f0423312 100644 --- a/src/wue.c +++ b/src/wue.c @@ -485,7 +485,7 @@ BOOL CopySKUSiPolicy(const char* drive_name) return r; static_sprintf(src, "%s\\SecureBootUpdates\\SKUSiPolicy.p7b", system_dir); - static_sprintf(dst, "%s\\efi\\microsoft\\boot\\SKUSiPolicy.p7b", drive_name); + static_sprintf(dst, "%s\\EFI\\Microsoft\\Boot\\SKUSiPolicy.p7b", drive_name); if ((_stat64U(dst, &stat64) != 0) && (_stat64U(src, &stat64) == 0)) { uprintf("Copying: %s (%s) (from %s)", dst, SizeToHumanReadable(stat64.st_size, FALSE, FALSE), src); r = CopyFileU(src, dst, TRUE);