NetCatTest

Zero-Day & Exploits

Kernel do macOS: CVE-2025-24118, credenciais e condição de corrida

Entenda TRAVERTINE no XNU: publicação de credenciais, atomicidade, SMR e um laboratório local de concorrência sem explorar o macOS.

Por Daniel Felipe 7 min leitura

Uma condição de corrida no kernel pode colocar o sistema em um estado que nenhuma linha de código pretendia produzir. A CVE-2025-24118, estudada como TRAVERTINE, é um caso instrutivo: uma aplicação local podia provocar corrupção de memória ligada à atualização de credenciais. A falha foi corrigida em janeiro de 2025. Este artigo examina o mecanismo histórico e propõe um laboratório de concorrência sem executar um exploit no macOS.

O que está confirmado sobre a CVE-2025-24118

A Apple descreve uma condição de corrida no kernel, com possibilidade de corrupção de memória por um aplicativo. As notas de segurança do macOS Sequoia 15.3 e do Sonoma 14.7.3, publicadas em 27 de janeiro de 2025, registram a correção. Essas são versões históricas de correção, não a recomendação de versão mais recente para outubro de 2026.

A pesquisa de Joseph Ravichandran localiza o problema na publicação de um ponteiro de credenciais de processo. O contexto é local: já existe código executando no dispositivo. Não se trata de um serviço de rede que recebe um pacote e concede acesso remoto automaticamente. A prova pública e a possibilidade descrita pelo fornecedor também não equivalem a uma demonstração universal de obtenção de root em todas as arquiteturas.

Elemento Leitura técnica
Componente Kernel XNU e atualização de credenciais
Pré-condição Aplicação local em execução
Problema Leitura concorrente durante uma publicação inadequada
Efeito documentado Corrupção de memória
Evidência deste artigo Modelo de estados intermediários em bytes

Credenciais, leitores e publicação de estado

Uma credencial responde a perguntas como quais identidades e permissões um processo possui. Diversas operações precisam consultá-la enquanto outras tarefas do sistema atualizam o estado. Uma implementação eficiente evita bloquear todos os leitores por longos períodos, mas precisa assegurar duas propriedades separadas: o objeto consultado continua vivo e sua referência é publicada de modo coerente.

Imagine que um leitor obtenha metade de uma referência antiga e metade de uma nova. O valor resultante não identifica necessariamente nenhum objeto válido. Esse problema é diferente de usar uma referência correta depois que o objeto foi liberado. Ambos podem terminar em corrupção, mas exigem raciocínios distintos para entender e corrigir a causa.

No estudo de TRAVERTINE, aparecem estruturas de processo protegidas e o campo proc_ro.p_ucred. O caminho de escrita analisado envolve uma cópia que, no cenário x86_64 apresentado pelo pesquisador, não assegura a atomicidade esperada para publicar aquele ponteiro. O ponto relevante é o contrato da escrita frente aos leitores, não simplesmente a existência de uma função chamada memcpy.

SMR não substitui atomicidade

Safe Memory Reclamation trata de quando um objeto pode ser reciclado sem prejudicar leitores ainda ativos. Uma estratégia desse tipo pode manter objetos antigos vivos e continuar falhando se o leitor observar uma referência parcialmente modificada. Tempo de vida e publicação são dimensões diferentes da segurança de concorrência.

A documentação de alocações somente para leitura do XNU ajuda a situar a intenção dessas estruturas. Para comparar conceitos, o material de RCU do kernel Linux discute acesso concorrente e períodos de graça. A comparação é conceitual: não afirma que os dois kernels implementam exatamente o mesmo protocolo.

Uma revisão de código precisa mapear todos os escritores, a largura da referência, alinhamento, ordenação de memória e protocolo dos leitores. Uma operação aparentemente indivisível em um teste pode ser dividida pelo código gerado ou por uma implementação diferente. Da mesma forma, uma garantia válida para um contador não pode ser transferida automaticamente a uma estrutura inteira.

Laboratório: enxergar um valor que nunca existiu

O programa seguinte usa dois valores inventados de oito bytes. Não são endereços de memória, não interagem com o XNU e não reproduzem a CVE. Ele enumera estados que uma cópia por partes poderia expor a um leitor. A comparação com duas publicações completas torna visível o requisito de consistência.

import json

antigo = bytes.fromhex('1122334455667788')
novo = bytes.fromhex('99aabbccddeeff00')
estados = [novo[:corte] + antigo[corte:] for corte in range(9)]
mistos = [estado for estado in estados if estado not in (antigo, novo)]
assert len(mistos) == 7
assert estados[0] == antigo and estados[-1] == novo
publicacao_atomica = [antigo, novo]
assert all(estado in (antigo, novo) for estado in publicacao_atomica)
print(json.dumps({'modelo': 'bytes locais, sem ponteiros reais',
    'estados_intermediarios': len(mistos),
    'valores': [estado.hex() for estado in mistos],
    'publicacao_atomica_mista': False},
    ensure_ascii=False))

corte representa quantos bytes novos já foram publicados. Nos extremos, existe apenas o valor antigo ou apenas o novo. Nos sete cortes internos, o resultado mistura ambos. Os asserts confirmam esses estados e também confirmam que o conjunto idealizado de publicações atômicas só contém os dois valores completos.

O resultado esperado é estados_intermediarios: 7 e publicacao_atomica_mista: false. Essa enumeração demonstra o erro de contrato possível, mas não prova que qualquer uma das sete combinações seja um ponteiro aproveitável. Exploração real depende de layout, temporização, validações e mecanismos de mitigação adicionais.

Como conduzir uma investigação autorizada

Comece pelo inventário: modelo do Mac, arquitetura, build do macOS e política de atualização. Registre a origem de cada informação. O nome comercial do sistema, sozinho, não resolve diferenças entre builds. Preserve relatórios de falha e metadados de execução de forma restrita, porque um panic pode conter caminhos, nomes e trechos de memória.

Uma investigação em laboratório deve separar três perguntas: a versão contém o caminho vulnerável; é possível alcançar a condição de corrida; e o efeito observado ultrapassa uma falha controlada. Um crash responde apenas à segunda pergunta quando o stack e a versão sustentam a relação. Não responde por si só à terceira.

Para estudar a correção, prefira comparação de fonte, análise do caminho de publicação e instrumentação em máquinas descartáveis. Testar em uma estação de trabalho com documentos e contas reais cria efeitos desnecessários. Uma reprodução que depende de centenas de tentativas também precisa registrar falhas sem resultado, não apenas a tentativa selecionada.

Critérios de remediação e reteste

Verificação Evidência a guardar Limite da conclusão
Atualização aplicada Build e boletim correspondente Não prova ausência de outras falhas
Caminho corrigido Diferença de implementação e contrato Não representa todo o kernel
Estresse concorrente Contagem, duração e relatórios Ausência de crash não prova impossibilidade
Compatibilidade Aplicações e periféricos testados Válida para a amostra utilizada

O reteste precisa manter as mesmas pré-condições documentadas e explicitar mudanças. Alterar arquitetura, versão e carga ao mesmo tempo impede atribuir a diferença a uma única correção. Também vale testar o comportamento normal de troca de identidade e criação de processos para evitar regressões funcionais no laboratório.

Perguntas que evitam conclusões exageradas

Uma aplicação local já significa comprometimento total? Não. Sistemas modernos mantêm fronteiras entre processos, serviços e kernel justamente para limitar o alcance de código local.

Pointer authentication elimina esse tipo de problema? Não é uma conclusão sustentada para todas as variantes. Autenticação de ponteiros, atomicidade e gerenciamento de vida útil são controles diferentes, com cobertura dependente da implementação.

Uma pontuação de severidade basta para descrever o vetor? Não. O registro, o aviso do fornecedor e a pesquisa precisam ser lidos juntos. Uma descrição histórica de execução remota não deve substituir a pré-condição local demonstrada no estudo.

O aprendizado técnico de TRAVERTINE é verificar a publicação do estado inteiro que os leitores realmente consomem. Um objeto protegido contra liberação precoce ainda pode ser inseguro se a referência usada para alcançá-lo não respeitar esse contrato.

Escrito por

Daniel Felipe é criador do NetCatTest e produz conteúdos sobre cibersegurança, privacidade digital, OSINT, laboratórios autorizados e ferramentas para estudo técnico responsável.

Compartilhar

Enviar este artigo