
Подробный разбор уязвимости CVE‑2025‑29824 в ОС Windows
clfs.sys
, которая позволяет атакующим повышать привилегии в системе8 апреля 2025 года Microsoft исправила 121 уязвимость в своих продуктах, в том числе CVE‑2025‑29824 — единственную, использующуюся злоумышленниками «в дикой природе». Она позволяла повышать привилегии в ОС Windows из-за ошибки в драйвере логирования clfs.sys
. Аналитики Microsoft Threat Intelligence обнаружили эту уязвимость в ходе атак группировки Storm‑2460 на компании, находящиеся в Саудовской Аравии, Испании, Венесуэле и США. С помощью CVE‑2025‑29824 атакующие повышали привилегии до NT AUTHORITY\SYSTEM
для последующего бокового перемещения и шифрования файлов жертвы.
Эксплоит для CVE‑2025‑29824 запускался в адресном пространстве процесса dllhost.exe
и использовал классические техники постэксплуатации: для получения адресов из пространства ядра применялась функция NtQuerySystemInformation
, а для повышения привилегий — RtlSetAllBits
изнутри ядра, чтобы включить все привилегии процесса при повреждении структуры EPROCESS
.
Так как для эксплуатации требовалось взаимодействие с драйвером clfs.sys
, атакующие создавали файл C:\ProgramData\SkyPdf\PDUDrv.blf
.
После повышения привилегий полезная нагрузка сначала внедрялась в адресное пространство процесса winlogon.exe
, оттуда — в procdump.exe
, а затем — в адресное пространство процесса dllhost.exe
, запущенного с помощью следующей команды:
C:\Windows\system32\dllhost.exe -accepteula -r -ma lsass.exe c:\programdata\[комбинация из случайных символов]
Эти действия выполняются для того, чтобы затем появилась возможность получить данные LSASS из памяти, что ведет к краже учетных данных пользователей Windows. С повышенными привилегиями выполнялось шифрование файлов в скомпрометированной системе с использованием шифровальщика RansomEXX, также запущенного через dllhost.exe
:
C:\Windows\system32\dllhost.exe --do [путь к вредоносному файлу RansomEXX]
По информации на официальном сайте Microsoft, уязвимость связана с использованием данных на куче после освобождения выделенной памяти, что при дальнейшей эксплуатации могло привести к повышению привилегий в ОС Windows.

clfs.sys
clfs.sys
— драйвер, работающий в пространстве ядра ОС Windows и предназначенный для логирования информации в файлы специального формата BLF (Base Log File). Драйвер появился в системе в 2005 году вместе с версией Windows Server 2003 R2. То, что clfs.sys
находится в пространстве ядра, объясняется тем, что он требуется для работы некоторых других драйверов. Например, менеджер транзакций (tm.sys
) использует его для журналирования транзакций с возможностью их отката.
На рисунке ниже можно увидеть используемые драйвером tm.sys
функции, импортируемые из clfs.sys
.

Также у clfs.sys
есть собственный API (clfsw32.dll
) для доступа к драйверу из пользовательского пространства. Например, чтобы создать основной файл лога, можно использовать функцию CreateLogFile, а чтобы добавить контейнер, где уже будут данные, — AddLogContainer. Кроме того, к драйверу можно обращаться через IOCTL, реализующийся в Windows через функцию NtDeviceIoControlFile, а создать дескриптор файла можно через NtCreateFile.
В последнее время clfs.sys
наряду с afd.sys
и win32k.sys
стал популярной целью у злоумышленников: уязвимости в нем часто появляются «в дикой природе» в ходе различных кампаний.
Как мы уже писали в одной из предыдущих статей, для получения разных версий можно использовать Winbindex. Загружаем версии с апрельским (от 8 апреля) и мартовским (от 11 марта) Security Update.


При сравнении двух файлов при помощи BinDiff можно обнаружить, что было изменено достаточно небольшое количество функций, а изменения преимущественно получили функции CClfsRequest::Close
и CClfsLogCCb::Cleanup
, вызывающиеся при закрытии дескриптора файла логирования:

В обновлениях, касающихся безопасности, Microsoft добавляет функцию следующего вида: Feature_[число]__private_IsEnabledDeviceUsage
. По нашему предположению, это сделано, чтобы в случае каких‑либо ошибок при исправлении можно было вернуть устройства в исходное состояние.
Так, декомпилированный код функции CClfsRequest::Close
выглядит следующим образом:

В то время как измененный код функции CClfsLogCcb::Cleanup
, вызывающийся изнутри CClfsRequest::Cleanup
, выглядит так:

При закрытии дескриптора файла ядро отправляет два I/O‑запроса к драйверу: первый — на очистку (IRP_MJ_CLEANUP
), второй — на закрытие (IRP_MJ_CLOSE
). Они обрабатываются следующим образом:

Порядок запросов можно также увидеть на диаграмме:

Здесь стоит отметить, что из пользовательского пространства нельзя отдельно вызвать IRP_MJ_CLEANUP
или IRP_MJ_CLOSE
, а также в момент IRP_MJ_CLEANUP
операции с дескриптором все еще возможны из пользовательского пространства.
При анализе измененного кода можно понять, что хотел сказать автор исправление связано с переносом вызова функции CClfsLogCcb::Release
из CClfsLogCcb::Cleanup
в CClfsRequest::Close
.
CClfsLogCcb::Release
— функция, которая уменьшает количество референсов для объекта CClfsLogCcb
на 1. Если референсов больше нет, вызывает деструктор, а затем очищает память, выделенную под указанный объект:

Однако из-за того, что память, выделенная под объект CClfsLogCcb
, высвобождалась в момент I/O‑запроса IRP_MJ_CLEANUP
, возможно реализовать такой IOCTL‑вызов, который также использует уже освобожденный объект CClfsLogCcb
. Это может привести к повреждению памяти внутри ядра.
Одной из функций, использующих объект CClfsLogCcb
, является CClfsRequest::StartArchival
:

Для успешного триггера уязвимости необходимо, чтобы цепочка выполнения следовала следующей диаграмме:

Стоит отметить, что освобождение происходит с использованием LookasideList
:

То есть, если количество освобожденных объектов не превышает глубину LookasideList
, объект на самом деле не будет освобожден, а только помечен внутри данного листа. Отметим, что глубина листа равна 24. Это значит, что для эксплуатации необходимо изначально создать как минимум 25 дескрипторов одного и того же файла логирования, затем закрыть 24 из них, чтобы заполнить лист, после чего эксплуатировать уязвимость в оставшихся.
При успешной реализации описанной стратегии в адресном пространстве ядра будет находиться освобожденная память, внутри которой может выделиться уже другой объект того же размера. Драйвер clfs.sys
будет считать, что этот объект — CClfsLogCcb
. Дальнейшая эксплуатация заключается в манипуляции этим «зависшим» объектом с помощью clfs.sys
.
clfs.sys
стал популярной целью для финансово мотивированных группировок в последние годы. Злоумышленники все чаще используют эксплоиты нулевого дня в этом и других драйверах для повышения привилегий и маскировки действий, связанных с постэксплуатацией. Во второй части совместного исследования эксперты «Лаборатории Касперского» описали подробности реализации такого ВПО. Защита от подобных атак наиболее сложна, ведь уязвимы самые последние версии программного обеспечения.
Чтобы противостоять угрозам, мы рекомендуем устанавливать средства защиты информации, которые предотвращают и логируют действия атакующих. Например, EDR-решения: они позволяют обнаружить злоумышленников на ранних этапах атаки и при проведении постэксплуатации. Это значительно повышает шансы на предотвращение финансовых потерь. Также, чтобы не облегчать жизнь злоумышленникам, важно выстроить процессы оперативного обновления ПО и регулярно проводить тестирование на проникновение.