
Análise de causa raiz e prova de conceito para CVE-2026-64705, um estouro de heap no kernel do macOS HFS xattr. Inclui imagem HFS+ armamentada, patcher, parser e relatório detalhado para pesquisa educacional e defensiva.
Análise de causa-raiz e prova de conceito para CVE-2026-64705, um estouro de buffer na extensão de kernel HFS corrigido no macOS Sonoma 14.8.7 (HT127117):
HFS — Impacto: um app pode causar término inesperado do sistema ou gravar memória do kernel. Um estouro de buffer foi resolvido com verificação de limites aprimorada.
O PoC é uma imagem de disco HFS+ armamentada. Montá-la e ler um atributo
estendido manipulado leva o kext HFS a um loop bcopy de 64 bytes sem limite
em um buffer de heap do kernel de 512 bytes → estouro de heap do kernel com
conteúdo de disco controlado pelo atacante → pânico em builds vulneráveis.
Nível de travamento/pânico — não RCE.
adds/b.hs, término de contagem zero e rejeição de total==0 / total>expectedhfs_setxattr: %s has a malformed overflow extent, o mesmo para getxattr.| arquivo | o quê |
|---|---|
poc-cve-2026-64705.dmg | Imagem HFS+ armamentada de 32 MB (arquivo de gatilho + registros xattr manipulados) |
weaponize.py | O patcher que construiu a imagem — re-deriva cada deslocamento da própria imagem; funciona em qualquer imagem base compatível |
parse_attr.py | Parser da árvore B de atributos usado para localizar/despejar os registros xattr |
BUILD.md | Receita completa de build a partir de uma imagem base limpa + os deltas hexadecimais exatos |
WRITEUP.md | Análise de causa-raiz: diff do kext (14.8.5 vs 14.8.7), loop vulnerável, mecanismo |
Em um sistema anterior à correção (ou uma VM sacrificial — isso causa pânico no kernel):
hdiutil attach -nobrowse poc-cve-2026-64705.dmg
xattr -l /Volumes/CVE64705/trigger.txt # estouro de heap do kernel -> pânico
Em um sistema corrigido, a mesma imagem monta normalmente e o gatilho é rejeitado pelo novo validador — você pode observar a prova diferencial no log do kernel:
hfs_getxattr: bigattr has a malformed overflow extent
o que também confirma que o registro manipulado leva a execução exatamente para o caminho corrigido (e anteriormente vulnerável).
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
Para um xattr grande armazenado como kHFSPlusAttrForkData, hfs_getxattr_internal
(e o espelhado hfs_setxattr_internal) percorre os 8 descritores de extensão do
registro de estouro. count_extent_blocks() ignora qualquer descritor cujo
blockCount exceda o total esperado e retorna a soma de 32 bits sem verificação
de transporte ou zero. Se cada blockCount exceder o total, a contagem retorna
0, blkcnt nunca avança, e o loop while (blkcnt < totalblocks) continua
copiando 64 bytes controlados pelo atacante por iteração além de um buffer de
heap de totalblocks*8 bytes. A variante de quebra de inteiro (blockCounts
somando além de 2^32) é a mesma verificação ausente; o patch 14.8.7 elimina ambas.
Para fins educacionais e de pesquisa defensiva. O bug está corrigido no macOS atual; teste apenas em máquinas que você possui.