Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Bootjack — Outillage d'exploitation pour le débordement d'erreur ICMP PXE UEFI d'EDK II (CVE-2026-97631) : forge des paquets ICMP usurpés, implante un faux EFI_EVENT et vide la mémoire DXE via UART. | Kitploit
Outils/GitHubGitHub/rayanziani/bootjack
Sécurité des Systèmes EmbarquésSniffing et Analyse de PaquetsAnalyse des VulnérabilitésExploitationShellcodeSécurité RéseauSécurité Matériel et IoTDéveloppement de Charges UtilesAnalyse de MicrologicielExploitation de Binaires
1il y a 5 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHub
rayanziani/bootjack

Bootjack

Outillage d'exploitation pour le débordement d'erreur ICMP PXE UEFI d'EDK II (CVE-2026-97631) : forge des paquets ICMP usurpés, implante un faux EFI_EVENT et vide la mémoire DXE via UART.

Voir le dépôt

CVE-2026-97631 : lecteur de mémoire DXE de pré-démarrage

Outillage pour le débordement d'erreur ICMP du pilote EDK II PXE Base Code (NetworkPkg/UefiPxeBcDxe, GHSA-99cj-7hg9-mp4m, CVSS 4.0 9.5).

Lors d'un démarrage PXE, le pilote copie un message d'erreur ICMP dans un tampon fixe de 504 octets. Un message plus long devient une écriture linéaire au-delà de ce tampon, dans le pool DXE. Comme la destination de l'écriture est l'adresse du tampon lui-même, la charge utile est indépendante de la position : l'octet i du datagramme atterrit à &Mode->IcmpError + i. Le débordement implante un EFI_EVENT contrefait ; le cœur DXE le distribue via le chemin normal CoreSignalEvent ; la charge utile restaure l'événement à partir d'un instantané, parcourt des plages mémoire choisies par l'opérateur et renvoie EFI_SUCCESS afin que le démarrage se poursuive.

Le rayon d'action reste à l'intérieur de la mémoire DXE du firmware lui-même. Aucune écriture en flash, aucun mécanisme de persistance, aucun artefact du système d'exploitation.

Disposition

include/pxe_layout.h   EFI_PXE_BASE_CODE_ICMP_ERROR, IEVENT offsets, wire structs
include/craft.h        one packet = one primitive
include/graft.h        counterfeit event + payload parameter block
include/layout.h       the overflow region (single source of truth)
src/payload.S          ring-0 payload: restore, walk ranges, stream out
src/craft.c            packet construction, IPv4 + IPv6
src/graft.c            IEVENT overlay, parameter block
src/layout.c           overflow assembly, shared by sender and simulator
src/main.c             pxeinj: sniff xid, probe, send
src/net.c              raw L3 transport, DHCP xid sniffer
src/recv.c             pxerecv: serial collector, dump + map
sim/sim.c              host harness that proves the chain
tools/fw_offsets.py    pool offsets from a debug firmware build

Compilation

Charge utile :

as --64 -o build/payload.o src/payload.S
ld -Ttext=0 -e payload_start --oformat elf64-x86-64 -o build/payload.elf build/payload.o
objcopy -O binary --only-section=.text build/payload.elf build/payload.bin

Le résultat fait 378 octets, indépendant de la position, sans relocations.

L'émetteur et le récepteur sont POSIX (AF_PACKET, IP_HDRINCL, termios) et se compilent avec make sous Linux. Le simulateur se compile avec MSVC via Makefile.win :

cl /nologo /W3 /O2 /Iinclude /Fe:build\sim.exe sim\sim.c src\craft.c src\graft.c src\layout.c

La chaîne, telle que prouvée par le simulateur

build/sim.exe mappe une fausse page de pool, écrit le débordement là où le memcpy vulnérable le ferait, vérifie que l'IEVENT résultant dispatcherait la charge utile, appelle la charge utile en tant que code machine réel, puis vérifie :

  • que l'événement est restauré octet pour octet
  • que les octets vidés sont égaux à la plage source
  • que les trames d'ouverture/fermeture sont intactes, afin qu'un vidage tronqué soit distinguable
  • qu'un UART mort ne bloque pas l'appel
  • que les sommes de contrôle du datagramme ICMP se vérifient et que le débordement atterrit à l'offset depuis lequel le pilote copie
  • que le xid BOOTP embarqué survit verbatim

26 vérifications portant sur la disposition, l'ABI, le framing et la construction des paquets. Cela prouve que les parties sont cohérentes entre elles. Cela ne prouve pas l'adresse de pool d'un firmware spécifique, qui est une allocation à l'exécution.

Fonctionnement

Deux modes, utilisés dans l'ordre.

Probe : chemin légal uniquement, aucune écriture hors limites.

pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --sniff --probe --send

Une erreur ICMP bien formée de 504 octets. Même usurpation, même transaction BOOTP intégrée, tout est identique. Si le client continue de démarrer, l'erreur a été acceptée et la boucle de copie vulnérable a été atteinte. Confirmation non destructive, et elle ne nécessite aucune adresse de pool.

Overflow : refuse de se construire tant que trois éléments n'existent pas : la base du pool (tools/fw_offsets.py), les octets d'événement intacts (--shadow), et au moins une plage.

pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --xid 0xdeadbeef \
       --pool-base 0x7f12345000 --payload build/payload.bin \
       --ranges ranges.txt --shadow shadow.bin --uart 0x3f8 --send

pxerecv -d /dev/ttyUSB0 -o dump.bin -m dump.map

ranges.txt contient une plage START-END par ligne, en hexadécimal sans 0x ; voir ranges.example.txt pour la taille et le budget de temps. Le chemin de débordement v6 est désactivé : la sonde fonctionne sur v6, l'écriture non, tant que la borne de copie v6 n'a pas été redérivée à partir du code source corrigé.

Pourquoi c'est silencieux

  • aucune allocation Boot Services, journalisation ou verrou à l'intérieur de la charge utile
  • aucune modification IDT/GDT/CR/MSR, aucun hook d'interruption, aucun registre de débogage
  • l'objet est restauré avant le début du dump, pas après
  • la sortie est un UART interrogé en polling, donc rien n'atterrit dans un tampon géré par le firmware
  • renvoie EFI_SUCCESS sur le chemin de notification normal, donc le démarrage se poursuit
  • le SignalLink de l'événement est cohérent avec lui-même, donc le parcours de liste ne déclenche pas d'assertion

Les traces résiduelles sont inhérentes au bug : l'événement a été signalé à un moment où il ne l'aurait normalement pas été, la page du pool reste sale, et si la plateforme mesure DXE avec un TPM, la valeur PCR est celle qu'elle avait au début du démarrage. Tout ce qui va au-delà n'est pas une propriété de ce bug.

Garde-fous dans le code

  • --send est requis ; par défaut, c'est un dry run
  • le débordement refuse de se construire sans --pool-base, --payload, --shadow et une liste de plages non vide. Chacun de ces éléments a une manière spécifique de corrompre le firmware s'il est deviné, donc aucun n'est optionnel
  • --shadow doit contenir une signature EFI_EVENT à l'offset attendu, ce qui détecte un fichier rempli de zéros et un mauvais --event-off en une seule vérification plutôt qu'au moment du dispatch
  • la sonde est un mode séparé et ne peut pas écrire hors limites
  • le polling UART est borné, donc un 16550 absent ne peut pas bloquer un démarrage ; une fois l'estimation épuisée, l'UART est abandonné et le puits RAM, s'il existe, continue
  • la trame de fermeture rend la troncature visible au lieu de silencieuse

Limites

  • L'adresse pool de Mode->IcmpError est une allocation à l'exécution et diffère selon la build du firmware. Elle ne peut pas être dérivée d'une link map. tools/fw_offsets.py donne les offsets ; la base doit être mesurée sur le firmware cible, par exemple à partir d'une trace DEBUG_POOL, puis mise en cache.
  • sizeof(EFI_PXE_BASE_CODE_MODE) et offsetof(..., IcmpError) changent entre les versions d'edk2. Les valeurs par défaut dans tools/fw_offsets.py sont des points de départ, pas des valeurs à prendre pour acquises.
  • L'expression exacte à partir de laquelle la borne de copie défectueuse est calculée n'est pas indiquée dans l'avis, et le correctif (#13302) la modifie. Lisez les deux fonctions DpcHandle dans l'arborescence cible avant de vous fier à l'offset de débordement.
  • Restaurer l'événement nécessite un instantané pris avant le débordement. Sans lui, la restauration écrit des zéros et laisse un événement corrompu dans la liste de signaux du cœur, dans laquelle le prochain CoreSignalEvent va parcourir. L'outil refuse de se construire sans --shadow pour cette raison.
Télécharger l’outil