
Analyse des causes profondes et preuve de concept pour CVE-2026-64705, un débordement de tas du noyau macOS HFS xattr. Inclut une image HFS+ armée, un patcher, un analyseur et un rapport détaillé à des fins de recherche pédagogique et défensive.
Analyse de la cause racine et preuve de concept pour CVE-2026-64705, un débordement de tampon dans l'extension noyau HFS corrigé dans macOS Sonoma 14.8.7 (HT127117) :
HFS — Impact : une application peut provoquer une terminaison inattendue du système ou écrire dans la mémoire du noyau. Un débordement de tampon a été corrigé grâce à une meilleure vérification des limites.
Le PoC est une image disque HFS+ armée. Son montage et la lecture d'un attribut étendu
conçu à cet effet poussent le kext HFS dans une boucle bcopy illimitée de 64 octets
dans un tampon de tas du noyau de 512 octets → débordement de tas du noyau avec contenu
sur disque contrôlé par l'attaquant → panique sur les builds vulnérables. Niveau crash/panique —
pas RCE.
adds/b.hs, la terminaison à compteur nul, et le rejet total==0 / total>expectedhfs_setxattr: %s a un extent de débordement malformé, idem pour getxattr.| fichier | description |
|---|---|
poc-cve-2026-64705.dmg | Image HFS+ armée de 32 Mo (fichier déclencheur + enregistrements xattr conçus) |
weaponize.py | Le patcher qui a construit l'image — redérive chaque décalage à partir de l'image elle-même ; fonctionne sur toute image de base compatible |
parse_attr.py | Analyseur de l'arbre B des attributs utilisé pour localiser/dumper les enregistrements xattr |
BUILD.md | Recette de build complète à partir d'une image de base propre + les deltas hexadécimaux exacts |
WRITEUP.md | Analyse de la cause racine : diff du kext (14.8.5 vs 14.8.7), boucle vulnérable, mécanisme |
Sur un système antérieur au correctif (ou une VM sacrifiable — cela fait paniquer le noyau) :
hdiutil attach -nobrowse poc-cve-2026-64705.dmg
xattr -l /Volumes/CVE64705/trigger.txt # débordement de tas du noyau -> panique
Sur un système corrigé, la même image se monte correctement et le déclencheur est rejeté par le nouveau validateur — vous pouvez observer la preuve différentielle dans le journal du noyau :
hfs_getxattr: bigattr a un extent de débordement malformé
ce qui confirme également que l'enregistrement conçu dirige l'exécution exactement dans la boucle corrigée (et auparavant vulnérable).
hdiutil create -fs HFS+ -size 32m -volname CVE64705 base.dmg
hdiutil attach -nobrowse base.dmg
echo trigger > /Volumes/CVE64705/trigger.txt
xattr -w bigattr "$(head -c 8192 /dev/zero | base64)" /Volumes/CVE64705/trigger.txt
hdiutil detach /Volumes/CVE64705
python3 weaponize.py # -> poc-cve-2026-64705.dmg
Pour un xattr volumineux stocké sous forme de kHFSPlusAttrForkData, hfs_getxattr_internal
(et le hfs_setxattr_internal en miroir) parcourt les 8 descripteurs d'extent de
l'enregistrement de débordement. count_extent_blocks() ignore tout descripteur dont
le blockCount dépasse le total attendu et renvoie la somme 32 bits sans vérification
de retenue ni de zéro. Si chaque blockCount dépasse le total, le compte revient à 0,
blkcnt n'avance jamais, et la boucle while (blkcnt < totalblocks) continue de copier
64 octets contrôlés par l'attaquant par itération au-delà d'un tampon de tas de
totalblocks*8 octets. La variante par repli d'entier (blockCounts dont la somme dépasse
2^32) est la même vérification manquante ; le correctif 14.8.7 élimine les deux.
À des fins éducatives et de recherche défensive. Le bug est corrigé dans macOS actuel ; testez uniquement sur des machines qui vous appartiennent.