Pull to refresh

Обламываем UAC

Reading time 6 min
Views 102K
Уж не знаю, сколько раз поднималась пресловутая тема контроля за действиями пользователя (которая начиная с Windows Vista известна как UAC): нужна ли она, насколько эффективна… Но мы рассмотрим этот вопрос еще раз, теперь с чисто прикладной, хакерской точки зрения. Рассмотрим плюсы и минусы системы, а также самое главное — как ее можно (и можно ли вообще) обойти.



Итак, что же такое UAC с точки зрения безопасности? Разработчики Windows (видимо, немало озаботившись унылыми сведениями из багтраков, регулярно пополняющимися все новыми и новыми уязвимостями в самой распространенной ОС в мире) решили, что если уж все или почти все юзеры сидят под правами администратора, то надо сделать некий программный компонент, который будет испрашивать у юзеров разрешения.
Оставим в стороне холивар на тему «Нужны ли простому юзеру права администратора?», поскольку сей крайне философский вопрос спорен: с одной стороны, права админа простому пользователю, действительно, не нужны, а с другой – они нужны туевой хуче довольно повседневных программ.
Итак, UAC призвана обеспечить пользователям возможность работать, не прибегая к административным правам. Обладая административными правами, пользователь может просматривать и изменять любую часть операционной системы, включая код и данные других пользователей и даже самой Windows. Без административных прав пользователи не могут случайно изменить системные параметры, вредоносная программа не может изменить параметры системной безопасности или отключить авер, а пользователи не могут нарушить безопасность важных данных других пользователей на общедоступных компьютерах. Работа с правами обычного пользователя, таким образом, помогает уменьшить количество срочных вызовов службы поддержки в корпоративных средах, смягчить ущерб от вредоносной программы, способствует более четкой работе домашних компьютеров и защищает уязвимые данные на общедоступных тачках.
UAC делит все исполняемые задачи на две группы – те, которые могут быть исполнены обычными пользователями и те, которые выполняются только администраторами. UAC незаметно для администратора переводит систему в режим непривилегированного пользователя, а когда требуются права администратора — появляется системный диалог, через который можно временно повысить свои права.
И ведь надо признать, что введение UAC довольно сильно обломало начинающих и не очень кодеров, зарабатывающих себе на жизнь разработкой малвари, так что на специальных бордах заказчики теперь в первую очередь спрашивают о возможности кода работать в Vista/7 и обходить UAC. Платили и до сих пор платят за это вполне адекватные деньги.

Немного ликбеза, или как законно получить права админа

Определить потребность системы и приложений в административных правах можно множеством способов. Один из них — команда контекстного меню и ярлык «Запуск от имени администратора» в пользовательском интерфейсе проводника. Эти элементы содержат цветной значок щита, который должен быть добавлен ко всем кнопкам или пунктам меню, выбор которых приводит к повышению прав. При выборе элемента «Запуск от имени администратора» проводник вызывает API-функцию ShellExecute с командой «runas».
Подавляющее большинство программ установки требуют административных прав, поэтому загрузчик образов, который инициирует запуск исполняемого файла, содержит код обнаружения установщиков для выявления устаревших версий. Часть алгоритмов используемой загрузчиком эвристики довольно проста: он ищет слова «setup», «install» или «update» в имени файла образа или внутренней информации о версии. Более сложные алгоритмы включают просмотр в исполняемом файле последовательностей байтов, обычно применяемых сторонними разработчиками в служебных программах – установочных оболочках.
Чтобы определить, нуждается ли целевой исполняемый файл в правах администратора, загрузчик образов также вызывает библиотеку совместимости приложений (appcompat). Библиотека обращается к базе данных совместимости приложений, чтобы определить, связаны ли с исполняемым файлом флаги совместимости RequireAdministrator или RunAsInvoker.
Самый общий способ запросить для исполняемого файла административные права — добавить в его файл манифеста приложения тег requestedElevationLevel. Манифесты — это XML-файлы, содержащие дополнительные сведения об образе. Они были введены в Windows XP как способ определения зависимостей для параллельно используемых библиотек DLL и сборок Microsoft .NET Framework. Наличие в манифесте элемента trustInfo (он показан ниже во фрагменте дампа Firewallsettings.exe) означает, что исполняемый файл был написан для Windows Vista и содержит элемент requestedElevationLevel. Атрибут level этого элемента может иметь одно из трех значений: asInvoker, highestAvailable и requireAdministrator.
<trustInfo 
 xmlns="urn:schema-microsoft-com:asm.v3">
 <security>
  <requestedPrivileges>
   <requestedExecutionLevel
    Level="requireAdministrator"
    uiAccess="false"/>
  </requestedPrivileges>
 </security>
</trustInfo>
Исполняемые файлы, не требующие административных прав, (например Notepad.exe), имеют значение атрибута asInvoker. В некоторых исполняемых файлах заложено допущение, что администраторы всегда хотят получить максимальные права. Поэтому в них используется значение highestAvailable. Пользователю, запускающему исполняемый файл с этим значением, предлагается повысить права, только если он работает в режиме AAM или рассматривается как администратор согласно определенным ранее правилам, и в связи с этим должен повысить права для обращения к своим административным привилегиям.
Примерами приложений, для которых используется значение highestAvailable, могут служить программы Regedit.exe, Mmc.exe и Eventvwr.exe. Наконец, значение requireAdministrator всегда инициирует запрос повышения и используется всеми исполняемыми файлами, которым не удастся выполнить свои действия без административных прав.
В приложениях со специальными возможностями атрибуту uiAccess задается значение «true» для управления окном ввода в процессах с повышенными правами. Кроме того, для обеспечения этих возможностей они должны быть подписаны и находиться в одном из нескольких безопасных размещений, включая %SystemRoot% и %ProgramFiles%.
Значения, задаваемые исполняемым файлом, можно легко определить, просмотрев его манифест с помощью служебной программы Sigcheck от Sysinternals. Например: sigcheck –m . При запуске образа, который запрашивает административные права, службе сведений о приложении (известна также как AIS, находится в %SystemRoot%\System32\Appinfo.dll), работающей в процессе Service Host (%SystemRoot%\System32\Svchost.exe), предписывается запустить программу Consent.exe (%SystemRoot%\System32\Consent.exe). Программа Consent создает снимок экрана, применяет к нему эффект затемнения, переключается на рабочий стол, доступный только системной учетной записи, устанавливает затемненный снимок в качестве фона и открывает диалоговое окно повышения прав, содержащее сведения об исполняемом файле. Вывод на отдельном рабочем столе предотвращает изменение этого диалогового окна любой вредоносной программой, работающей под учетной записью пользователя.


Типичная реакция UAC на непонятные действия

Переполнение буфера

Казалось бы, какая связь между переполнением буфера и UAC? Оказывается, таящиеся в Windows баги позволяют обойти ограничения UAC и повысить свои права. Сегодня я покажу на конкретном примере, как при помощи тривиального переполнения буфера можно обойти UAC и добиться администраторских прав.
Есть такая WinAPI — RtlQueryRegistryValues (msdn.microsoft.com), она используется для того, чтобы запрашивать множественные значения из реестра одним своим вызовом, что делается с использованием специальной таблицы RTL_QUERY_REGISTRY_TABLE, которая передается в качестве __in__out параметра.
Самое интересное (и постыдное для разработчиков Microsoft) в этой API то, что существует определенный ключ реестра, который можно изменить при помощи ограниченных пользовательских прав: HKCU\EUDC\[Language]\SystemDefaultEUDCFont. Если сменить тип этого ключа на REG_BINARY, то вызов RtlQueryRegistryValues приведет к переполнению буфера.
Когда ядерная API-функция Win32k.sys!NtGdiEnableEudc запрашивает ключ реестра HKCU\EUDC\[Language]\SystemDefaultEUDCFont, она честно предполагает, что этот ключ реестра имеет тип REG_SZ, так что в буфер передается структура UNICODE_STRING, у которой первое поле является типом ULONG (где представлена длина строки). Но так как мы можем изменить тип этого параметра на REG_BINARY, то систему это ставит в глубокий тупик и она неправильно интерпретирует длину передаваемого буфера, что приводит к переполнению стека.

UINT codepage = GetACP();
TCHAR tmpstr[256];
_stprintf_s(tmpstr, TEXT("EUDC\\%d"), codepage); 
HKEY hKey;
RegCreateKeyEx(HKEY_CURRENT_USER, tmpstr, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | DELETE, NULL, &hKey, NULL);
RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));
RegSetValueEx(hKey, TEXT("SystemDefaultEUDCFont"), 0, REG_BINARY, RegBuf, ExpSize);
__try
{
    EnableEUDC(TRUE);    
}
__except(1)
{
}
RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));
RegCloseKey(hKey);
Ключевой момент эксплойта

Отключение UAC через оснастку

Заключение

Обойти UAC можно. Не скажу, что это легко, ведь разработчики Windows VIsta/W7 постарались на славу, надо отдать им должное. Но все же лазейки остаются. Можно найти одну-две кроличьих дыры, которые способны свести на нет старания команды Windows. Успех в этом случае приходит к тем, кто может работать с отладчиками и дебаггерами типа IDA Pro или WinDBG.
Удачи тебе в твоих стараниях и да пребудет с тобой сила!

image
Журнал Хакер, Июнь (06) 149
Александр Эккерт


Подпишись на «Хакер»
Tags:
Hubs:
+42
Comments 47
Comments Comments 47

Articles

Information

Website
xakep.ru
Registered
Founded
Employees
51–100 employees
Location
Россия