К ним относятся три перечисленные ниже изменения:

  • В Windows 2003 появился механизм блокировки (lockdown), обеспечивающий безопасное выполнение асинхронных операций WMI.
  • В Windows 2003 нельзя присвоить нулевое (Null) значение Дескриптору безопасности (Security Descriptor (SD)) в стандартной информационной модели (Common Information Model (CIM)).
  • В Windows 2003 удалено расширение Active Directory Service Interfaces (ADSI)-WMI.

Механизмы блокировки для асинхронных сценариев

Асинхронный сценарий WMI содержит основное тело и вызываемые процедуры, которые выполняются параллельно (т.е. асинхронно) основному сценарию. Процедуры выполняют через WMI некоторые операции, такие как остановка служб Windows или обработка событий, генерируемых в ходе выполнения основного сценария. Новый механизм блокировки гарантирует, что обратный вызов асинхронной процедуры будет поступать от авторизованного источника.

В общем случае, когда клиентское приложение WMI выполняет асинхронную операцию или обработку события, то сначала оно обращается к процессу winmgmt.exe. Данное соединение обрабатывается на уровне COM, что осуществляется вызовом метода ConnectServer, предоставляемого объектом WbemScripting.SWbemLocator. Как видно из Рисунка 1 (цифра 1), на данном шаге клиент WMI обрабатывает указатель на winmgmt.exe, в результате чего, когда выполняется некоторое действие или происходит событие, процесс WMI вызывает реализованную в клиенте процедуру (вызов процедуры соответствует цифре 2 на Рисунке 1). В клиенте WMI имеется несколько параметров безопасности (таких как тип заимствования прав (impersonation type) и уровень аутентификации (authentication level)), к которым процесс winmgmt.exe при необходимости обращается. Как можно видеть из Рисунка 1 (цифра 2), процесс WMI всегда пытается выполнить на клиенте обратный вызов процедуры с тем же уровнем аутентификации.

  

Однако управление уровнем безопасности невозможно в тех случаях, когда клиент является сценарием WMI либо оснасткой Microsoft Management Console (MMC) (когда клиенту не хватает функциональности для контроля параметров безопасности процесса), а также в сетевой инфраструктуре, более ранней, чем Windows 2000 (поскольку в этой среде учетная запись Local System не может быть идентифицирована в сети). В подобных случаях, когда клиенту WMI нужно выполнить асинхронную операцию, лежащий ниже механизм вызывает на клиенте в качестве отдельного процесса приложение unsecapp.exe (см. цифру 1 на Рисунке 2). Подобным образом работают все версии Windows.

Приложение Unsecapp.exe передает клиенту свой указатель. Затем нижележащие механизмы WMI COM при обращении к winmgmt.exe передают этому процессу указатель на Unsecapp.exe вместе с вызовом асинхронной процедуры сценария WMI (цифра 2, Рисунок 2). При выполнении обратного вызова winmgmt.exe обращается к unsecapp.exe (цифра 3, Рисунок 2). Поскольку сценарий WMI, в отличие от клиента COM/DCOM WMI, не может выполнять обратный вызов в безопасном режиме, то unsecapp.exe допускает обратные вызовы из любого места. Разумеется, с точки зрения безопасности использование unsecapp.exe сопряжено с определенным риском, поскольку при этом любой процесс может выполнить обратный вызов от имени winmgmt.exe. После приема обратного вызова unsecapp.exe возвращает его сценарию WMI на уровень асинхронно выполняемой процедуры (см. цифру 4 на Рисунке 2). Следует подчеркнуть, что компонент unsecapp.exe задействуется только в ходе выполнения асинхронных операций. Для синхронных и полусинхронных (semisynchronous) операций используется другой механизм. Более подробно отличия между этими типами операций описаны в статьях MSDN "Making an Asynchronous Call with VBScript" и "Making a Semisynchronous Call with VBScript".

Механизмы блокировки сценариев в Windows XP, Windows 2000 и Windows NT 4.0. В системе Windows 2003 разработчики Microsoft реализовали механизм блокировки для unsecapp.exe, но на момент написания данной статьи компания не планировала встраивать аналогичные механизмы в более ранние версии Windows. Поэтому если вы хотите использовать асинхронные операции или уведомления о событиях в сценариях WMI на платформах Windows XP, Windows 2000 и Windows NT4.0, то следует принимать следующие меры предосторожности:

  • По возможности используйте в сценариях не асинхронную, а полусинхронную технологию.
  • В тех случаях, когда использование в сценарии асинхронной технологии является необходимым, при выполнении критичных операций (таких как выключение системы) избегайте использования контекста безопасности с высшим уровнем полномочий (т.е. административного) в процедурах, обрабатывающих асинхронные обратные вызовы. В принципе, всегда, когда это возможно, следует избегать выполнения сценариев в контексте безопасности с административными полномочиями, но будьте особенно аккуратны с асинхронными сценариями. При использовании асинхронных операций следует предусматривать в клиентском коде проверку прав доступа.

Безусловно, использование асинхронных сценариев несет в себе потенциальную опасность, однако угроза безопасности имеет место только во время работы приложения, выполняющего операции или обрабатывающего события в асинхронном режиме. Также следует учитывать, что степень угрозы пропорциональна уровню полномочий контекста выполнения сценария и типу операции, выполняемой процедурой.

Механизмы блокировки сценариев в Windows 2003. В системе Windows 2003 компания Microsoft реализовала для unsecapp.exe оболочку (wrapper), выполняющую функцию посредника безопасности (security broker) между клиентом WMI и процессом winmgmt.exe, который осуществляет проверку правомочности обратных вызовов, выполняемых через соответствующий интерфейс unsecapp.exe. Для обеспечения обратной совместимости с асинхронными приложениями WMI предыдущих версий данная оболочка по умолчанию отключена, но приложения WMI COM/DCOM могут при необходимости включать или отключать данную оболочку. Таким образом, некоторому клиентскому приложению WMI можно предписать (путем включения оболочки) использование механизма аутентификации обратных вызовов, в то время как все остальные программы будут использовать установку по умолчанию для Everyone (с отключенной оболочкой).

Тем не менее, сценарии WMI могут сами включать и отключать данную оболочку, так что в данном случае вы не можете обязать сценарий активировать оболочку. Для того чтобы принудительно включить оболочку и заставить unsecapp.exe принимать только аутентифицированные вызовы нужно изменить значение соответствующего параметра реестра. Необходимо удостовериться, что данная установка является глобальной для всех приложений и сценариев. Чтобы включить аутентификацию вызовов измените с 0 (анонимные вызовы разрешены) на 1 значение параметра UnsecappAccessControlDefault в разделе реестра HKEY_LOCAL_MACHINESOFTWAREMicrosoftWBEMCIMOM.

После активации оболочки она будет перехватывать все обратные вызовы unsecapp.exe с целью идентификации компонента, выполнившего вызов. Как показано на Рисунке 3, когда клиентский сценарий пытается обратиться к winmgmt.exe для выполнения асинхронной операции (цифра 2), оболочка извлекает из маркера безопасности идентификатор SID клиента (цифра 1). Когда winmgmt.exe выполняет обратный вызов unsecapp.exe (Рисунок 3, цифра 3), оболочка перехватывает его и извлекает SID компонента, выполнившего этот вызов. В ходе извлечения SID неявно производится обращение к службе Active Directory (AD), которая проверяет существование SID источника вызова (Рисунок 3, цифра 4). Следующим шагом выполняется сравнение SID источника вызова и SID клиента (Рисунок 3, цифра 5). Если эти значения совпадают, то unsecapp.exe выполняет обратный вызов клиентского сценария (Рисунок 3, цифра 6). Если же значения SID различаются, то в этом случае unsecapp.exe не передает обратный вызов клиентской процедуре.

Изменение параметра реестра, активирующего оболочку, влияет на работу асинхронных приложений и сценариев только в тех сетевых средах, где имеются компьютеры с операционной системой версии более ранней, чем Windows 2000. Типичным примером данной ситуации может служить запуск приложения (или сценария) WMI на одном из серверов Windows 2003 (с активированным механизмом блокировки), которое обращается через WMI к удаленному серверу Windows NT4.0 с целью получения некоторой информации. Напомню, что в сетях Windows 2000 и выше учетная запись Local System может идентифицироваться аналогично пользовательским учетным записям, поэтому службы Windows могут запускаться не только в контексте безопасности определенного доменного пользователя, но также и в контексте учетной записи компьютера. Что касается версий, предшествующих Windows 2000, то здесь учетная запись Local System имеет только локальный статус и не распознается в домене. Соответственно, в сети она не имеет никаких полномочий и поэтому не может быть идентифицирована рассматриваемой оболочкой.

Запрет использования нулевого (Null) дескриптора безопасности (SD) в пространстве имен репозитария CIM (CIM Repository)

Пространство имен репозитария CIM содержит некоторый набор классов, относящихся к заданному пространству управления (management area) (например, для AD это будет RootDirectoryLDAP, для SNMP – RootSNMP, а для Microsoft IIS – RootMicrosoftIISv2). Каждое пространство имен имеет свой дескриптор SD, который описывает настройки параметров безопасности для данного пространства имен. По умолчанию пространство имен в момент его создания наследует эти настройки безопасности от родительского пространства. Значение SD (а, следовательно, и эти настройки) можно изменять с помощью метода SetSD системного класса __SystemSecurity. Более подробное описание класса __SystemSecurity и имеющихся у него методов содержится в статье Microsoft "__SystemSecurity" по адресу: http://msdn.microsoft.com/library/en-us/wmisdk/wmi/_systemsecurity.asp.

В Windows 2003 значение SD пространства имен репозитария CIM не может быть установлено в Null. В предыдущих версиях Windows, если в дочернем пространстве имен для SD было задано значение Null, то оно наследовало значение SD от родительского пространства (поскольку если SD установлен в Null, то его флаг блокировки наследования (inheritance-blocking) имеет значение 0, что соответствует включенному состоянию механизма наследования). Путем исключения возможности установки нулевого SD, Microsoft решила не допускать сознательное удаление SD пространства имен. Таким образом, теперь при получении доступа к дочернему пространству имен приложение не может изменить его настройки параметров безопасности на значения этих параметров из родительского пространства.

Исключение расширения ADSI-WMI

С помощью расширения ADSI-WMI из компьютерного объекта ADSI можно извлекать некоторую информацию WMI. Данное расширение имеется в системах Windows XP, Windows 2000 и Windows NT 4.0. Однако из системы Windows 2003 компания Microsoft решила убрать это расширение, что объясняется следующими двумя причинами:

  • Концепция "Trustworthy Computing" предполагает, что для уменьшения количества вероятных путей атак в системе должны быть активированы только те ее компоненты, которые необходимы для работы. По мнению Microsoft расширение ADSI-WMI относится к числу редко используемых компонентов, однако вы вполне можете оказаться одним из тех немногих, кому он действительно нужен.
  • Само по себе данное расширение не является непосредственным источником какой-либо конкретной угрозы безопасности, однако для его работы необходим высокий уровень привилегий в системе.

Из сценария, содержащегося в Листинге 1, видно, какие данные могут быть получены с уровня WMI объекта ADSI, соответствующего компьютеру с более ранней версией операционной системы, чем Windows 2003. Требуется только указать имя компьютера в формате LDAP (Lightweight Directory Access Protocol). Как видно из фрагмента с меткой A Листинга 1, сценарий извлекает объект ADSI, соответствующий заданному компьютеру. Далее сценарий обращается к созданному объекту ADSI и с помощью свойства WMIObjectPath расширения ADSI-WMI получает информацию о пути к объекту WMI, отображаемому данным объектом ADSI (см. фрагмент с меткой B Листинга 1). В этом случае путь к объекту WMI включает в себя моникер:

WINMGMTS: {impersonationLevel=impersonate} !//W2K-EVO500A/root/cimv2: Win32_ComputerSystem.Name= 'W2K-EVO500A' 

Далее этот путь к объекту WMI можно использовать для обращения к объекту Win32_ComputerSystem, отображаемому компьютерным объектом ADSI.

На Листинге 1 во фрагменте с меткой C показан альтернативный способ быстрого обращения к объекту Win32_ComputerSystem, заключающийся в использовании метода GetWMIObject расширения ADSI-WMI. Данный метод в неявном виде использует путь к объекту WMI.

И аналогично, вместо того, чтобы извлекать данные из экземпляра объекта Win32_ComputerSystem вы можете установить WMI-соединение с тем компьютером, которому соответствует данный объект ADSI. Далее можно создать экземпляр любого из классов в пространстве Root/CIMv2 репозитария CIM путем вызова метода GetWMIServices, который возвращает объект SWbemServices (см. фрагмент с меткой D на Листинге 1). Более подробная информация по объекту SWbemServices содержится в статье Microsoft " SWbemServices", адрес: http://msdn.microsoft.com/library/en-us/wmisdk/wmi/swbemservices.asp.

Если на компьютере установлена Windows 2003, где расширение ADSI-WMI отсутствует, то получить путь к объекту WMI непосредственно из объекта ADSI нельзя. В этом случае необходимо сначала создать моникер WMI, поскольку теперь объект ADSI его более не предоставляет. Для построения моникера (см. фрагмент с меткой A в Листинге 2) нужно обратиться к ADSI и получить DNS имя хоста (DNS host name) и имя компьютера (computer host name). Как показано на Листинге 2 (фрагмент с меткой B), имея эти два имени можно построить моникер WMI, который требуется функции GetObject для обращения к объекту WMI. Далее этот моникер можно использовать для извлечения и отображения информации о пути к объекту WMI (см. фрагмент с меткой C в Листинге 2).

Как и в случае извлечения данных о пути к объекту WMI, для получения ссылки на объект Win32_ComputerSystem аналогичным образом строится моникер с использованием имени DNS и имени компьютера. После этого (см. фрагмент с меткой D на Листинге 2) созданный моникер точно так же используется функцией GetObject для того, чтобы получить объект Win32_ComputerSystem. Затем можно отобразить значения всех свойств объекта Win32_ComputerSystem, что иллюстрирует код с меткой E Листинга 2.

Процедура подключения к объекту WMI несколько отличается, хотя здесь применяются те же самые базовые принципы. Чтобы подключиться к какому-либо классу объекта репозитория Root/CIMv2, необходимо создать объект пространства имен WMI. Из фрагмента с меткой E Листинга 2 видно, что путь к объекту пространства имен WMI состоит из DNS имени компьютера, с которым нужно установить соединение через WMI, и пространства имен Root/CIMv2. После того как соединение установлено, можно обращаться к любому из классов пространства имен Root/CIMv2, в частности, к классу Win32_Service.

После того как WMI-соединение было установлено, можно использовать свойство __PATH объекта Win32_ComputerSystem и получить то же самое значение пути к объекту WMI, которое извлекает код, обозначенный меткой С. Учтите, что в системах Windows 2003 и Windows XP для извлечения свойства __PATH предлагается альтернативное свойство, которое называется SystemProperties_. В более ранние версиях Windows для этого необходимо использовать технику кодирования, аналогичную той, которая показана на Листинге 2 во фрагменте с меткой C. Для чего может потребоваться вновь извлекать значение пути? Его можно использовать для получения информации о путях к другим объектам, связанным с Win32_Computer, таким как Win32_Service или Win32_Processor. Эти связи можно просматривать с помощью WMI CIM Studio – программным средством, которое можно загрузить со страницы WMI Administrative Tools по адресу: http://www.microsoft.com/downloads/details.aspx?familyid=6430f853-1120-48db-8cc5-f2abdc3ed314&displaylang=en.

При проектировании Windows 2003 учитывалось множество факторов, и одним из наиболее важных требований была безопасность. Технология WMI является важным компонентом, лежащим в основе управления компьютерами на платформе Windows. С помощью данной технологии можно выполнять множество критичных действий, таких как выключение системы или изменение ее конфигурации, поэтому обеспечение безопасности при работе с WMI является очень важным вопросом. С появлением инициативы Trustworthy Computing в WMI был внесен ряд изменений, касающихся как администраторов, так и разработчиков. Таким образом, переход на Windows 2003 приводит к необходимости провести тщательный анализ ранее разработанных сценариев и методик работы с возможным внесением в них соответствующих изменений.


Листинг 1. Получение информации через расширение ADSI-WMI
' Begin callout A
Set objComputer = GetObject("LDAP://CN=NET-EVO500,” & _
  “OU=Domain Controllers,DC=LissWare,DC=NET")
' End callout A
 
BEGIN COMMENT
'Извлечение данных о пути к объекту WMI через расширение WMI-ADSI.
END COMMENT
' Begin callout B
WScript.Echo objComputer.WMIObjectPath
' End callout B
 
BEGIN COMMENT
'Доступ к объекту Win32_ComputerSystem через расширение WMI-ADSI
' object.
END COMMENT
' Begin callout C
Set objWMIInstance = objComputer.GetWMIObject
' End callout C
  DisplayInstanceProperties (objWMIInstance)
 
BEGIN COMMENT
'С помощью данного расширения WMI-ADSI устанавливается WMI-соединение
' с компьютером, отображаемым объектом ADSI.
END COMMENT
' Begin callout D
Set objWMIServices = objComputer.GetWMIServices
' End callout D
Set objWMIInstances = _
  objWMIServices.InstancesOf ("Win32_Service")
For Each objWMIInstance in objWMIInstances
  DisplayInstanceProperties (objWMIInstance)
Next
Листинг 2. Получение аналогичной информации без использования расширения ADSI-WMI.
Set objComputer = GetObject("LDAP://CN=NET-EVO500," & _
  "OU=Domain Controllers,DC=LissWare,DC=NET")
' Begin callout A
strDNSHostName = objComputer.Get ("dNSHostName")
strHostName = objComputer.Get ("name")
' End callout A
 
BEGIN COMMENT
'Формирование моникера WMI и получение данных о пути к объекту WMI.
END COMMENT
' Begin callout B
Set objWMIInstance = GetObject("winmgmts:" & _
  "{impersonationLevel=impersonate}!//" & _
  strDNSHostName & _
  "/Root/CIMv2:Win32_ComputerSystem.Name='" & _
  strHostName & "'")
' End callout B
' Begin callout C
WScript.Echo objWMIInstance.Path_.Path
' End callout C
 
BEGIN COMMENT
'Обращение к объекту Win32_ComputerSystem.
END COMMENT
' Begin callout D
Set objWMIInstance = GetObject("winmgmts:" & _
  "{impersonationLevel=impersonate}!//" & _
  strDNSHostName & _
  "/Root/CIMv2:Win32_ComputerSystem.Name='" & _
   strHostName & "'")
' End callout D
' Begin callout E
DisplayInstanceProperties (objWMIInstance)
' End callout E
 
BEGIN COMMENT
'Установка WMI-соединения с компьютером, отображаемым объектом ADSI.
END COMMENT
' Begin callout F
Set objWMIServices = GetObject("winmgmts:" & _
  "{impersonationLevel=impersonate}!//" & _
  strDNSHostName & _
  "/Root/CIMv2")
' End callout F
Set objWMIInstances = _
  objWMIServices.InstancesOf ("Win32_Service")
For Each objWMIInstance in objWMIInstances
  DisplayInstanceProperties (objWMIInstance)
Next