<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; HTA/VBS: Настройка безопасности DCOM и WMI]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7523&amp;type=atom" />
	<updated>2014-01-30T16:24:18Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=7523</id>
		<entry>
			<title type="html"><![CDATA[Re: HTA/VBS: Настройка безопасности DCOM и WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=79551#p79551" />
			<content type="html"><![CDATA[<p>Сегодня попался на глаза этот код, решил <a href="https://github.com/dab00/wmi-dcom-tuner">реанимировать</a>. Всем мир.</p>]]></content>
			<author>
				<name><![CDATA[dab00]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27085</uri>
			</author>
			<updated>2014-01-30T16:24:18Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=79551#p79551</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA/VBS: Настройка безопасности DCOM и WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=63480#p63480" />
			<content type="html"><![CDATA[<p>О чем и спик, что не в домене, а в рабочей группе. Да и речь не обо мне. Гипотетически время от времени надо подключаться к WMI удаленного компа не в домене, а админу в силу каких-нибудь инструкций и т.п. нельзя отключать родной брандмауэр. Понятно, что шансов мало, что такое может случиться, но тем не менее. Что интересно - все по фэн-шую (MSDNу) - и не работает.</p>]]></content>
			<author>
				<name><![CDATA[dab00]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27085</uri>
			</author>
			<updated>2012-09-03T16:58:55Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=63480#p63480</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA/VBS: Настройка безопасности DCOM и WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=63479#p63479" />
			<content type="html"><![CDATA[<p>Ну, у меня для локальной сети фаерволл отключён групповой политикой, так что даже не скажу насчёт его настройки.</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2012-09-03T16:53:18Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=63479#p63479</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[HTA/VBS: Настройка безопасности DCOM и WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=63478#p63478" />
			<content type="html"><![CDATA[<p>Столкнулся с задачей, решение которой, на мой взгляд, заслуживает внимания.<br />Задача: Подключиться к WMI удаленного компьютера под управлением Windows Vista или 7 c включенным UAC в рабочей группе.<br /><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa826699(v=vs.85).aspx">Решение</a>: Настроить разрешения на запуск и активацию DCOM, а также права на необходимые пространства имен WMI.<br />HTA по мотивам задачи:<br /></p><div class="codebox"><pre><code>
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Настройка&lt;/title&gt;
	&lt;!-- Настройка DCOM и WMI --&gt;
	&lt;meta http-equiv=content-type content=&quot;text-html; charset=windows-1251&quot;&gt;
    &lt;meta http-equiv=MSThemeCompatible content=yes&gt;
    &lt;hta:application              
		icon=comres.dll
        scroll=no
		version = &quot;1.0&quot;
    &gt;
&lt;/head&gt;
&lt;style type=&quot;text/css&quot;&gt;
	#usr{width:210px;}
	#ok,#cancel{width:103px;}
	#cancel{margin-left:4px}
	#ns{height:240px; overflow:auto;}
	#st{top: expression(ns.scrollTop)&quot;
&lt;/style&gt;
&lt;script language=&quot;VBScript&quot;&gt;	
	Sub window_onload()
		window.resizeTo 250, 430
		window.moveTo 20, 20
		For Each objNameSpace In GetObject(&quot;winmgmts:\\.\root&quot;).InstancesOf(&quot;__NAMESPACE&quot;)			
			s = s &amp; &quot;&lt;div&gt;&lt;input id=&quot;&quot;&quot; &amp; objNameSpace.Name &amp; &quot;&quot;&quot; type=&quot;&quot;checkbox&quot;&quot;/&gt;&quot; &amp; objNameSpace.Name &amp; &quot;&lt;/div&gt;&quot;
		Next		
		document.getElementById(&quot;ns&quot;).InnerHTML = s
		document.getElementById(&quot;usr&quot;).focus()
	End Sub
	
	Sub cancel_onclick()
		window.close
	End Sub
	
	Sub ok_onclick()
		s = document.getElementById(&quot;usr&quot;).Value
		If s = &quot;&quot; Then
			MsgBox &quot;Имя пользователя не может быть пустым&quot;,vbInformation
			Exit Sub
		End If		
		DACLModify s
	End Sub		
	
	Function DACLModify(sUserName)
		On Error Resume Next		
		Dim bPartOfDomain, sDomainName &#039;имя домена (если не в домене - имя локального компьютера)
		Dim objWinCS, obj
		Dim objWMI		
				
		Set objWMI = GetObject(&quot;winmgmts:\\.\root\cimv2&quot;)
		
		If IsPreVista(objWMI) Then
			MsgBox &quot;Текущая версия операционной системы не поддерживается&quot;,vbExclamation
			Exit Function
		End If
		
		Set objWinCS = objWMI.ExecQuery(&quot;SELECT * FROM Win32_ComputerSystem&quot;)
		For Each obj In objWinCS
			bPartOfDomain = obj.PartOfDomain
			If bPartOfDomain Then
				sDomainName = obj.Domain
			Else
				sDomainName = obj.Name
			End If
		Next
		Set objWinCS = Nothing

		Dim objCollection
		&#039;поиск учетной записи
		If bPartOfDomain Then
			Set objCollection = objWMI.ExecQuery(&quot;SELECT SID FROM Win32_Account WHERE Domain=&#039;&quot; &amp; sDomainName &amp; &quot;&#039; AND Name=&#039;&quot; &amp; sUserName &amp; &quot;&#039;&quot;)
		Else
			Set objCollection = objWMI.ExecQuery(&quot;SELECT SID FROM Win32_Account WHERE Name=&#039;&quot; &amp; sUserName &amp; &quot;&#039;&quot;)
		End If

		If objCollection.Count = 0 Then			
			MsgBox &quot;Учетная запись &quot; &amp; sUserName &amp; &quot; не найдена&quot;,vbInformation
			Exit Function
		End If		
		
		Dim strSID
		&#039;получаем SID
		For Each obj In objCollection
			strSID = UCase(obj.SID)
		Next
		Set objCollection = Nothing
		
		&#039;безопасность DCOM
		If document.getElementById(&quot;dcom&quot;).checked Then
			If DCOM_DACL_Modify(sUserName, sDomainName, strSID) &lt;&gt; 0 Then Exit Function
		End If
		
		&#039;безопасность пространств имен wmi
		For Each n In document.getElementById(&quot;ns&quot;).childNodes			
			If n.childNodes(0).checked Then
				If WMI_DACL_Modify(sUserName, sDomainName, strSID, n.innerText) &lt;&gt; 0 Then Exit Function
			End If
		Next		
		
		If Err.Number = 0 Then
			MsgBox &quot;Настройка безопасности DCOM и WMI завершена&quot;,vbInformation
		Else
			MsgBox &quot;Не удалось настроить безопасность DCOM и WMI&quot;,vbCritical
		End If
		
	End Function
	
	Function DCOM_DACL_Modify(sUserName, sDomainName, strSID)
		On Error Resume Next
		Const HKLM = &amp;H80000002
		Const KeyPath = &quot;SOFTWARE\Microsoft\Ole&quot;
		Const KeyValue = &quot;MachineLaunchRestriction&quot;
		Const KeyEnableValue = &quot;EnableDCOM&quot; &#039;влючено ли использование DCOM
		Dim objReg
		
		DCOM_DACL_Modify = 1 &#039;по умолчанию - ошибка
		
		Set objReg = GetObject(&quot;winmgmts:\\.\root\default:StdRegProv&quot;)		

		&#039;читаем ключ - разрешен ли DCOM
		Dim sEnableValue		
		If objReg.GetStringValue(HKLM, KeyPath, KeyEnableValue, sEnableValue) &lt;&gt; 0 Then
			MsgBox &quot;Не удалось прочитать ключ &quot; &amp; &quot;HKLM\&quot; &amp; KeyPath &amp; &quot;\&quot; &amp; KeyEnableValue,vbCritical
			Exit Function
		End If
		
		If UCase(sEnableValue) &lt;&gt; &quot;Y&quot; Then			
			If objReg.SetStringValue(HKLM, KeyPath, KeyEnableValue, &quot;Y&quot;) &lt;&gt; 0 Then
				MsgBox &quot;Не удалось записать ключ &quot; &amp; &quot;HKLM\&quot; &amp; KeyPath &amp; &quot;\&quot; &amp; KeyEnableValue,vbCritical
				Exit Function
			End If
		End If
		
		&#039;---Права
		&#039;читаем ключ
		Dim arrSD		
		If objReg.GetBinaryValue(HKLM, KeyPath, KeyValue, arrSD) &lt;&gt; 0 Then
			MsgBox &quot;Не удалось прочитать ключ &quot; &amp; KeyPath &amp; &quot;\&quot; &amp; KeyValue,vbCritical
			Exit Function
		End If
		If Not IsArray(arrSD) Then
			MsgBox &quot;Ключ &quot; &amp; &quot;HKLM\&quot; &amp; KeyPath &amp; &quot;\&quot; &amp; KeyValue &amp; &quot; не является массивом&quot;,vbCritical
			Exit Function
		End If

		&#039;конвертируем в Win32_SecurityDescriptor - только Vista и 7
		Dim objWMI, SDHelper
		Set objWMI = GetObject(&quot;winmgmts:\\.\root\cimv2&quot;)
		Set SDHelper = objWMI.Get(&quot;Win32_SecurityDescriptorHelper&quot;)
		Dim objSD		
		If SDHelper.BinarySDToWin32SD(arrSD, objSD) &lt;&gt; 0 Then &#039;BinarySDToSDDL
			MsgBox &quot;Не удалось конвертировать массив в дескриптор безопасности DCOM&quot;,vbCritical
			Exit Function
		End If

		Dim arrACE, objACE
		Dim bFound &#039;флаг - SID найден
		arrACE = objSD.DACL
		&#039;настройка существующих записей
		For Each objACE In arrACE &#039;ищем наш SID
			If StrComp(objACE.Trustee.SIDString, strSID, vbTextCompare) = 0 Then &#039;SID найден
				bFound = True				
				&#039;разрешение на полный доступ
				objACE.AceType = 0
				objACE.AccessMask = &amp;H1F
				Exit For
			End If			
		Next

		&#039;если SID не найден
		If Not bFound Then			
			Dim objSID, objTrustee, objNewACE
			&#039;формируем новый экземпляра класса Win32_Ace
			Set objSID = objWMI.Get(&quot;Win32_SID.SID=&#039;&quot; &amp; strSID &amp; &quot;&#039;&quot;)
			Set objTrustee = objWMI.Get(&quot;Win32_Trustee&quot;).SpawnInstance_()
			objTrustee.Domain = sDomainName &#039;домен или имя локального компа
			objTrustee.Name = sUserName
			objTrustee.SID = objSID.BinaryRepresentation
			objTrustee.SidLength = objSID.SidLength
			objTrustee.SIDString = strSID
			Set objSID = Nothing
			Set objNewACE = objWMI.Get(&quot;Win32_Ace&quot;).SpawnInstance_()
			objNewACE.AceType = 0  &#039;разрешить
			objNewACE.AceFlags = 0
			objNewACE.AccessMask = &amp;H1F &#039;полный доступ
			objNewACE.Trustee = objTrustee			
			Set objTrustee = Nothing
			
			&#039;расширяем DACL
			ReDim Preserve arrACE(UBound(arrACE) + 1)
			Set arrACE(UBound(arrACE)) = objNewACE			
			Set objNewACE = Nothing			
			objSD.DACL = arrACE
			Erase arrACE
		End If
		
		Set objWMI = Nothing
		
		&#039;сохраняем изменения - конвертируем обратно - только Vista и 7
		Dim arrSD2		
		If SDHelper.Win32SDToBinarySD(objSD, arrSD2) &lt;&gt; 0 Then
			MsgBox &quot;Не удалось конвертировать дескриптор безопасности DCOM в массив&quot;,vbCritical
			Exit Function
		End If
		Set SDHelper = Nothing
		
		If Not IsArray(arrSD2) Then
			MsgBox &quot;Конвертирванный дескриптор безопасности DCOM не является массивом&quot;,vbCritical
			Exit Function
		End If				
		
		If objReg.SetBinaryValue(HKLM, KeyPath, KeyValue, arrSD2) &lt;&gt; 0 Then
			MsgBox &quot;Не удалось записать ключ &quot; &amp; &quot;HKLM\&quot; &amp; KeyPath &amp; &quot;\&quot; &amp; KeyValue,vbCritical
			Exit Function
		End If
		Set objReg = Nothing		
		
		DCOM_DACL_Modify = Err.Number
		
	End Function
	
	Function WMI_DACL_Modify(sUserName, sDomainName, strSID, strNameSpace)
		On Error Resume Next
		Dim objSecurity, objNameSpace
		
		WMI_DACL_Modify = 1 &#039;по умолчанию - ошибка
		
		Set objNameSpace = GetObject(&quot;winmgmts:\\.\root\&quot; &amp; strNameSpace)
		Set objSecurity = objNameSpace.Get(&quot;__SystemSecurity=@&quot;)
		
		Dim objSD
		&#039;получаем дескриптор безопасности пространства имен - только Vista и 7
		If objSecurity.GetSecurityDescriptor(objSD) &lt;&gt; 0 Then &#039;если не удалось получить дескриптор безопасности
			MsgBox &quot;Не удалось получить дескриптор безопасности пространства имен &quot;	&amp; strNameSpace,vbCritical
			Exit Function
		End If

		Dim arrACE, objACE
		arrACE = objSD.DACL
		Dim bFound &#039;флаг - SID найден
		&#039;настройка существующих записей
		For Each objACE In arrACE &#039;ищем наш SID
			If StrComp(objACE.Trustee.SIDString, strSID, vbTextCompare) = 0 Then &#039;SID найден
				bFound = True
				&#039;разрешение на полный доступ
				objACE.AceType = 0
				objACE.AccessMask = &amp;H6003F
				Exit For
			End If
		Next

		&#039;если SID не найден
		If Not bFound Then			
			Dim objSID, objTrustee, objNewACE, objWMI
			Set objWMI = GetObject(&quot;winmgmts:\\.\root\cimv2&quot;)
			&#039;формируем новый экземпляра класса Win32_Ace
			Set objSID = objWMI.Get(&quot;Win32_SID.SID=&#039;&quot; &amp; strSID &amp; &quot;&#039;&quot;)
			Set objTrustee = objWMI.Get(&quot;Win32_Trustee&quot;).SpawnInstance_()
			objTrustee.Domain = sDomainName &#039;домен или имя локального компа
			objTrustee.Name = sUserName
			objTrustee.SID = objSID.BinaryRepresentation
			objTrustee.SidLength = objSID.SidLength
			objTrustee.SIDString = strSID
			Set objSID = Nothing
			Set objNewACE = objWMI.Get(&quot;Win32_Ace&quot;).SpawnInstance_()
			Set objWMI = Nothing
			objNewACE.AceType = 0  &#039;разрешить
			objNewACE.AceFlags = 0
			objNewACE.AccessMask = &amp;H6003F &#039;полный доступ
			objNewACE.Trustee = objTrustee			
			Set objTrustee = Nothing
			
			&#039;расширяем DACL
			ReDim Preserve arrACE(UBound(arrACE) + 1)
			Set arrACE(UBound(arrACE)) = objNewACE			
			Set objNewACE = Nothing			
			objSD.DACL = arrACE
			Erase arrACE
		End If

		&#039;сохраняем изменения настроек безопасности пространства имен - только Vista и 7
		If objSecurity.SetSecurityDescriptor(objSD) &lt;&gt; 0 Then
			MsgBox &quot;Не удалось сохранить изменения в настройке безопасности пространства имен &quot; &amp; strNameSpace,vbCritical
			Exit Function
		End If
		
		Set objSecurity = Nothing
		Set objNameSpace = Nothing
		
		WMI_DACL_Modify = Err.Number
		
	End Function
		
	Function IsPreVista(objWMI)
		On Error Resume Next
		Dim obj
		For Each obj In objWMI.ExecQuery(&quot;Select * From Win32_OperatingSystem&quot;)
			If CInt(Left(obj.Version, 1)) = 5 Then &#039;XP или ранее
				IsPreVista = True
			End If
		Next
	End Function
&lt;/script&gt;
&lt;body&gt;	
	Имя пользователя: &lt;br/&gt;&lt;input id=&quot;usr&quot; type=&quot;text&quot;/&gt;&lt;br/&gt;
	&lt;input id=&quot;dcom&quot; type=&quot;checkbox&quot;/&gt;DCOM&lt;br/&gt;	
	&lt;div id=&quot;st&quot;&gt;Пространства имен WMI:&lt;/div&gt;
	&lt;div id=&quot;ns&quot;&gt;&lt;/div&gt;&lt;br/&gt;
	&lt;input id=&quot;ok&quot; type=&quot;button&quot; value=&quot;OK&quot;/&gt;&lt;input id=&quot;cancel&quot; type=&quot;button&quot; value=&quot;Отмена&quot;/&gt;	
&lt;/body&gt; 
&lt;/html&gt;</code></pre></div><p>Запуск, разумеется, от имени администратора:<br /></p><div class="codebox"><pre><code>
With CreateObject(&quot;Scripting.FileSystemObject&quot;)
	f = .BuildPath(.GetParentFolderName(WScript.ScriptFullName),&quot;DCOM&#039;n&#039;WMI_Access_Rights_Adjustment.hta&quot;)
	If .FileExists(f) Then
		CreateObject(&quot;Shell.Application&quot;).ShellExecute &quot;mshta.exe&quot;, Chr(34) &amp; f &amp; Chr(34),, &quot;runas&quot;,1
	Else
		MsgBox &quot;Файл &quot; &amp; f &amp; &quot; не найден&quot;,vbExclamation
	End If
End With</code></pre></div><p>Наверное на форуме кому-нибудь будет полезно.</p><p>p.s.: Настройка Брандмауэра Windows согласно MSDN ни <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa389286(v=vs.85).aspx">для XP</a>, ни <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa822854(v=vs.85).aspx">для Vista/7</a> по моим наблюдениям не помогает - ни netsh, ни скриптом, ни руками - только отключение. Хотелось бы знать, только у меня лыжи не едут?</p>]]></content>
			<author>
				<name><![CDATA[dab00]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27085</uri>
			</author>
			<updated>2012-09-03T16:49:22Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=63478#p63478</id>
		</entry>
</feed>
