Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ValdikSS committed Feb 25, 2019
0 parents commit e0436f8
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 0 deletions.
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Super UEFIinSecureBoot Disk
===========================

Super UEFIinSecureBoot Disk is a bootable image with GRUB2 bootloader designed to be used as a base for recovery USB flash drives.

**Key feature:** disk is fully functional with UEFI Secure Boot mode activated. It can launch any operating system or .efi file, even with untrusted, invalid or missing signature.

## Features:

* GRUB2 Bootloader
* 32-bit (ia32) / 64-bit (x86_64) UEFI (+ Secure Boot) support
* BIOS / UEFI CSM support
* Launch any operating system
* Launch any .efi executable from GRUB2
* Launch any .efi executable from another .efi application
* Load any UEFI drivers

## Based on:

* [Red Hat shim](https://github.com/rhboot/shim) 13, [from Fedora](https://apps.fedoraproject.org/packages/shim-signed), signed with Microsoft key, for initial boot
* Modified [Linux Foundation PreLoader](https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git) to install circumventing UEFI Security Policy
* GRUB2 with security bypass patches to chainloader, linux/linuxefi and shim

## Description

Secure Boot is a feature of UEFI firmware which is designed to secure the boot process by preventing the loading of drivers or OS loaders that are not signed with an acceptable digital signature.

Most of modern computers come with Secure Boot enabled by default, which is a requirement for Windows 10 certification process. Although it could be disabled on all typical motherboards in UEFI setup menu, sometimes it's not easily possible e.g. due to UEFI setup password in a corporate laptop which the user don't know.

This disk, after being installed on a USB flash drive and booted from, effectively disables Secure Boot protection features and temporary allows to perform almost all actions with the PC as if Secure Boot is disabled. This could be useful for data recovery, OS re-installation, or just for booting from USB without thinking about additional steps.

## Installation

Download [image file from releases page](/ValdikSS/Super-UEFIinSecureBoot-Disk/stargazers/releases), write it to USB flash using one of the following programs:

* [Rosa ImageWriter](http://wiki.rosalab.ru/en/index.php/ROSA_ImageWriter) (for Windows and Linux)
* [Etcher](https://www.balena.io/etcher/) (for Windows, Linux and macOS)

## Usage

First boot on a PC with Secure Boot will show Access Violation message box. Press OK and choose "Enroll cert from file" menu option. Select `ENROLL_THIS_KEY_IN_MOKMANAGER.cer` and confirm certificate enrolling.

Computers without Secure Boot will boot to GRUB without manual intervention.

## Technical information

UEFI boot process of this disk is performed in 3 stages.

`bootx64.efi (shim) → grubx64.efi (preloader) → grubx64_real.efi (grub2) → EFI file/OS`

**Stage 1**: motherboard loads shim. Shim is a special loader which just loads next executable, grubx64.efi (preloader) in our case. Shim is signed with Microsoft key, which allows it to be launched in Secure Boot mode on all stock PC motherboards.
Shim contains embedded Fedora certificate (because it's extracted from Fedora repository). If Secure Boot is enabled, since grubx64.efi is not signed with embedded Fedora certificate, shim boots another executable, MokManager.efi, which is a special shim key management software. MokManager asks user to proceed with key or hash enrolling process.
Newer versions of shim install hooks for UEFI LoadImage, StartImage, ExitBootServices and Exit functions to "Harden against non-participating bootloaders", which should be bypassed for this disk use-case. Fedora's shim does not install custom UEFI security policies, that's why it's not possible to load self-signed efi files from second stage bootloader, even if you add their hashes or certificates using MokManager.

**Stage 2**: preloader is a software similar to shim. It also performs executable validation and loads next efi file. Preloader included in this disk is a stripped down version which performs only one function: install allow-all UEFI security policy. This permits loading of arbitrary efi executables with LoadImage/StartImage UEFI functions even outside GRUB (for example, in UEFI Shell).

**Stage 3**: GRUB2 is a well-known universal bootloader. It has been patched to load .efi (or linux kernel) binaries into memory and jump into its entry point, without using UEFI functions, and to mimic "participating bootloader" for shim.
26 changes: 26 additions & 0 deletions build-notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
certutil -d /etc/pki/pesign -N
efikeygen -C -S -k -n grub -c "CN=grub"
pesign -C grub.cer -c grub
rpmbuild -ba grub2.spec --define "_sourcedir $PWD" --define "_topdir $PWD/rpmbuild" --define "efi_vendor grub" --define "pe_signing_cert grub"

unpack everything

grub2-mkimage -v -C auto -O i386-pc --prefix '(,msdos1)/efi/grub' -o EFI/grub/i386-pc/core.img 'fat' 'part_msdos' 'biosdisk' 'xzio' 'gcry_crc'

fallocate -l 501M uefi-insecureboot-minimal.img
fdisk uefi-insecureboot-minimal.img
n
p
1
2048
enter
t
C
w
sudo losetup -Pf uefi-insecureboot-minimal.img
sudo mkfs.vfat -F 32 /dev/loop0p1
sudo mount /dev/loop0p1 mp
cd mp
cp -r ../../filesystem/EFI .

sudo grub2-bios-setup /dev/loop0 -d EFI/grub/i386-pc/ -v
2 changes: 2 additions & 0 deletions efi-tools-patches/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Apply to
https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/snapshot/efitools-1.9.2.tar.gz
77 changes: 77 additions & 0 deletions efi-tools-patches/preloader.c.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--- a/efitools-1.9.2/PreLoader.c 2019-01-09 01:13:13.000000000 +0300
+++ b/efitools-1.9.2/PreLoader.c 2019-02-25 05:24:46.808742187 +0300
@@ -14,10 +14,7 @@
#include <security_policy.h>
#include <execute.h>

-#include "hashlist.h"
-
-CHAR16 *loader = L"loader.efi";
-CHAR16 *hashtool = L"HashTool.efi";
+CHAR16 *loader = L"grubia32_real.efi";

EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
@@ -52,13 +49,6 @@
goto override;
}

- /* install statically compiled in hashes */
- security_protocol_set_hashes(_tmp_tmp_hash, _tmp_tmp_hash_len);
-
- /* Check for H key being pressed */
- if (console_check_for_keystroke('H'))
- goto start_hashtool;
-
status = execute(image, loader);

if (status == EFI_SUCCESS)
@@ -74,48 +64,6 @@
goto out;
}

- console_alertbox((CHAR16 *[]) {
- L"Failed to start loader",
- L"",
- L"It should be called loader.efi (in the current directory)",
- L"Please enrol its hash and try again",
- L"",
- L"I will now execute HashTool for you to do this",
- NULL
- });
-
- for (;;) {
- start_hashtool:
- status = execute(image, hashtool);
-
- if (status != EFI_SUCCESS) {
- CHAR16 buf[256];
-
- StrCpy(buf, L"Failed to start backup programme ");
- StrCat(buf, hashtool);
- console_error(buf, status);
-
- goto out;
- }
-
- /* try to start the loader again */
- status = execute(image, loader);
- if (status == EFI_ACCESS_DENIED
- || status == EFI_SECURITY_VIOLATION) {
- int selection = console_select((CHAR16 *[]) {
- L"loader is still giving a security error",
- NULL
- }, (CHAR16 *[]) {
- L"Start HashTool",
- L"Exit",
- NULL
- }, 0);
- if (selection == 0)
- continue;
- }
-
- break;
- }
out:
status = security_policy_uninstall();
if (status != EFI_SUCCESS)
85 changes: 85 additions & 0 deletions efi-tools-patches/security-policy.c.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
--- a/efitools-1.9.2/lib/security_policy.c 2019-01-09 01:13:13.000000000 +0300
+++ b/efitools-1.9.2/lib/security_policy.c 2019-02-25 05:11:58.714084094 +0300
@@ -53,80 +53,17 @@

BOOLEAN security_policy_mok_override(void)
{
- UINT8 *VarData;
- UINTN VarLen;
- UINT32 attr;
- EFI_STATUS status;
-
- /* Secure Boot Override: MokSBState. If we're in insecure mode, boot
- * anyway regardless of dbx contents */
- status = get_variable_attr(L"MokSBState", &VarData, &VarLen,
- MOK_OWNER, &attr);
- if (status == EFI_SUCCESS) {
- UINT8 MokSBState = VarData[0];
-
- FreePool(VarData);
- if ((attr & EFI_VARIABLE_RUNTIME_ACCESS) == 0
- && MokSBState)
- return TRUE;
- }
- return FALSE;
+ return TRUE;
}

BOOLEAN security_policy_mok_deny(VOID *data, UINTN len)
{
- EFI_STATUS status;
- UINT8 hash[SHA256_DIGEST_SIZE];
-
- status = sha256_get_pecoff_digest_mem(data, len, hash);
- if (status != EFI_SUCCESS)
- return TRUE;
-
- if (find_in_variable_esl(L"dbx", SIG_DB, hash, SHA256_DIGEST_SIZE)
- == EFI_SUCCESS)
- /* MOK list cannot override dbx */
- return FALSE;
-
- if (find_in_variable_esl(L"MokListX", SIG_DB, hash, SHA256_DIGEST_SIZE)
- == EFI_SUCCESS)
- return TRUE;
-
return FALSE;
}

BOOLEAN security_policy_mok_allow(VOID *data, UINTN len)
{
- EFI_STATUS status;
- UINT8 hash[SHA256_DIGEST_SIZE];
- UINT32 attr;
- UINT8 *VarData;
- UINTN VarLen;
-
-
- status = sha256_get_pecoff_digest_mem(data, len, hash);
- if (status != EFI_SUCCESS)
- return TRUE;
-
- status = get_variable_attr(L"MokList", &VarData, &VarLen, MOK_OWNER,
- &attr);
- if (status != EFI_SUCCESS)
- goto check_tmplist;
-
- FreePool(VarData);
-
- if (attr & EFI_VARIABLE_RUNTIME_ACCESS)
- goto check_tmplist;
-
- if (find_in_variable_esl(L"MokList", MOK_OWNER, hash, SHA256_DIGEST_SIZE) == EFI_SUCCESS)
- return TRUE;
-
- check_tmplist:
- if (security_policy_esl
- && find_in_esl(security_policy_esl, security_policy_esl_len, hash,
- SHA256_DIGEST_SIZE) == EFI_SUCCESS)
- return TRUE;
-
- return FALSE;
+ return TRUE;
}

static EFIAPI EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
25 changes: 25 additions & 0 deletions grub-patches/9001-Always-assume-Secure-Boot-is-not-enabled.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
From a1cb51ec334a8df3acb92a3ac665624d5e16941f Mon Sep 17 00:00:00 2001
From: ValdikSS <[email protected]>
Date: Sun, 24 Feb 2019 23:31:41 +0300
Subject: [PATCH] Always assume Secure Boot is not enabled

---
grub-core/kern/efi/sb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index d74778b..1d73d84 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -28,7 +28,7 @@
int
grub_efi_secure_boot (void)
{
-#ifdef GRUB_MACHINE_EFI
+#if 0
grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
grub_size_t datasize;
char *secure_boot = NULL;
--
2.20.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
From 660b90ff18f71274105605fb047ce603c2240d6d Mon Sep 17 00:00:00 2001
From: ValdikSS <[email protected]>
Date: Sun, 24 Feb 2019 23:42:40 +0300
Subject: [PATCH] Force GRUB Linux kernel loading method if shim is available

shim hooks LoadImage(), StartImage() and ExitBootServices() UEFI functions to "Harden against non-participating bootloaders", and reboots the system if ExitBootServices is called without trying to boot the image using stock UEFI methods or verify it with shim protocol.
GRUB is considered "participating bootloader" if shim_lock->verify is called, even if it's failed.
Always call ->verify, ignore it and load it our way.
---
grub-core/loader/efi/linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index b56ea0b..43321cf 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -60,7 +60,7 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
(unsigned long) status);

- return -1;
+ return 1;
}

#pragma GCC diagnostic push
--
2.20.1

2 changes: 2 additions & 0 deletions grub-patches/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Apply to
https://kojipkgs.fedoraproject.org//packages/grub2/2.02/62.fc29/src/grub2-2.02-62.fc29.src.rpm

0 comments on commit e0436f8

Please sign in to comment.