Contexte de l'exploitation
Firecracker isole le code non fiable dans une micro‑VM. L’article décrit comment, à partir d’un accès limité à la mémoire physique de l’hôte, les chercheurs ont détourné le fil d’exécution d’un vCPU pour exécuter du code arbitraire en tant que root sur le système hôte. L’attaque repose sur la primitive « host memory » présentée dans la partie 1 (PwnEscape) et sur la vulnérabilité identifiée comme CVE‑2026‑99999.
Chaîne de résolution d’adresses
Le premier défi consiste à relier une page contrôlée dans la VM à son adresse physique d’hôte (HPA). Les attaquants ont injecté un nonce dans une page invitée, puis ont parcouru les racines potentielles de l’Extended Page Table (EPT) jusqu’à retrouver la page dont le contenu correspondait au nonce :
for root in candidate_ept_roots:
page_hpa = walk_ept(root, guest_gpa)
if page_hpa is invalid:
continue
contents = read_host(page_hpa, len(nonce))
if contents == nonce:
candidates.append((root, page_hpa))
Cette recherche a permis d’isoler un unique EPT root et d’obtenir l’adresse physique guest_page_hpa de la page contrôlée.
Ensuite, ils ont inversé la table de pages de l’hôte pour retrouver le répertoire de pages (PGD) du processus Firecracker qui mappe cette page :
for mapping in reverse_map_host_page_tables(guest_page_hpa):
pgd = mapping.root
guest_page_va = mapping.virtual_address
resolved_hpa = walk_host_page_tables(pgd, guest_page_va)
if resolved_hpa != guest_page_hpa:
continue
if read_host(resolved_hpa, len(nonce)) != nonce:
continue
process_candidates.append((pgd, guest_page_va))
Le PGD ainsi récupéré a servi à identifier l’image ELF de Firecracker et à calculer le load bias (firecracker_base) nécessaire pour convertir les adresses virtuelles du binaire en adresses réelles du processus.
Manipulation du cadre de registre pt_regs
Chaque vCPU est géré par un fil d’exécution qui invoque ioctl(vcpu_fd, KVM_RUN, 0). Pendant l’appel, le noyau sauvegarde les registres utilisateurs du fil dans une structure pt_regs. Le pointeur d’instruction (RIP) indique où le fil reprendra après le retour de KVM_RUN. En modifiant ce cadre, l’attaquant peut forcer le fil à exécuter une fonction choisie dans le processus Firecracker.
Pour localiser le cadre actif, les chercheurs ont cherché dans la mémoire hôte une structure pt_regs dont l’adresse de retour correspondait à l’adresse de continuation de KVM_RUN dans le binaire chargé. Cette adresse est dérivée du load bias et d’un offset connu du point d’appel. Une fois le cadre trouvé, ils ont remplacé le registre rip par l’adresse d’une séquence xor eax, eax; ret ou par l’appel à write(2) qui génère une preuve d’exécution.
Analyse des contraintes et des limites
L’exploitation dépend de plusieurs conditions :
Accès à la primitive de mémoire hôte : sans la capacité de lire/écrire des pages physiques, la chaîne d’adresses ne peut pas être construite.
Connaissance du nonce : le modèle de page doit contenir un motif identifiable pour établir la correspondance entre les espaces d’adressage.
Stabilité du fil vCPU : le cadre pt_regs doit appartenir à un fil actif au moment de l’injection, sinon la modification n’a aucun effet.
ASLR : le calcul du load bias repose sur la découverte de l’image ELF et d’un octet de signature dans le wrapper write(2). Si le binaire est fortement randomisé ou si les signatures sont absentes, la localisation devient impraticable.
Enfin, l’attaque ne détruit pas la micro‑VM : le processus Firecracker continue de fonctionner, et la connexion SSH reste active, ce qui rend la compromission difficile à détecter immédiatement.