В предыдущих сериях


Не так давно я рассказал о двух уязвимостях Стима: 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:\test\logs»).

Теперь поправим реестр: в ветке «HKLM\Software\wow6432node\valve\steam» сменим значение параметра «InstallPath» на «C:\test\1\..». Обычно пользователям без прав администратора ветки реестра внутри HKLM недоступны на запись, но не в данном случае. При установке Valve установили такие права на свою ветку внутри HKLM, что в ней всем пользователям доступны любые действия («Full control» для группы «Users»).

Шаг 2. Проведем небольшой тест


Запустим сервис «Steam Client Service». После того, как он остановится (это произойдет автоматически через несколько секунд), проверим содержимое папки «C:\test\logs» – обнаружим там файл «service_log.txt». Содержимое лога будет примерно таким:

08/27/19 13:45:01 : ERROR: SteamService: Invalid file signature C:\test\1\..\bin\SteamService.dll

Обратим внимание, что путь «C:\test\1\..» эквивалентен пути «C:\test», поэтому для работы Windows использовал второй, а в сообщение попал первый. Удалим файл «service_log.txt» и продолжим.

Шаг 3. Добавим больше текста


Интересный факт: когда ОС Windows работает с путями, содержащими "\..", она автоматически упрощает такие пути. Не проводя никакие проверки для промежуточных папок.

Например, путь «C:\1\<test>\..» будет преобразован в «C:\1» не смотря на тот факт, что в имени папки нельзя использовать символы угловых скобок.

На первом шаге мы прописали путь в реестре, теперь добавим в него переносы строк. Это можно сделать, написав простой код, но реально сделать и из интерфейса regedit. Достаточно открыть ветку реестра «HKLM\Software\wow6432node\valve\steam» и выбрать «Modify binary data..» в контекстном меню параметра «InstallPath». Появится что-то типа хекс-редактора, где можно произвести нужные правки.



Проведем еще один тестовый запуск сервиса и проверим результат наших действий.



После теста снова необходимо удалить файл «service_log.txt».

Шаг 4. Перенаправим создаваемый файл


Пользователи без прав администратора не могут создавать символические ссылки с одного файла на другой. Но тут есть фокус – можно объединить другие виды ссылок, которые доступны пользователям без прав администратора, чтобы получить эффект, близкий к симлинку с файла на файл.

Сначала создадим NTFS reparse point (другое название NTFS mount point) с папки «C:\test\logs» на "\RPC Control\". "\RPC Control\" – это не обычная папка в привычном нам понимании, ее нельзя посмотреть, например, в эксплорере. Это системная объектная директория, внутри которой находятся, например, именованные мьютексы, события и прочие подобные объекты. Почему для нее работает перенаправление через NTFS reparse point непонятно, скорее всего, дело в использовании одинаковых абстракций для папок в файловой системе и объектных директорий. Из объектной директории можно создать симлинк на файл без прав администратора. Создадим симлинк вида "\RPC Control\service_log.txt" <-> «C:\Путь\к\файлу».

В результате любые обращения к «C:\test\logs\service_log.txt» будут перенаправлены на файл «C:\Путь\к\файлу». Чтобы создать такое перенаправление есть два основных требования – папка, из которой создается NTFS reparse point, должна быть пустой, и она же должна быть доступна для записи пользователю. Именно для выполнения первого условия, мы после каждого теста удаляли файл «service_logs.txt», второе условие обеспечивается тем, что исходную папку мы создали в контролируемом пользователем месте.

Существует специальная утилита, которая создает такие пары симлинков – CreateSymlink и доступна для скачивания на GitHub. Использование утилиты:

CreateSymlink.exe <откуда> <куда>

В нашем случае это будет:

CreateSymlink.exe "C:\test\logs\service_log.txt" "C:\Путь\к\файлу"

Собирая все вместе, получаем, что при старте сервиса «Steam Client Service» будет создан файл по пути, который был указан при создании симлинка, и в этом файле будет содержимое, которое мы можем проконтролировать (ну кроме первой и последней строки). Если укажем путь к существующему файлу, то содержимое будет дописано в конец файла. Все это будет выполнено от имени сервиса Steam Client Service с правами NT AUTHORITY\SYSTEM.

Impact


Теперь я перечислю возможные результаты воздействия от наименее важных и по возрастанию.

  1. DoS

    Если целью симлинка поставить «C:\Windows\System32\config\SAM» или «C:\Windows\System32\config\SECURITY», то маловероятно, что ОС сможет загрузиться после перезагрузки.
  2. Перенаправление пользователя в интернете

    Поставим цель симлинка «C:\Windows\system32\drivers\etc\hosts» и добавим туда строку типа «127.0.0.1 google.com».

    Результат:

  3. Горизонтальный EoP
    Горизонтальным повышением привилегий называют такое изменение прав, при котором мы получаем доступ не к более высоким правам, а правам того же уровня, но относительно других объектов, например, к правам других пользователей.

    Поставим цель симлинка «C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\run.bat» и добавим туда строку типа «start C:\test\1.exe».
    Все файлы из папки «C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp» исполняются пользователями, когда они входят в систему. Таким образом, один пользователь может принудить другого пользователя к запуску кода. Из bat файла все строчки будут выполняться по очереди. Первая и последняя просто не сделают ничего, но внедренная команда «start C:\test\1.exe» отработает.

    С внедрением такой команды есть одна тонкость – символы "\" будут учитываться при нормализации пути, поэтому для корректной работы нужно будет добавить еще несколько "\.." к прописываемому пути в реестре.
  4. Вертикальный EoP
    Вертикальное повышение привилегий – это привычное повышение, например, от пользователя без прав администратора до NT AUTHORITY\SYSTEM.

    Довольно часто можно найти ПО, которое исполняет текстовые скрипты с высокими правами. Мы можем добавить команды в такие скрипты и исполнить свой код с высокими правами. Я не нашел таких скриптов в чистой ОС, поэтому нельзя просто продемонстрировать такой эксплоит. Но в качестве примера я могу указать bat файлы, которые создаются NVIDIA и VmWare или logon-скрипты для ОС в домене.

Дополнительно для повышения можно проверить возможность создания xml-файлов, ini-файлов с нарушенным форматом. К сожалению вариантов слишком много – создание задач для TaskSheduler’а, работа с .manifest и прочими загрузками библиотек и многие другие. Мне кажется, что описанных выше результатов уже достаточно для понимания результатов уязвимости.

Таймлайн


Для полноты картины приведу скучный таймлайн по данной уязвимости.
26.08 – нашел уязвимость.
27.08 – разбанен на h1, опубликовал отчет.
12.09 – вышло исправление.

Выводы


На этом я заканчиваю посты об исследовании Steam – 3 уязвимости, которые были найдены при довольно поверхностном анализе, это уже не мало. Чтобы лезть глубже нужно больше времени и желания. К сожалению, отношение Valve и некомпетентность сотрудников HackerOne – это очень сильные преграды.

Я хочу еще раз поблагодарить всех читателей, которые помогли сделать Steam безопасней. Я благодарю Valve за то, что они все-таки исправили уязвимости и опровергли мои конспирологические теории. Я благодарю HackerOne за предоставление платформы, не смотря на то, что они в основном мешали мне донести уязвимости до Valve.

This article in english.

Комментарии (11)


  1. amarao
    01.10.2019 12:29

    steam точка йехе, как всегда.


    ./steam.sh, в отдельном network namespace от отдельного пользователя с запретом capabilities, ни разу не запущенный от root'а, с приватным home dir и devices.


  1. Victor_koly
    01.10.2019 12:42
    +2

    При установке Valve установили такие права на свою ветку внутри HKLM, что в ней всем пользователям доступны любые действия («Full control» для группы «Users»).

    Круто выходит.


  1. BingoBongo
    01.10.2019 12:51
    -2

    К чему эти танцы со стимом? Большинство пользователей имеет права администратора, почему бы сразу не удалить папку C:/Windows/System32?


  1. Mur81
    01.10.2019 13:46

    Если вручную поменять учётку под которой стартует сервис стима на учётку с только юзерскими правами, то нарушит ли это его работоспособность? Раз права на запись в его парку и ветку реестра уже есть у юзеров. Просто что бы хотя бы что-то не запускалось с правами системы.


    1. xi-tauw Автор
      01.10.2019 13:52

      С большой вероятностью нарушит, поскольку обычно основная задача сервиса как раз выполнять действия требующие высоких привилегий.
      Сервис Steam при своем старте пытается обновить себя и без админских прав он не сможет скопировать файлы в C:\Program Files (x86)\Common Files\Steam — думаю что после этого он завершит свою работу.


      1. Mur81
        01.10.2019 14:14

        задача сервиса как раз выполнять действия требующие высоких привилегий

        Так-то оно так, но мы же знаем, что на ветку в HKLM и папку в Program Files права на запись у юзеров уже есть. Про C:\Program Files (x86)\Common Files\Steam не знал — пишу с телефона и рабочего компа, тут Стима нет и посмотреть не могу.
        То что я предложил выше это просто первое, что пришло в голову. Т.е. ситуация на мой взгляд такая — мы понимаем, что это насквозь дырявое поделие и задача малой кровью хотя бы не допустить эскалации привилегий до NT AUTHORITY\SYSTEM.
        Может быть попробовать дать права на запись юзерам в C:\Program Files (x86)\Common Files\Steam. Да, согласен, что это не то что бы очень хорошее предложение. Но думается это меньшее из зол.


        1. xi-tauw Автор
          01.10.2019 14:28

          Если вопрос именно как не допустить эскалации, то в данный момент уязвимость закрыта (насколько я смотрел — пути нормализуются до записи в лог и сам файл лога перенесен из доступной пользователю папки).
          Что случится при любых изменениях в правах — никому не известно. Некоторые пользователи указывали, что они отключали сервис вообще и клиент продолжал работать. но это до первого обновления, надо думать.


          1. Mur81
            01.10.2019 15:49

            Мне кажется, что это была не последняя уязвимость. Вот в чём дело.
            По поводу предложенной мной схему понял — надо проверять.


  1. ormoulu
    01.10.2019 14:38
    +2

    Да вы так скоро им все lpe пофиксите :D


  1. Sui_Dream
    01.10.2019 17:39

    This article in english.

    Думаю, такие ссылки лучше давать в начале статьи.


  1. iluxa1810
    02.10.2019 08:26

    Steam- это маленькая инди-студия. Не нужно на них обижаться…
    Они вон спустя несколько лет пофиксили моргания у NPC в Half-Life 2, а спустя 6 лет после выхода Dota 2 озаботились вопросами матчмейкинга и бустинга аккаунтов…