
Описание и PoC для CVE-2020-0753, CVE-2020-0754 и шести неисправленных уязвимостей типа отказа в обслуживании в Windows.
Служба отчетов об ошибках Windows исправила 2 ошибки повышения привилегий в последний вторник исправлений. Этим двум ошибкам присвоены идентификаторы CVE-2020-0753 и CVE-2020-0754. Обе ошибки используют состояние гонки в файловых операциях службы. Однако эти две ошибки не так просто эксплуатировать из-за небольших окон гонки и неопределенных мест сброса файлов. Здесь мы делимся нашими методами их эксплуатации.
Основная причина двух ошибок гонки указана в наших отчетах; фактическую причину можно выразить как Предсказуемое уязвимо. Когда служба WER обрабатывает временные файлы, она манипулирует расположением файла C:\ProgramData\Microsoft\Windows\WER\Temp, который является каталогом с правами чтения/записи для аутентифицированных пользователей. Это означает, что обычный пользователь со средним уровнем целостности (medium-IL) может перезаписать файл, созданный службой WER, и даже превратить его в файловую ссылку, чтобы повредить/удалить другие файлы, к которым он иначе не мог бы получить доступ.
Чтобы обеспечить безопасность файловых операций, служба WER использует стандартный API GetTempFileNameW и обернула его в wersvc.dll->UtilGetTempFile. Этот API помогает WerSvc генерировать незанятое случайное имя файла в форме "WER****.tmp", случайная часть имени файла генерируется как 4-байтовое шестнадцатеричное число от 0000 до FFFF. Если одно число уже использовано для создания файла, API выберет другое случайное имя файла.
В этой стратегии есть очевидный недостаток: если создать 65535 файлов с именами от WER0000.tmp до WERFFFE.tmp, API выберет случайное число и проверит, существует ли файл, например WERA560.tmp. Он обнаружит, что файл уже существует, и будет продолжать проверку от WERA560.tmp до WERFFFF.tmp. Пока проверка продолжается, появляется окно подготовки, поскольку мы нашли способ заставить WerSvc зависнуть на вызове GetTempFileNameW на 4‑5 секунд, что является довольно большим временным разрывом. Тем временем мы заставляем службу сбросить временный файл с фиксированным именем, а именно WERFFFF.tmp.
После того как служба создает временный файл с именем WERFFFF.tmp, API автоматически закрывает удерживаемый дескриптор файла и возвращает имя файла службе для дальнейших операций с файлом. Это именно то место, где возникает ошибка. Выполняются три условия:
Здесь служба будет записывать содержимое в файл и удалять его. И запись, и удаление приведут к повышению привилегий за счет использования файловых ссылок и определенных методов эксплуатации.
Чтобы превратить ошибку в произвольное удаление файлов, мы творчески используем множественные точки соединения каталогов (directory junctions) для завершения эксплуатации. Наш эксплойт включает следующие шаги:
WER***.tmp в $pwd\1\ и создаем точку соединения $pwd\2\ -> $pwd\1\;$pwd\2\ и другой процесс для непрерывного выполнения команды SetOplock $pwd\1\WERFFFF.tmp;$pwd\2\ -> \RPC CONTROL\, а затем создаем символический объект \RPC CONTROL\WERFFFF.tmp -> $target и \RPC CONTROL\WERFFFF.tmp.etl -> $target;Подробная эксплуатация и PoC предоставлены в WERReport-CVE-2020-0753.
Используя уязвимость в GetTempFileNameW, мы получаем предсказуемое место, где будет работать служба; используя многоуровневые точки соединения файловой системы, мы делаем состояние гонки надежно эксплуатируемым.
Тем временем мы заметили, что такого рода ошибка гонки также может привести к возможному перезаписыванию файлов, что, вероятно, ведет к ошибкам повышения привилегий при определенных обстоятельствах.
Чтобы объяснить, почему произвольное повреждение файлов (если вы можете контролировать очень маленькую часть содержимого файла: менее 63 байт) может быть превращено в EoP, нам нужно обратить внимание на механизм работы Защитника Windows.
У Защитника Windows есть база данных сигнатур вредоносных программ. Если файл содержит какую-то сигнатуру вредоносной программы, защитник сочтет его вредоносным и удалит. Однако эта функция приводит к дополнительной поверхности атаки. Например, на WCTF2019 @icchy из tokyowesterns разработал задачу для Windows ctf под названием "Gyotaku The Flag", которая использует эту функцию как оракул для утечки информации.
Здесь мы используем эту функцию Защитника Windows для удаления произвольного файла, если у нас есть произвольное повреждение файла с частичным контролем содержимого. Мы можем просто записать сигнатуру вредоносной программы в файл и инициировать стандартную проверку Защитником Windows; файл будет помещен в карантинную зону защитника, откуда обычный пользователь (т.е. пользователь со средним уровнем целостности, не администратор) может его удалить, просто запустив операцию проверки два раза.
Таким образом, ошибка произвольного повреждения файлов может быть превращена в произвольное удаление файлов, если с помощью этой ошибки можно поместить строку сигнатуры вредоносной программы в целевой файл.
Используя эту технику, мы получаем произвольное удаление файлов с помощью Защитника.
Произвольное удаление файлов можно использовать гораздо проще для получения дополнительных привилегий.
Microsoft OneDrive — это пакет приложений, предоставляющий услуги персонального облачного хранения. Это приложение встроено в Windows как опция установки по умолчанию, начиная с Windows 8. В ходе нашего исследования были обнаружены и отправлены в MSRC 6 уязвимостей в запланированных задачах обслуживания OneDrive.
Вот таблица уязвимостей, которые мы собираемся раскрыть в соответствующих запланированных задачах Microsoft OneDrive:
| Уязвимая программа | Тип | Предоставлен PoC |
|---|---|---|
| FileSyncConfig.exe | HardLink | да |
| FileSyncHelper.exe | HardLink | да |
| OneDriveFileSyncConfig.exe | SymLink | да |
| OneDriveSetup.exe | HardLink | да |
| OneDriveSetup.exe | HardLink | да |
| OneDriveStandaloneUpdater.exe | HardLink | да |
Все 6 ошибок вызваны тем, что служба некорректно обрабатывает жесткие и символьные ссылки при работе с расположениями, контролируемыми обычным пользователем. При эксплуатации этих ошибок сложность возникает из-за того, что имя файла обычно содержит PID текущего процесса или временную метку, указывающую, когда файл обрабатывался. Обе проблемы решаются установкой оплока (oplock) на уникальный DLL-файл, который служба попытается загрузить при запуске, что позволяет получить все необходимые данные для прогнозирования имени файла, с которым служба будет работать позже. Пример PoC предоставлен в каталоге FileSyncConfigTemp_hardlink.