В предыдущих сериях
Не так давно я рассказал о двух уязвимостях Стима: CVE-2019-14743 и CVE-2019-15316. Там была целая история о том, как я пытался зарепортить их, у меня не получалось, меня забанили, и только после публичного раскрытия и помощи сообщества удалось достичь результатов. Valve сделали вид, что извинились, и разбанили меня на HackerOne, так что очередную уязвимость я решил передать через этот сервис. На третий раз (здесь должна быть очевидная шутка о Half-Life 3) все прошло более или менее успешно.
Описание уязвимости
Уязвимость позволяет создавать файлы с частично контролируемым содержанием (либо добавлять частично контролируемое содержание к уже существующим файлам). Версия уязвимого сервиса — 5.31.28.21 (данные файла SteamService.exe). Сначала я опишу как воспользоваться уязвимостью, а после опишу возможные последствия.
Шаг 1. Окружение
Необходимо завершить приложение Steam и остановить сервис «Steam Client Service», если они запущены. Чаще всего пользователи без прав администратора не могут запускать и останавливать любые сервисы. Но конкретно для этого сервиса Valve установили права, позволяющие всем пользователям останавливать и запускать его.
Создаем папку в любом доступном пользователю месте (например, «C:test»). В эту папку необходимо скопировать файлы Steam.exe и steamclient.dll из исходной папки Стима (по-умолчанию это «C:Program Files (x86)Steam»). Создаем пустую подпапку logs («C:testlogs»).
Теперь поправим реестр: в ветке «HKLMSoftwarewow6432nodevalvesteam» сменим значение параметра «InstallPath» на «C:test1..». Обычно пользователям без прав администратора ветки реестра внутри HKLM недоступны на запись, но не в данном случае. При установке Valve установили такие права на свою ветку внутри HKLM, что в ней всем пользователям доступны любые действия («Full control» для группы «Users»).
Шаг 2. Проведем небольшой тест
Запустим сервис «Steam Client Service». После того, как он остановится (это произойдет автоматически через несколько секунд), проверим содержимое папки «C:testlogs» – обнаружим там файл «service_log.txt». Содержимое лога будет примерно таким:
08/27/19 13:45:01 : ERROR: SteamService: Invalid file signature C:test1..binSteamService.dll
Обратим внимание, что путь «C:test1..» эквивалентен пути «C:test», поэтому для работы Windows использовал второй, а в сообщение попал первый. Удалим файл «service_log.txt» и продолжим.
Шаг 3. Добавим больше текста
Интересный факт: когда ОС Windows работает с путями, содержащими "..", она автоматически упрощает такие пути. Не проводя никакие проверки для промежуточных папок.
Например, путь «C:1<test>..» будет преобразован в «C:1» не смотря на тот факт, что в имени папки нельзя использовать символы угловых скобок.
На первом шаге мы прописали путь в реестре, теперь добавим в него переносы строк. Это можно сделать, написав простой код, но реально сделать и из интерфейса regedit. Достаточно открыть ветку реестра «HKLMSoftwarewow6432nodevalvesteam» и выбрать «Modify binary data..» в контекстном меню параметра «InstallPath». Появится что-то типа хекс-редактора, где можно произвести нужные правки.
Проведем еще один тестовый запуск сервиса и проверим результат наших действий.
После теста снова необходимо удалить файл «service_log.txt».
Шаг 4. Перенаправим создаваемый файл
Пользователи без прав администратора не могут создавать символические ссылки с одного файла на другой. Но тут есть фокус – можно объединить другие виды ссылок, которые доступны пользователям без прав администратора, чтобы получить эффект, близкий к симлинку с файла на файл.
Сначала создадим NTFS reparse point (другое название NTFS mount point) с папки «C:testlogs» на "RPC Control". "RPC Control" – это не обычная папка в привычном нам понимании, ее нельзя посмотреть, например, в эксплорере. Это системная объектная директория, внутри которой находятся, например, именованные мьютексы, события и прочие подобные объекты. Почему для нее работает перенаправление через NTFS reparse point непонятно, скорее всего, дело в использовании одинаковых абстракций для папок в файловой системе и объектных директорий. Из объектной директории можно создать симлинк на файл без прав администратора. Создадим симлинк вида "RPC Controlservice_log.txt" <-> «C:Путькфайлу».
В результате любые обращения к «C:testlogsservice_log.txt» будут перенаправлены на файл «C:Путькфайлу». Чтобы создать такое перенаправление есть два основных требования – папка, из которой создается NTFS reparse point, должна быть пустой, и она же должна быть доступна для записи пользователю. Именно для выполнения первого условия, мы после каждого теста удаляли файл «service_logs.txt», второе условие обеспечивается тем, что исходную папку мы создали в контролируемом пользователем месте.
Существует специальная утилита, которая создает такие пары симлинков – CreateSymlink и доступна для скачивания на GitHub. Использование утилиты:
CreateSymlink.exe <откуда> <куда>
В нашем случае это будет:
CreateSymlink.exe "C:testlogsservice_log.txt" "C:Путькфайлу"
Собирая все вместе, получаем, что при старте сервиса «Steam Client Service» будет создан файл по пути, который был указан при создании симлинка, и в этом файле будет содержимое, которое мы можем проконтролировать (ну кроме первой и последней строки). Если укажем путь к существующему файлу, то содержимое будет дописано в конец файла. Все это будет выполнено от имени сервиса Steam Client Service с правами NT AUTHORITYSYSTEM.
Impact
Теперь я перечислю возможные результаты воздействия от наименее важных и по возрастанию.
- DoS
Если целью симлинка поставить «C:WindowsSystem32configSAM» или «C:WindowsSystem32configSECURITY», то маловероятно, что ОС сможет загрузиться после перезагрузки.
- Перенаправление пользователя в интернете
Поставим цель симлинка «C:Windowssystem32driversetchosts» и добавим туда строку типа «127.0.0.1 google.com».
Результат:
- Горизонтальный EoP
Горизонтальным повышением привилегий называют такое изменение прав, при котором мы получаем доступ не к более высоким правам, а правам того же уровня, но относительно других объектов, например, к правам других пользователей.Поставим цель симлинка «C:ProgramDataMicrosoftWindowsStart MenuProgramsStartUprun.bat» и добавим туда строку типа «start C:test1.exe».
Все файлы из папки «C:ProgramDataMicrosoftWindowsStart MenuProgramsStartUp» исполняются пользователями, когда они входят в систему. Таким образом, один пользователь может принудить другого пользователя к запуску кода. Из bat файла все строчки будут выполняться по очереди. Первая и последняя просто не сделают ничего, но внедренная команда «start C:test1.exe» отработает.С внедрением такой команды есть одна тонкость – символы "" будут учитываться при нормализации пути, поэтому для корректной работы нужно будет добавить еще несколько ".." к прописываемому пути в реестре.
- Вертикальный EoP
Вертикальное повышение привилегий – это привычное повышение, например, от пользователя без прав администратора до NT AUTHORITYSYSTEM.Довольно часто можно найти ПО, которое исполняет текстовые скрипты с высокими правами. Мы можем добавить команды в такие скрипты и исполнить свой код с высокими правами. Я не нашел таких скриптов в чистой ОС, поэтому нельзя просто продемонстрировать такой эксплоит. Но в качестве примера я могу указать bat файлы, которые создаются NVIDIA и VmWare или logon-скрипты для ОС в домене.
Дополнительно для повышения можно проверить возможность создания xml-файлов, ini-файлов с нарушенным форматом. К сожалению вариантов слишком много – создание задач для TaskSheduler’а, работа с .manifest и прочими загрузками библиотек и многие другие. Мне кажется, что описанных выше результатов уже достаточно для понимания результатов уязвимости.
Таймлайн
Для полноты картины приведу скучный таймлайн по данной уязвимости.
26.08 – нашел уязвимость.
27.08 – разбанен на h1, опубликовал отчет.
12.09 – вышло исправление.
Выводы
На этом я заканчиваю посты об исследовании Steam – 3 уязвимости, которые были найдены при довольно поверхностном анализе, это уже не мало. Чтобы лезть глубже нужно больше времени и желания. К сожалению, отношение Valve и некомпетентность сотрудников HackerOne – это очень сильные преграды.
Я хочу еще раз поблагодарить всех читателей, которые помогли сделать Steam безопасней. Я благодарю Valve за то, что они все-таки исправили уязвимости и опровергли мои конспирологические теории. Я благодарю HackerOne за предоставление платформы, не смотря на то, что они в основном мешали мне донести уязвимости до Valve.
Автор: Кравец Василий