
Exploit do kernel Android para CVE-2025-38352, anteriormente explorado em ataques reais. Visa kernels Linux x86_64 vulneráveis v5.10.x.
Chronomaly é um exploit de kernel para o kernel Android / Linux usando CVE-2025-38352. O exploit foi escrito especificamente para o kernel Linux v5.10.157, mas deve funcionar contra todos os kernels v5.10.x vulneráveis, pois não requer nenhum offset de texto específico do kernel para funcionar.
Abordei a vulnerabilidade em detalhes em uma série de posts de blog em três partes, do PoC até o exploit:

Este exploit só foi testado contra um kernel Linux x86_64 v5.10.157 rodando no QEMU. Pedi a um amigo que me enviasse a configuração de kernel do Pixel 6a para basear minha configuração de kernel, e estas são as opções de configuração importantes para este exploit (comecei a partir da configuração do kernelCTF como base):
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=nCONFIG_PREEMPT=y (Preempção total, sem RT)CONFIG_SLAB_MERGE_DEFAULT=nDEBUG_LIST=nBUG_ON_DATA_CORRUPTION=nLIST_HARDENED=nPara desabilitar o CONFIG_POSIX_CPU_TIMERS_TASK_WORK, você pode seguir os passos descritos no meu primeiro post do blog aqui.
Consulte o arquivo qemu.sh para ver meu script de execução do QEMU. Usei 4 núcleos e 3 GB de RAM para os testes.
Como o exploit depende de temporizadores de CPU, há dois parâmetros que você pode precisar alterar para adaptá-lo ao seu ambiente.
CPU_USAGE_THRESHOLDEste parâmetro é usado ao consumir tempo de CPU para disparar os temporizadores dentro de race_func(). Ele deve ser definido de modo que:
CPU_USAGE_THRESHOLD está muito alto, pois os temporizadores estão disparando antes que a thread de race_func() consiga sair).Para determinar se os temporizadores estão disparando ou não, insira uma instrução printf() no código de polling do SIGUSR1 em free_func(). Se você vir a mensagem impressa, isso significa que os temporizadores dispararam.
Se configurado corretamente, você começará a ver as mensagens "Parent raced too late / too early" no terminal.
PARENT_SETTIME_DELAY_USPARENT_SETTIME_DELAY_US. Este parâmetro é usado pelo processo pai para atingir a 2ª janela de corrida dentro de send_sigqueue() ao mesmo tempo que o processo filho. Execute o exploit, observe e modifique-o da seguinte forma:
Idealmente, você quer ver tanto "raced too late" quanto "raced too early" sendo impressos, e o exploit funcionará em menos de 1 minuto. Se você vir apenas um ocorrendo mais do que o outro, ajuste de acordo.
Na minha implementação de cross-cache, presumi que o kernel não está muito ocupado e que não houve muitas alocações de struct sigqueue. Adicionei um comentário em sigqueue_crosscache_preallocs() que explica o que você precisaria fazer para melhorar isso.
Se o kernel estiver realmente ocupado, ou se já houver algumas páginas de slab de struct sigqueue na lista parcial por CPU / por nó, a implementação atual de cross-cache em exploit.c falhará, e o uaf_sigqueue / realloc_sigqueue não será realocado como uma página de dados de pipe buffer.
Propositalmente, escolhi não fazer o cross-cache funcionar em um kernel ocupado, para que o exploit não seja mal utilizado :)
Se você tiver alguma dúvida, entre em contato comigo via X / Twitter!