
Эксплойт для ядра Android для CVE-2025-38352, ранее использовавшийся в дикой природе. Нацелен на уязвимые ядра Linux x86_64 версии v5.10.x.
Chronomaly — это эксплойт ядра для Android/Linux, использующий CVE-2025-38352. Эксплойт был написан специально для ядра Linux v5.10.157, но должен работать против всех уязвимых ядер v5.10.x, так как для его работы не требуется каких-либо конкретных смещений текста ядра.
Я подробно описал уязвимость в серии из трёх постов в блоге, от PoC до эксплойта:

Этот эксплойт тестировался только на ядре Linux x86_64 v5.10.157, запущенном в QEMU. Я попросил друга прислать мне конфиг ядра Pixel 6a, чтобы использовать его как основу для своего конфига, и вот какие параметры конфигурации важны для этого эксплойта (за основу я взял конфиг kernelCTF):
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=nCONFIG_PREEMPT=y (Полное вытеснение, без RT)CONFIG_SLAB_MERGE_DEFAULT=nDEBUG_LIST=nBUG_ON_DATA_CORRUPTION=nLIST_HARDENED=nЧтобы отключить CONFIG_POSIX_CPU_TIMERS_TASK_WORK, вы можете следовать шагам, описанным в моём первом посте в блоге здесь.
Обратитесь к файлу qemu.sh за моим скриптом запуска QEMU. Для тестирования я использовал 4 ядра и 3 ГБ ОЗУ.
Поскольку эксплойт зависит от таймеров ЦП, возможно, потребуется изменить два параметра для адаптации к вашему окружению.
CPU_USAGE_THRESHOLDЭтот параметр используется при потреблении времени ЦП для срабатывания таймеров внутри race_func(). Он должен быть установлен так, чтобы:
CPU_USAGE_THRESHOLD слишком высок — таймеры срабатывают до того, как поток race_func() успеет завершиться).Чтобы определить, срабатывают ли таймеры, вставьте оператор printf() в код опроса SIGUSR1 в функции free_func(). Если вы увидите сообщение на экране, значит, таймеры сработали.
При правильной настройке вы начнёте видеть сообщения «Parent raced too late / too early» в терминале.
PARENT_SETTIME_DELAY_USPARENT_SETTIME_DELAY_US. Этот параметр используется родительским процессом для попадания во второе окно гонки внутри send_sigqueue() одновременно с дочерним процессом. Запустите эксплойт, наблюдайте и изменяйте параметр следующим образом:
В идеале вы должны видеть на экране как «raced too late», так и «raced too early» — тогда эксплойт сработает в течение 1 минуты. Если вы видите, что одно сообщение появляется чаще другого, отрегулируйте параметр соответствующим образом.
В своей реализации кросс-кэша я исходил из предположения, что ядро не слишком загружено и что аллокаций struct sigqueue было немного. Я добавил комментарий в sigqueue_crosscache_preallocs(), где объясняется, что нужно сделать для улучшения.
Если ядро сильно загружено или на списке частичных страниц (per-cpu / per-node) уже есть несколько slab-страниц struct sigqueue, то текущая реализация кросс-кэша в exploit.c не сработает, и uaf_sigqueue / realloc_sigqueue не будут перераспределены как страница данных буфера канала.
Я намеренно не стал делать кросс-кэш рабочим в загруженном ядре, чтобы эксплойтом не злоупотребляли :)
Если у вас есть вопросы, пожалуйста, свяжитесь со мной через X / Twitter!