Олицетворение позволяет серверу уведомить SRM о временном заимствовании профиля защиты клиента, запрашивающего ресурс. После этого сервер может обращаться к ресурсам от имени клиента, a SRM — проводить проверку его прав доступа. Обычно серверу доступен более широкий круг ресурсов, чем клиенту, и при олицетворении сервер может терять часть исходных прав доступа. Также вероятно и обратное: при олицетворении сервер может получить дополнительные права.
Сервер олицетворяет клиент лишь в пределах потока, выдавшего запрос на олицетворение. Управляющие структуры данных потока содержат необязательный элемент для маркера доступа. Однако основной маркер потока, отражающий его реальные права, всегда доступен через управляющие структуры процесса.
За поддержку олицетворения в Windows отвечает несколько механизмов. Если сервер взаимодействует с клиентом через именованный канал, он может вызвать Windows-функцию ImpersonateNamedPipeClient и тем самым сообщить SRM о том, что ему нужно подменить собой пользователя на другом конце канала. Если сервер взаимодействует с клиентом через DDE (Dynamic Data Exchange) или RPC, то выдает аналогичный запрос на олицетворение через DdeImpersonateClient или RpcImpersonateClient. Поток может создать маркер олицетворения просто как копию маркера своего процесса, вызвав функцию ImpersonateSelf. Для блокировки каких-то SID или привилегий поток может потом изменить полученный маркер олицетворения. Наконец, пакет SSPI (Security Support Provider Interface) может олицетворять своих клиентов через ImpersonateSecurityContext. SSPI реализует модель сетевой защиты вроде LAN Manager версии 2 или Kerberos.
После того как серверный поток завершает выполнение своей задачи, он возвращает себе прежний профиль защиты. Эти формы олицетворения удобны для выполнения определенных операций по запросу клиента и для корректного аудита обращений к объектам. (Например, генерируемые данные аудита сообщают идентификацию подменяемого клиента, а не серверного процесса.) Их недостаток в том, что нельзя выполнять всю программу в контексте клиента. Кроме того, маркер олицетворения не дает доступа к сетевым файлам или принтерам, если только они не поддерживают null-сеансы или не используется олицетворение уровня делегирования (delegation-level impersonation), причем удостоверения защиты достаточны для аутентификации на удаленном компьютере. (Null-сеанс создается при анонимном входе.)
Если все приложение должно выполняться в контексте защиты клиента или получать доступ к сетевым ресурсам, клиент должен быть зарегистрирован в системе. Для этого предназначена Windows-функция LogonUser, которая принимает в качестве параметров имя учетной записи, пароль, имя домена или компьютера, тип входа (интерактивный, пакетный или сервисный) и провайдер входа (logon provider), а возвращает основной маркер. Серверный поток принимает маркер в виде маркера олицетворения, либо сервер запускает программу, основной маркер которой включает удостоверения клиента. C точки зрения защиты, процесс, создаваемый с применением маркера, который возвращается при интерактивном входе через Logon-User, например API-функцией CreateProcessAsUser, выглядит как программа, запущенная пользователем при интерактивном входе в систему. Недостаток этого подхода в том, что серверу приходится получать имя и пароль по учетной записи пользователя. Если сервер передает эту информацию по сети, он должен надежно шифровать ее, чтобы избежать получения имени и пароля злоумышленником, перехватывающим сетевой трафик.
Windows не позволяет серверам подменять клиенты без их ведома. Клиентский процесс может ограничить уровень олицетворения серверным процессом, сообщив при соединении с ним требуемый SQOS (Security Quality of Service). Процесс может указывать флаги SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITYIMPERSONATION и SECURITYDELEGATION при вызове Windows-функции CreateFile. Каждый уровень позволяет серверу выполнять различный набор операций относительно контекста защиты клиента:
• SecurityAnonymous — самый ограниченный уровень; сервер не может олицетворять или идентифицировать клиент;
• SecurityIdentification — сервер может получать SID и привилегии клиента, но не получает право на олицетворение клиента;
• SecurityImpersonation — сервер может идентифицировать и олицетворять клиент в локальной системе;
• SecurityDelegation — наименее ограниченный уровень. Позволяет серверу олицетворять клиент в локальных и удаленных системах. Windows NT 4 и более ранние версии лишь частично поддерживают этот уровень олицетворения.
Если клиент не устанавливает уровень олицетворения, Windows по умолчанию выбирает SecurityImpersonation. Функция CreateFile также принимает модификаторы SECURITY_EFFECTIVE_ONLY и SECURITY_CONTEXT_TRACKING.
Первый из них не дает серверу включать/выключать какие-то привилегии или группы клиента на время олицетворения. A второй указывает, что все изменения, вносимые клиентом в свой контекст защиты, отражаются и на сервере, который олицетворяет этот клиент. Данный модификатор действует, только если клиентский и серверный процессы находятся в одной системе.
Ограниченные маркеры
Ограниченный маркер (restricted token) создается на базе основного или олицетворяющего с помощью функции CreateRestrictedToken и является его копией, в которую можно внести следующие изменения:
• удалить некоторые элементы из таблицы привилегий маркера;
• пометить SID-идентификаторы маркера атрибутом проверки только на запрет (deny-only);
• пометить SID-идентификаторы маркера как ограниченные.
Поведение SID с атрибутом проверки только на запрет (deny-only SID) и ограниченных SID (restricted SID) кратко поясняется в следующих разделах. Ограниченные маркеры удобны, когда приложение подменяет клиент при выполнении небезопасного кода. B ограниченном маркере может, например, отсутствовать привилегия на перезагрузку системы, что не позволит коду, выполняемому в контексте защиты ограниченного маркера, перезагрузить систему.
ЭКСПЕРИМЕНТ: просмотр ограниченных маркеров
B Windows XP или Windows Server 2003 можно заставить Explorer создать процесс с ограниченным маркером по следующей процедуре.
1. Создайте на рабочем столе ярлык для \Windows\Notepad.exe.
2. Отредактируйте свойства ярлыка и установите флажок Run With Different Credentials (Запускать с другими учетными данными). Заметьте: в описании под этим флажком говорится о том, что вы можете запускать программу от своего имени, в то же время защищая компьютер от несанкционированных действий данной программы*.
3. Закройте окно свойств и запустите программу двойным щелчком ее ярлыка.
4. Согласитесь с параметрами по умолчанию для выполнения под текущей учетной записью и защиты компьютера от несанкционированных действий этой программы.
5. Запустите Process Explorer и просмотрите содержимое вкладки Security для свойств запущенного вами процесса Notepad. Заметьте, что маркер содержит ограниченные SID и SID с атрибутом проверки только на запрет, а также что у него лишь одна привилегия. Свойства в левой части окна, показанного на следующей иллюстрации, относятся к Notepad, выполняемому с неограниченным маркером, а свойства в правой части окна — к его экземпляру, запущенному по описанной процедуре.
* B русской версии Windows XP ошибочно говорится о защите от несанкционированных действий других программ. — Прим. перев.
Ограниченный маркер дает несколько побочных эффектов.
• Удаляются все привилегии, кроме SeChangeNotifyPrivilege.
• Любые SID администраторов или пользователей с правами администраторов помечаются как Deny-Only (проверка только на запрет). Такой SID удаляет права доступа к любым ресурсам, доступ к которым для администраторов запрещен соответствующим АСЕ, но в ином случае был бы замещен АСЕ, ранее выданным группе администраторов через дескриптор защиты.