Приветствую всех читателей. В своем блоге я опубликовал много статей о том, как я находил уязвимости в разных продуктах. Но все истории-исследования заканчиваются победой. В этот раз я решил поделиться историей неуспеха. Небольшое исследование, которое заняло у меня где-то 5-6 часов, в ходе которого я был близок к созданию интересного эксплоита, но магия не случилась.
Как легко заметить, я люблю искать уязвимости на повышение привилегий. Обычно такие уязвимости позволяют подняться с уровня прав обычного пользователя, до уровня прав администратора или системы (NT AUTHORITY\SYSTEM). Но в данном случае, я решил рассмотреть другой вариант: поднятие прав с уровня NT AUTHORITY\LOCAL SERVICE до NT AUTHORITY\SYSTEM.
Все началось со статьи про уязвимость повышения привилегий в Windows 7. Уязвимость состоит в том, что по умолчанию Windows 7 в реестре две ветки имеют интересные права для пользователя ОС. А именно ветки
позволяют пользователю без прав администратора создавать разделы внутри себя. Исследователь показал, что можно создать раздел 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, убрал пользователей, которые нам не интересны (администраторы, система), убрал права на чтение и получилось вот что:
Эти строки говорят, что пользователь NT SERVICE\Dhcp может создавать подразделы в своей ветке, а пользователь NT SERVICE\Autotime может делать все что угодно в ветке сервиса W32Time. Имена пользователей вида NT SERVICE\НазваниеСервиса — это специальные пользователи или даже точнее сказать метки, которые получают соответствующие процессы сервисов. Поскольку сервис Dhcp по умолчанию запущен, прав на остановку у нас нет, то и рассматривать его я не стал.
А вот сервис W32Time довольно интересен, поскольку на него может влиять другой процесс, а именно сервис autotimesvc. Более того, не обязательно пользоваться идеей с созданием подраздела. У autotimesvc полные права на всю ветку, а значит можно поставить свой бинарный файл и указать пользователя NT AUTHORITY\SYSTEM. Кроме этого, запрашиваем права самого сервиса в видим:
На человеческом языке это означает, что NT AUTHORITY\LOCAL SERVICE может останавливать и запускать этот сервис. Все складывается просто идеально. Осталось только попасть в контекст сервиса autotimesvc.
Сервис autotimesvc не имеет никаких особых отличий от других сервисов. Плюсы: работает от имени NT AUTHORITY\LOCAL SERVICE, что позволяет нам в него влезть. Минусы: запустить и остановить этот сервис могут только администраторы и NT AUTHORITY\SYSTEM.
Вся наша цепочка действий в итоге завязана на необходимость запуска сервиса 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 хоть и не очень хорошо документирован, но Алекс Ионеску все же внес огромный вклад и даже подготовил утилиты по работе с событиями WNF.
Цель уже близка, вся цепочка действий зависит только от возможности изменить событие WNF_CELL_NITZ_INFO. Пробуем сделать это из под обычного пользователя — отказ в доступе. Пробуем из под NT AUTHORITY\LOCAL SERVICE — отказ в доступе.
Запрашиваем очередной SDDL для этого события и получаем:
CC — чтение данных, DC — запись. Видим, что изменить состояние могут либо администраторы, либо сервис WwanSvc. Нам не привыкать, смотрим, что еще за сервис появился. А вот тут все — этот сервис работает уже под пользователем NT AUTHORITY\SYSTEM и не имеет каких-то особых вариантов для воздействия. Вот на этом мое исследование и кончилось. Цепочка действий не сложилась — эксплоит я не написал.
Здесь можно поставить много слов «если». Если бы сервис WwanSvc работал бы от имени NT AUTHORITY\LOCAL SERVICE… Если бы права были не такими ограничивающими… Если бы еще что-то было, то вот тогда я точно бы все реализовал. Но, как я уже сказал в начале статьи — не всякое исследование обязательно успешное. Я потратил время, но получил новый опыт, узнал о WNF. Возможно я где-то свернул не туда и кто-то другой сумеет реализовать эту идею, а может я сам вернусь к ней спустя время. В любом случае это было интересное путешествие.
Как легко заметить, я люблю искать уязвимости на повышение привилегий. Обычно такие уязвимости позволяют подняться с уровня прав обычного пользователя, до уровня прав администратора или системы (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)
Эти строки говорят, что пользователь NT SERVICE\Dhcp может создавать подразделы в своей ветке, а пользователь NT SERVICE\Autotime может делать все что угодно в ветке сервиса W32Time. Имена пользователей вида NT SERVICE\НазваниеСервиса — это специальные пользователи или даже точнее сказать метки, которые получают соответствующие процессы сервисов. Поскольку сервис Dhcp по умолчанию запущен, прав на остановку у нас нет, то и рассматривать его я не стал.
А вот сервис W32Time довольно интересен, поскольку на него может влиять другой процесс, а именно сервис autotimesvc. Более того, не обязательно пользоваться идеей с созданием подраздела. У autotimesvc полные права на всю ветку, а значит можно поставить свой бинарный файл и указать пользователя NT AUTHORITY\SYSTEM. Кроме этого, запрашиваем права самого сервиса в видим:
Windows Time (W32Time)
D:(A;;RPWP;;;LS)
На человеческом языке это означает, что NT AUTHORITY\LOCAL SERVICE может останавливать и запускать этот сервис. Все складывается просто идеально. Осталось только попасть в контекст сервиса autotimesvc.
Первые трудности
Сервис 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;
Но это пока не приближает нас к пониманию как же этот триггер задействовать. Я собрал из реестра все подобные триггеры и стал смотреть на данные в поле Data0. Все они были как-то похожи:
7518BCA32C0FC641
75D0BEA32E0B8A0D
7530BCA32B188341
7538BCA32F029209
7548BCA32F029209
7558BCA32F029209
7568BCA32F029209
7538BCA32F029209
7548BCA32F029209
7558BCA32F029209
7568BCA32F029209
...
Погуглив по разным вариантам, я обнаружил, что если взять первые 4 байта в обратном порядке, то начинают появляться интересные ссылки. Дальнейшие поиски точно показали, что речь идет о подсистеме WNF и ее событиях.
Более того, я наше свой вариант 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)
CC — чтение данных, DC — запись. Видим, что изменить состояние могут либо администраторы, либо сервис WwanSvc. Нам не привыкать, смотрим, что еще за сервис появился. А вот тут все — этот сервис работает уже под пользователем NT AUTHORITY\SYSTEM и не имеет каких-то особых вариантов для воздействия. Вот на этом мое исследование и кончилось. Цепочка действий не сложилась — эксплоит я не написал.
Заключение
Здесь можно поставить много слов «если». Если бы сервис WwanSvc работал бы от имени NT AUTHORITY\LOCAL SERVICE… Если бы права были не такими ограничивающими… Если бы еще что-то было, то вот тогда я точно бы все реализовал. Но, как я уже сказал в начале статьи — не всякое исследование обязательно успешное. Я потратил время, но получил новый опыт, узнал о WNF. Возможно я где-то свернул не туда и кто-то другой сумеет реализовать эту идею, а может я сам вернусь к ней спустя время. В любом случае это было интересное путешествие.
GeorgeGFedoroff
Спасибо. Это было изумительное приключение. А еще есть?
xi-tauw Автор
Спасибо. Рано или поздно будет еще.