Приветствую всех читателей. В своем блоге я опубликовал много статей о том, как я находил уязвимости в разных продуктах. Но все истории-исследования заканчиваются победой. В этот раз я решил поделиться историей неуспеха. Небольшое исследование, которое заняло у меня где-то 5-6 часов, в ходе которого я был близок к созданию интересного эксплоита, но магия не случилась.
Как легко заметить, я люблю искать уязвимости на повышение привилегий. Обычно такие уязвимости позволяют подняться с уровня прав обычного пользователя, до уровня прав администратора или системы (NT AUTHORITY\SYSTEM). Но в данном случае, я решил рассмотреть другой вариант: поднятие прав с уровня NT AUTHORITY\LOCAL SERVICE до NT AUTHORITY\SYSTEM.
позволяют пользователю без прав администратора создавать разделы внутри себя. Исследователь показал, что можно создать раздел Performance, внутри которого указать dll. После некоторых команд эта dll будет загружена в пространство сервиса и тем самым исполнит код от имени NT AUTHORITY\SYSTEM, который предоставит пользователь с низкими правами. В старших версиях Windows такие прав уже нет и, вроде, даже для семерки были выпущены патчи. Запомним саму идею уязвимости.
Теперь посмотрим на сервисы с другой стороны. Обычно сервисы работают от имени одного из трех пользователей: NT AUTHORITY\SYSTEM (максимальные права), NT AUTHORITY\LOCAL SERVICE (права выше, чем у пользователей, но не такие высокие как NT AUTHORITY\SYSTEM) или NT AUTHORITY\NETWORK SERVICE (права как у предыдущего, но может проводить аутентификацию по сети). Иногда в ходе атак можно получить права NT AUTHORITY\LOCAL SERVICE и тут появляется вопрос, что же делать дальше? Вроде и права выше пользовательских (например есть привилегия SeImpersonatePrivilege), но, например, свободно читать файлы пользователей прав нет. Обычно в таких ситуация используют что-то из «картофельного» семейства: Rotten Potato, Juicy Potato и другие. Я решил посмотреть, а не найдется ли что-то свое.
Совмещая идеи из предыдущих абзацев, получаем общую канву исследования. Пробуем посмотреть на права в реестре, кому и что разрешено. Я взял свою утилиту SDDLViewer, указал ветку реестра
Эти строки говорят, что пользователь NT SERVICE\Dhcp может создавать подразделы в своей ветке, а пользователь NT SERVICE\Autotime может делать все что угодно в ветке сервиса W32Time. Имена пользователей вида NT SERVICE\НазваниеСервиса — это специальные пользователи или даже точнее сказать метки, которые получают соответствующие процессы сервисов. Поскольку сервис Dhcp по умолчанию запущен, прав на остановку у нас нет, то и рассматривать его я не стал.
А вот сервис W32Time довольно интересен, поскольку на него может влиять другой процесс, а именно сервис autotimesvc. Более того, не обязательно пользоваться идеей с созданием подраздела. У autotimesvc полные права на всю ветку, а значит можно поставить свой бинарный файл и указать пользователя NT AUTHORITY\SYSTEM. Кроме этого, запрашиваем права самого сервиса в видим:
На человеческом языке это означает, что NT AUTHORITY\LOCAL SERVICE может останавливать и запускать этот сервис. Все складывается просто идеально. Осталось только попасть в контекст сервиса autotimesvc.
Вся наша цепочка действий в итоге завязана на необходимость запуска сервиса autotimesvc. Если права не позволяют запустить сервис, то посмотрим на альтернативные возможности. У некоторых сервисов есть возможность запуска по триггерам. Запрос информации по триггерам сервиса: sc qtriggerinfo autotimesvc:
Хорошая новость: триггер есть. Плохая: это какой-то непонятный триггер.
Тут стоит сделать уточнение, что существует разные триггеры: вход в домен, получение сетевого пакета, событие системы ETW и другие. Я очень надеялся на то, что будет именно ETW, потому что такие события может создавать любой пользователь и так можно было бы запустить сервис. Но вот что такое «СОБЫТИЕ ИЗМЕНЕНИЯ НАСТРАИВАЕМОГО СОСТОЯНИЯ СИСТЕМЫ»?
Полезем смотреть в реестр за более подробными данными.
Смотрим: Action = 1 это значит, что при триггере сервис будет запущен.
Data0 — какие-то данные
GUID — идентификатор триггера
Type = 7 — тип триггера
Идем в MSDN за пояснениями. А там нет типа 7, он незадокументирован. Включаем гугл-фу. Находим хоть что-то, что показывает, что тип 7 и GUID из реестра связаны между собой.
Но это пока не приближает нас к пониманию как же этот триггер задействовать. Я собрал из реестра все подобные триггеры и стал смотреть на данные в поле Data0. Все они были как-то похожи:
Погуглив по разным вариантам, я обнаружил, что если взять первые 4 байта в обратном порядке, то начинают появляться интересные ссылки. Дальнейшие поиски точно показали, что речь идет о подсистеме WNF и ее событиях.
Более того, я наше свой вариант Data0 под названием: WNF_CELL_NITZ_INFO 0xd8a0b2ea3bed075. Ключевое слово NITZ фигурирует и в описании сервиса autotimesvc.
Цель уже близка, вся цепочка действий зависит только от возможности изменить событие WNF_CELL_NITZ_INFO. Пробуем сделать это из под обычного пользователя — отказ в доступе. Пробуем из под NT AUTHORITY\LOCAL SERVICE — отказ в доступе.
Запрашиваем очередной SDDL для этого события и получаем:
CC — чтение данных, DC — запись. Видим, что изменить состояние могут либо администраторы, либо сервис WwanSvc. Нам не привыкать, смотрим, что еще за сервис появился. А вот тут все — этот сервис работает уже под пользователем NT AUTHORITY\SYSTEM и не имеет каких-то особых вариантов для воздействия. Вот на этом мое исследование и кончилось. Цепочка действий не сложилась — эксплоит я не написал.
Кравец Василий @xi-tauw
Как легко заметить, я люблю искать уязвимости на повышение привилегий. Обычно такие уязвимости позволяют подняться с уровня прав обычного пользователя, до уровня прав администратора или системы (NT AUTHORITY\SYSTEM). Но в данном случае, я решил рассмотреть другой вариант: поднятие прав с уровня NT AUTHORITY\LOCAL SERVICE до NT AUTHORITY\SYSTEM.
Начало
Все началось со статьи про уязвимость повышения привилегий в Windows 7. Уязвимость состоит в том, что по умолчанию Windows 7 в реестре две ветки имеют интересные права для пользователя ОС. А именно веткиHKLM\SYSTEM\CurrentControlSet\Services\Dnscache
HKLM\SYSTEM\CurrentControlSet\Services\RpcEptMapper
позволяют пользователю без прав администратора создавать разделы внутри себя. Исследователь показал, что можно создать раздел Performance, внутри которого указать dll. После некоторых команд эта dll будет загружена в пространство сервиса и тем самым исполнит код от имени NT AUTHORITY\SYSTEM, который предоставит пользователь с низкими правами. В старших версиях Windows такие прав уже нет и, вроде, даже для семерки были выпущены патчи. Запомним саму идею уязвимости.
Теперь посмотрим на сервисы с другой стороны. Обычно сервисы работают от имени одного из трех пользователей: NT AUTHORITY\SYSTEM (максимальные права), NT AUTHORITY\LOCAL SERVICE (права выше, чем у пользователей, но не такие высокие как NT AUTHORITY\SYSTEM) или NT AUTHORITY\NETWORK SERVICE (права как у предыдущего, но может проводить аутентификацию по сети). Иногда в ходе атак можно получить права NT AUTHORITY\LOCAL SERVICE и тут появляется вопрос, что же делать дальше? Вроде и права выше пользовательских (например есть привилегия SeImpersonatePrivilege), но, например, свободно читать файлы пользователей прав нет. Обычно в таких ситуация используют что-то из «картофельного» семейства: Rotten Potato, Juicy Potato и другие. Я решил посмотреть, а не найдется ли что-то свое.
Исследование
Совмещая идеи из предыдущих абзацев, получаем общую канву исследования. Пробуем посмотреть на права в реестре, кому и что разрешено. Я взял свою утилиту SDDLViewer, указал ветку реестра
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services, убрал пользователей, которые нам не интересны (администраторы, система), убрал права на чтение и получилось вот что:
Код:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Dhcp
D:(A;;LC;;;NT SERVICE\Dhcp)(A;CIIO;LC;;;NT SERVICE\Dhcp)
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\W32Time
D:(A;;DCLC;;;NT SERVICE\autotimesvc)(A;CIIO;GW;;;NT SERVICE\autotimesvc)
А вот сервис W32Time довольно интересен, поскольку на него может влиять другой процесс, а именно сервис autotimesvc. Более того, не обязательно пользоваться идеей с созданием подраздела. У autotimesvc полные права на всю ветку, а значит можно поставить свой бинарный файл и указать пользователя NT AUTHORITY\SYSTEM. Кроме этого, запрашиваем права самого сервиса в видим:
Код:
Windows Time (W32Time)
D:(A;;RPWP;;;LS)
Первые трудности
Сервис autotimesvc не имеет никаких особых отличий от других сервисов. Плюсы: работает от имени NT AUTHORITY\LOCAL SERVICE, что позволяет нам в него влезть. Минусы: запустить и остановить этот сервис могут только администраторы и NT AUTHORITY\SYSTEM.Вся наша цепочка действий в итоге завязана на необходимость запуска сервиса autotimesvc. Если права не позволяют запустить сервис, то посмотрим на альтернативные возможности. У некоторых сервисов есть возможность запуска по триггерам. Запрос информации по триггерам сервиса: sc qtriggerinfo autotimesvc:
Хорошая новость: триггер есть. Плохая: это какой-то непонятный триггер.
Тут стоит сделать уточнение, что существует разные триггеры: вход в домен, получение сетевого пакета, событие системы ETW и другие. Я очень надеялся на то, что будет именно ETW, потому что такие события может создавать любой пользователь и так можно было бы запустить сервис. Но вот что такое «СОБЫТИЕ ИЗМЕНЕНИЯ НАСТРАИВАЕМОГО СОСТОЯНИЯ СИСТЕМЫ»?
Полезем смотреть в реестр за более подробными данными.
Смотрим: Action = 1 это значит, что при триггере сервис будет запущен.
Data0 — какие-то данные
GUID — идентификатор триггера
Type = 7 — тип триггера
Идем в MSDN за пояснениями. А там нет типа 7, он незадокументирован. Включаем гугл-фу. Находим хоть что-то, что показывает, что тип 7 и GUID из реестра связаны между собой.
Код:
//
// CUSTOM_SYSTEM_STATE_CHANGE_EVENT_GUID is used with SERVICE_TRIGGER_TYPE_CUSTOM_SYSTEM_STATE_CHANGE
//
DEFINE_GUID ( /* 2d7a2816-0c5e-45fc-9ce7-570e5ecde9c9 */
CUSTOM_SYSTEM_STATE_CHANGE_EVENT_GUID,
0x2d7a2816,
0x0c5e,
0x45fc,
0x9c, 0xe7, 0x57, 0x0e, 0x5e, 0xcd, 0xe9, 0xc9
);
/* 2d7a2816-0c5e-45fc-9ce7-570e5ecde9c9 */extern "C" const GUID CUSTOM_SYSTEM_STATE_CHANGE_EVENT_GUID;
Код:
7518BCA32C0FC641
75D0BEA32E0B8A0D
7530BCA32B188341
7538BCA32F029209
7548BCA32F029209
7558BCA32F029209
7568BCA32F029209
7538BCA32F029209
7548BCA32F029209
7558BCA32F029209
7568BCA32F029209
...
Более того, я наше свой вариант Data0 под названием: WNF_CELL_NITZ_INFO 0xd8a0b2ea3bed075. Ключевое слово NITZ фигурирует и в описании сервиса autotimesvc.
Последний рубеж
WNF хоть и не очень хорошо документирован, но Алекс Ионеску все же внес огромный вклад и даже подготовил утилиты по работе с событиями WNF.Цель уже близка, вся цепочка действий зависит только от возможности изменить событие WNF_CELL_NITZ_INFO. Пробуем сделать это из под обычного пользователя — отказ в доступе. Пробуем из под NT AUTHORITY\LOCAL SERVICE — отказ в доступе.
Запрашиваем очередной SDDL для этого события и получаем:
Код:
D:(A;;CCDC;;;SY)(A;;CCDC;;;NT SERVICE\WwanSvc)(A;;CCDC;;;BA)(A;;CC;;;AU)(A;;CC;;;IU)
Заключение
Здесь можно поставить много слов «если». Если бы сервис WwanSvc работал бы от имени NT AUTHORITY\LOCAL SERVICE… Если бы права были не такими ограничивающими… Если бы еще что-то было, то вот тогда я точно бы все реализовал. Но, как я уже сказал в начале статьи — не всякое исследование обязательно успешное. Я потратил время, но получил новый опыт, узнал о WNF. Возможно я где-то свернул не туда и кто-то другой сумеет реализовать эту идею, а может я сам вернусь к ней спустя время. В любом случае это было интересное путешествие.Кравец Василий @xi-tauw