
Démontre CVE-2022-34302, un contournement de Secure Boot via le bootloader signé New Horizon Datasys dont le chargeur PE/COFF personnalisé intégré exécute des applications UEFI non signées.
New Horizon Datasys Reboot Restore Boot Loader - Bring Your Own Vulnerable UEFI Application (BYOVUA) - Contournement de Secure Boot via un chargeur d'amorçage signé doté d'un chargeur PE/COFF personnalisé intégré qui charge des applications UEFI non signées.
Ce dépôt illustre la technique BYOVUA (Bring Your Own Vulnerable UEFI Application) en exploitant CVE-2022-34302, une vulnérabilité de contournement de Secure Boot dans le chargeur d'amorçage New Horizon Datasys.
Contrairement aux vulnérabilités basées sur le Shell UEFI (CVE-2022-34301 et CVE-2022-34303), ce chargeur d'amorçage n'expose pas de Shell UEFI. À la place, shdloader.efi implémente son propre chargeur PE/COFF personnalisé qui charge un binaire de second étage (shdmgr.ef_) sans utiliser la fonction LoadImage() du firmware et sans effectuer aucune vérification de signature. Un attaquant n'a qu'à remplacer shdmgr.ef_ par n'importe quelle application UEFI compatible pour obtenir une exécution de code arbitraire avec Secure Boot activé.
Il s'agit de la plus dangereuse des trois vulnérabilités divulguées dans la recherche « One Bootloader to Load Them All ». Comme l'a noté Eclypsium : le contournement est intégré, complètement silencieux, et ne laisse aucune indication visuelle à l'écran - le rendant invisible même sur les systèmes dotés d'un moniteur et indétectable sur les systèmes sans tête tels que les serveurs ou les équipements industriels.
BYOVUA est l'équivalent UEFI de la technique BYOVD (Bring Your Own Vulnerable Driver) utilisée au niveau du noyau. Au lieu d'apporter un pilote noyau signé présentant une vulnérabilité, l'attaquant apporte une application UEFI signée qui contient des fonctionnalités capables de compromettre Secure Boot.
Comme shdloader.efi est signé avec un certificat approuvé par Microsoft, il est accepté par Secure Boot sans contestation, ce qui le rend approuvé sur tout système qui inclut ce certificat dans sa base de données Secure Boot (db) - c'est-à-dire pratiquement tous les PC compatibles UEFI livrés au cours de la dernière décennie. Une fois en cours d'exécution, son chargeur PE personnalisé intégré offre à l'attaquant la capacité de charger et d'exécuter du code non signé arbitraire avant le chargement du système d'exploitation, dans un environnement où les contrôles de sécurité modernes (ASLR, DEP, protections du noyau) n'existent tout simplement pas.
shdloader.efi est un chargeur d'amorçage UEFI distribué dans le cadre des produits de restauration et de récupération système de New Horizon Datasys (Reboot Restore Rx, RollBack Rx). Son rôle dans la chaîne d'amorçage légitime est de charger un composant de gestion pré-OS (shdmgr.ef_) qui gère les opérations d'instantané et de restauration avant le démarrage du système d'exploitation.
La vulnérabilité est un défaut de conception dans l'architecture du chargeur d'amorçage. Plutôt que d'utiliser les services d'amorçage LoadImage() et StartImage() du firmware - qui appliquent la vérification de signature Secure Boot - shdloader.efi implémente son propre chargeur PE/COFF personnalisé qui lit, relocalise et exécute shdmgr.ef_ directement à partir des octets bruts du disque, contournant complètement les contrôles de sécurité du firmware.
Le problème fondamental : un binaire signé qui est approuvé par Secure Boot contient son propre chargeur d'image qui ne vérifie pas les signatures. Le firmware valide shdloader.efi comme signé, mais une fois qu'il est en cours d'exécution, il charge shdmgr.ef_ sans aucune vérification. Remplacer shdmgr.ef_ par une application UEFI arbitraire a pour résultat que cette application s'exécute avec un accès matériel complet, tandis que Secure Boot est signalé comme activé.
| Propriété | Valeur |
|---|
| Fichier | shdloader.efi = EFI/Boot/bootx64.efi |
| Éditeur | New Horizon Datasys Inc |
| Produit | Reboot Restore Rx / RollBack Rx |
| CVE | CVE-2022-34302 |
| Signature | Microsoft Windows UEFI Driver Publisher → Microsoft Corporation UEFI CA 2011 |
| Découverte | Eclypsium (Mickey Shkatov, Jesse Michael) - Août 2022 |
| Présentation | DEF CON 30 - « One Bootloader to Load Them All » |
| Révocation | Ajouté à la DBX via Microsoft KB5012170 (Août 2022) |
Cela est fondamentalement différent de CVE-2022-34301 et CVE-2022-34303, où l'attaquant doit interagir avec un Shell UEFI et corrompre manuellement gSecurity2 pour désactiver la vérification. Ici, le contournement est automatique et silencieux - aucune interaction utilisateur, aucune sortie visible, aucune invite de shell.
Le shdloader.efi signé contient sa propre implémentation d'un chargeur d'image PE/COFF. Au lieu d'appeler le service d'amorçage LoadImage() du firmware, qui invoquerait les Security Architectural Protocols et vérifierait la signature de l'image par rapport à la base de données Secure Boot, le chargeur d'amorçage :
\EFI\Boot\shdmgr.ef_ en utilisant le EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.reloc et applique les relocalisations de baseÀ aucun moment de ce processus, le chargeur ne vérifie la signature Authenticode de l'image, ne consulte la base de données Secure Boot (db/dbx), ou n'invoque le EFI_SECURITY2_ARCH_PROTOCOL. L'image est chargée uniquement sur la base de sa validité structurelle PE/COFF.```c
// Pseudocode of what shdloader.efi does internally
//
// NOTE: This is a simplified representation. The actual
// implementation was derived from reverse engineering.
EFI_STATUS LoadShdmgr(VOID) { // Step 1: Open the file File = OpenFile(L"\EFI\Boot\shdmgr.ef_");
// Step 2: Read raw bytes (no signature check)
ReadFile(File, &Buffer, &Size);
// Step 3: Parse PE/COFF headers
DosHeader = (EFI_IMAGE_DOS_HEADER *)Buffer;
PeHeader = (EFI_IMAGE_NT_HEADERS *)(Buffer + DosHeader->e_lfanew);
// Step 4: Allocate memory and copy sections
ImageBase = AllocatePages(...);
CopySections(ImageBase, Buffer, PeHeader);
// Step 5: Apply base relocations from .reloc
Delta = ImageBase - PeHeader->OptionalHeader.ImageBase;
ApplyRelocations(ImageBase, PeHeader, Delta);
// Step 6: Jump to entry point
// NO SIGNATURE VERIFICATION ANYWHERE
EntryPoint = ImageBase + PeHeader->OptionalHeader.AddressOfEntryPoint;
((EFI_IMAGE_ENTRY_POINT)EntryPoint)(ImageHandle, SystemTable);
}
---
<div id='LoadImageVsCustomLoader'/>
### ***LoadImage vs Custom Loader***
La différence entre `LoadImage()` du firmware et le chargeur personnalisé constitue la faille de sécurité critique :```
┌─────────────────────────────────────────────────────────────────────────┐
│ Firmware LoadImage() - How legitimate boot chains work │
│ │
│ bootx64.efi ──> LoadImage("shdmgr.ef_") │
│ │ │
│ ├── Parse PE/COFF headers │
│ ├── Verify Authenticode signature │
│ ├── Check signature against db (allowed) │
│ ├── Check hash against dbx (revoked) │
│ ├── Call gSecurity2->FileAuthenticationState() │
│ │ │ │
│ │ ├── Signature valid? ── YES ──> Load image │
│ │ └── Signature invalid? ── NO ──> REJECT │
│ └── StartImage() │
│ │
├─────────────────────────────────────────────────────────────────────────┤
│ Custom PE Loader - What shdloader.efi does │
│ │
│ shdloader.efi ──> OpenFile("shdmgr.ef_") │
│ │ │
│ ├── ReadFile() into buffer │
│ ├── Parse PE/COFF headers │
│ ├── Allocate memory │
│ ├── Copy sections │
│ ├── Apply .reloc relocations │
│ ├── *** NO SIGNATURE CHECK *** │
│ └── Jump to EntryPoint │
│ │
│ Result: ANY valid PE/COFF EFI application runs, signed or not │
└─────────────────────────────────────────────────────────────────────────┘
Le chargeur PE personnalisé est une implémentation simplifiée et attend une disposition PE/COFF spécifique. Les binaires qui ne s'y conforment pas sont rejetés avec des erreurs :``` Reloc table overflows binary Relocation failed Invalid entry point
Un binaire auquel il manque l'un de ces éléments sera rejeté par le chargeur personnalisé.
| Champ | Valeur requise | Raison |
|-------|---------------|--------|
| *Machine* | `0x8664` (x64) | Le chargeur ne prend en charge que les images x86-64 |
| *Subsystem* | `10` (EFI Application) | Doit être une EFI Application |
| *section .reloc* | `.reloc` doit exister avec des entrées de relocalisation de base valides | Le chargeur effectue sa propre relocalisation d'image. Sans .reloc, il échoue avec « Reloc table overflows binary » |
| *Relocation Directory* | `VirtualAddress` != 0, Size != 0 (DATA_DIRECTORY[5]) | L'entrée de répertoire doit pointer vers des données de relocalisation valides |
Un script de vérification (Scripts/VerifyPE.py) est fourni pour vérifier la compatibilité avant le déploiement.
---
<div id='BYOVD'/>
### ***Parallèle avec le BYOVD noyau***
Le parallèle structurel entre le BYOVUA UEFI et le BYOVD noyau est exact, bien que CVE-2022-34302 représente la forme la plus directe - le composant signé **lui-même** charge du code non signé, plutôt que de fournir une primitive pour désactiver la vérification :```
┌──────────────────────────────────────────────────────────────┐
│ UEFI BYOVUA - CVE-2022-34302 (Custom PE Loader) │
│ │
│ Signed Bootloader ──> Custom PE Loader ──> Load unsigned │
│ (trusted by (no sig check) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ UEFI BYOVUA - CVE-2022-34301/34303 (Shell + gSecurity2) │
│ │
│ Signed Shell ─ mm ─> gSecurity2 = NULL ─> Load unsigned │
│ (trusted by (Security2 Protocol) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ Kernel BYOVD (DSE Bypass) │
│ │
│ Signed Driver ─ IOCTL ─> g_CiOptions = 0 ─> Load unsigned │
│ (trusted by (CI.dll) kernel drivers │
│ DSE / CI) │
└──────────────────────────────────────────────────────────────┘
CVE-2022-34302 est la variante la plus dangereuse car le contournement est inhérent à la conception du bootloader - il n'y a aucune étape intermédiaire où l'attaquant doit corrompre un mécanisme de sécurité. Le composant signé charge directement du code non signé dans le cadre de son fonctionnement normal.
Le fichier signé shdloader.efi est placé sur la partition système EFI (ESP) en tant que chargeur de démarrage par défaut. Comme il est signé par le certificat UEFI Driver Publisher de Microsoft, Secure Boot le valide et le charge sans problème.```
EFI System Partition (ESP)
└── EFI/
└── Boot/
└── bootx64.efi (shdloader.efi) ← Signed by Microsoft Windows UEFI Driver Publisher
└── shdmgr.ef_ (PAYLOAD) ← Unsigned, loaded by shdloader's custom PE loader
Au démarrage du système, le firmware :
1. Lit `bootx64.efi` depuis l'ESP
2. Appelle `LoadImage()` qui vérifie la signature Authenticode par rapport à la base de données Secure Boot
3. La signature correspond au certificat Microsoft UEFI CA 2011 dans la `db` → l'image est acceptée
4. Appelle `StartImage()` pour transférer l'exécution à `shdloader.efi`
---
<div id='Phase2'/>
### ***Phase 2 - Activation du chargeur PE personnalisé***
Une fois que `shdloader.efi` a le contrôle, il affiche un message de diagnostic et active immédiatement son chargeur PE/COFF personnalisé :```
Booting in insecure mode
Le chargeur d'amorçage effectue ensuite les opérations suivantes :
\EFI\Boot\shdmgr.ef_ à l'aide du protocole de système de fichiers.text, .data, .reloc, etc.) vers la mémoire allouéeLoadAddress - ImageBase) et applique toutes les relocalisations de base depuis la section .relocLoadAddress + AddressOfEntryPoint comme cible d'exécutionAucune vérification de signature n'a lieu à aucun moment de ce processus. Le chargeur n'appelle pas LoadImage(), n'invoque pas gSecurity2->FileAuthenticationState() et ne vérifie pas les bases de données db ou dbx. Le fichier est chargé uniquement sur la base de sa validité structurelle.
Si le fichier n'est pas trouvé, le chargeur d'amorçage signale :``` Failed to open \EFI\Boot\shdmgr.ef_ - 800000000000000E Failed to load image
---
<div id='Phase3'/>
### ***Phase 3 - Exécution de code non signé***
Le chargeur personnalisé saute vers le point d'entrée de `shdmgr.ef_`. L'application UEFI non signée s'exécute désormais avec :
- Un accès matériel complet (mémoire directe, ports d'E/S, PCI, MMIO)
- Aucun système d'exploitation encore chargé
- Aucune protection ASLR, DEP ou noyau
- Aucune surveillance EDR ou de sécurité des points de terminaison
- Secure Boot signalé comme **activé** à toute requête ultérieure du système d'exploitation
L'attaque est totalement silencieuse. Contrairement à CVE-2022-34301 et CVE-2022-34303, qui affichent une invite UEFI Shell visible, cet exploit ne produit aucune sortie visuelle au-delà du message « Booting in insecure mode » (qui, sur un système légitime, apparaît brièvement et est rapidement remplacé par l'écran de démarrage du système d'exploitation). Sur les systèmes sans écran (serveurs, IoT, équipements industriels), il n'y a aucune indication whatsoever.
---
<div id='Phase4'/>
### ***Phase 4 - Persistance***
L'attaque est persistante par défaut. Tant que `shdloader.efi` reste à `\EFI\Boot\bootx64.efi` et que la charge utile de l'attaquant reste à `\EFI\Boot\shdmgr.ef_` sur l'ESP, la charge utile non signée s'exécute à chaque démarrage.
Aucun script `startup.nsh` n'est nécessaire. Aucune adresse gSecurity2 n'a besoin d'être recalculée lors des mises à jour du firmware. Le chargeur PE personnalisé charge tout `shdmgr.ef_` qu'il trouve, inconditionnellement.
Le système continue de signaler Secure Boot comme « activé » - seule la chaîne de confiance a été rompue au niveau du bootloader. Cela rend l'attaque invisible aux requêtes de statut Secure Boot au niveau du système d'exploitation et à tout logiciel de sécurité qui s'appuie sur l'attestation Secure Boot.
> **Important :** La persistance n'est rompue que si la DBX est mise à jour avec l'entrée de révocation pour `shdloader.efi` (KB5012170), ce qui amène le firmware à rejeter `shdloader.efi` lui-même avant que le chargeur personnalisé ne s'active.
---
---
---
<div id='Exploit'/>
## ***Exploit***
Le répertoire `Exploit/` contient tout ce qui est nécessaire pour construire un `shdmgr.ef_` compatible :```
Exploit/
|
├── README.md ← Build guide and PE/COFF requirements
|
├── PayloadShdmgr/
| |
│ ├── ForceReloc.nasm ← Force .reloc section generation
│ ├── shdmgr.ef_.c ← UEFI application source (EDK2)
│ ├── shdmgr.ef_.inf ← EDK2 module definition
│ ├── shdmgr.ef_.dsc ← EDK2 platform build configuration
│ └── shdmgr.ef_.dec ← EDK2 package declaration
|
└── Scripts/
└── VerifyPE.py ← PE/COFF compatibility verifier
Le bootloader signé a été ajouté à la liste de révocation DBX de Microsoft via KB5012170 (août 2022). Sur les systèmes mis à jour, le bootloader sera rejeté par Secure Boot avant même que le chargeur PE personnalisé ne s'active.
Pour l'environnement de laboratoire, vous avez besoin d'un système où :
Le QEMU UEFI Research Environment fournit une configuration automatisée pour cela.
CVE-2022-34302 est plus simple à exploiter que CVE-2022-34301 et CVE-2022-34303 :
| Aspect | CVE-2022-34302 (Chargeur personnalisé) | CVE-2022-34301/34303 (Shell) |
|---|
| Technique | Remplacer shdmgr.ef_ par la charge utile | Corrompre gSecurity2 via la commande mm |
| Interaction | Aucune (entièrement automatique) | Commandes shell manuelles ou startup.nsh |
| Visibilité | Silencieux (« Booting in insecure mode ») | Invite UEFI Shell visible |
| Dépendance au firmware | Aucune (la charge utile est autonome) | L'adresse de gSecurity2 change selon la version du firmware |
| Complexité | Faible (remplacement de fichier) | Moyenne (analyse et modification de la mémoire) |
| Furtivité | Élevée (aucune sortie visuelle en mode headless) | Faible (shell visible à l'écran) |