Informační zpravodaj zabezpečení společnosti Microsoft: Chyba zabezpečení serveru SQL Server by mohla umožnit vzdálené spuštění kódu

ÚVOD

Společnost Microsoft vydala informační zpravodaj zabezpečení k chybě zabezpečení serveru Microsoft SQL Server, která by mohla umožnit vzdálené spuštění kódu. Tento informační zpravodaj zabezpečení obsahuje dodatečné informace týkající se zabezpečení. Chcete-li zobrazit celý obsah tohoto zpravodaje, navštivte následující web společnosti Microsoft: Tento článek obsahuje skript jazyka Visual Basic, který lze použít jako alternativní řešení pro všechny spuštěné instance serveru SQL Server v místním počítači.

UKÁZKA SKRIPTU JAZYKA VISUAL BASIC, KTERÝ LZE POUŽÍT JAKO ALTERNATIVNÍ ŘEŠENÍ

Tento skript jazyka Visual Basic lze použít u role Public k odepření oprávnění pro spouštění rozšířené uložené procedury sp_replwritetovarbin ve všech ovlivněných verzích serveru SQL Server, které jsou spuštěny v místním počítači.

Společnost Microsoft poskytuje ukázky programování pouze pro ilustraci, bez žádné záruky výslovně uvedené nebo odvozené, včetně, bez omezení, odvozených záruk vztahujících se k obchodovatelnosti nebo vhodnosti pro určitý účel. Tento článek předpokládá, že uživatel je obeznámen s programovacím jazykem, který je předmětem ukázky, a s nástroji použitými pro vytvoření a ladění skriptu. Pracovníci technické podpory společnosti Microsoft mohou vysvětlit funkce určité procedury, nemohou však následující příklady rozšířit o další funkce nebo vytvářet procedury podle konkrétních požadavků uživatele.


Zkopírujte tento kód do textového souboru, uložte jej s příponou souboru VBS a pak soubor skriptu spusťte pomocí programu CScript.exe. Skript projde všechny spuštěné instance serveru SQL Server v místním počítači a pro ovlivněné verze použije alternativní řešení. Aby bylo možné alternativní řešení použít, je třeba být pro každou instanci serveru SQL Server členem role správce systému. Pokud nemáte účet systému Windows, který by byl členem role správce systému pro všechny ovlivněné servery se spuštěnými servery SQL Server, může být nutné spustit tento skript z více účtů. Pokud v systémech Windows Server 2008 a Windows Vista používáte účet správce systému Windows, který je členem role správce systému, je třeba spustit tento skript v příkazovém řádku s vyššími oprávněními.
'*************************************************************************************
'Popis: Tento skript prochází všechny spuštěné instance serveru SQL Server
' a odpírá roli Public oprávnění pro spuštění procedury sp_replwritetovarbin pro všechny
' ovlivněné verze.
' TENTO SKRIPT SLOUŽÍ JAKO ALTERNATIVNÍ ŘEŠENÍ A NEMĚL BY BÝT POUŽÍVÁN V PŘÍPADĚ, ŽE
' BYLA VYDÁNA A INSTALOVÁNA AKTUALIZACE ZABEZPEČENÍ.
'*************************************************************************************

OPTION EXPLICIT
ON ERROR RESUME NEXT

' Konstanty
CONST EXIT_SUCCESS = 0
CONST EXIT_FAILURE = 1
CONST EXIT_NOINSTANCES = -1
CONST DEFAULTNAMESPACE = "root\default"
CONST STDREGPROV = "stdregprov"
CONST HKEY_LOCAL_MACHINE = &H80000002
CONST REG_MULTI_SZ = 7
CONST REG_SZ = 1
CONST adCmdText = 1


Call VBMain()

Function VBMain()
Err.Clear
ON ERROR RESUME NEXT

Dim sInstances(), strInstance, i, TotalCount
VBMain = EXIT_SUCCESS
If GetInstances(sInstances, TotalCount) = FALSE Then
WScript.Quit EXIT_FAILURE
End If

If IsEmptyNull(sInstances) Then
WScript.Echo "INFORMACE: Nejsou přítomny žádné instance."
VBMain = EXIT_NOINSTANCES
Exit Function
End If

For i = 0 To TotalCount-1
strInstance = sInstances(i,0)
GetFullInstance strInstance, sInstances(i,1)
If ApplyFix(sInstances(i,0), strInstance) = FALSE Then
wscript.echo "CHYBA: Alternativní řešení nelze použít pro instanci " + sInstances(i,0) + "." + vbCRLF
VBMain = EXIT_FAILURE
End If
Next

WScript.Echo "INFORMACE: Byly zpracovány všechny spuštěné instance SQL."
End Function

Function GetInstances(ByRef sInstances, ByRef TotalCount)
Err.Clear
ON ERROR RESUME NEXT

Dim sInstances1, sInstances2, i
Dim instCount1, instCount2
GetInstances = FALSE

If NOT GetRegValue ("", HKEY_LOCAL_MACHINE, "Software\Microsoft\Microsoft SQL Server", "InstalledInstances", sInstances1, REG_MULTI_SZ, TRUE) Then
WScript.Echo "CHYBA: Čtení instancí SQL v tomto počítači se nezdařilo."
Exit Function
End If

sInstances2 = NULL
If IsOs64Bit() = TRUE Then
If NOT GetRegValue ("", HKEY_LOCAL_MACHINE, "Software\Microsoft\Microsoft SQL Server", "InstalledInstances", sInstances2, REG_MULTI_SZ, FALSE) Then
WScript.Echo "CHYBA: Čtení instancí SQL v tomto počítači se nezdařilo."
Exit Function
End If
End If

If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then
WScript.Echo "INFORMACE: Nejsou přítomny žádné instance."
WScript.Quit EXIT_SUCCESS
End If

instCount1 = 0
instCount2 = 0
TotalCount = 0
If IsEmptyNull(sInstances1) = FALSE Then
instCount1 = UBound(sInstances1) + 1
TotalCount = instCount1
End If

If IsEmptyNull(sInstances2) = FALSE Then
instCount2 = UBound(sInstances2) + 1
TotalCount = TotalCount + instCount2
End If

ReDim PRESERVE sInstances(TotalCount,1)
if instCount1 > 0 Then
For i = 0 To UBound(sInstances1)
sInstances(i,0) = sInstances1(i)
sInstances(i,1) = True
Next
End If
If instCount2 >0 Then
For i = 0 To UBound(sInstances2)
sInstances(i+instCount1,0) = sInstances2(i)
sInstances(i+instCount1,1) = FALSE
Next
End If
GetInstances = TRUE
End Function


Function ApplyFix(ByVal strInstance, ByVal strServerName)
Err.Clear
ON ERROR RESUME NEXT

Dim objConn, objCmd, objCmd1, objRS, objRS1
Dim strCommand, strConn
Dim strBuildVersion, strProductLevel, bApplyFix

' Inicializace návratové hodnoty
ApplyFix = FALSE

strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";"
' Kvůli zkrácení kódu je kontrola chyb záměrně vynechána
Set objConn = CreateObject("ADODB.Connection")
Set objCmd = CreateObject("ADODB.Command")
Set objCmd1 = CreateObject("ADODB.Command")

' Otevření připojení k hlavní databázi
objConn.Open strConn
If ErrorOccurred("Chyba: Nelze se připojit k instanci " + strInstance) Then
Set objConn = Nothing
Exit Function
End If

' Ověření verze před použitím opravy
strCommand = "select SERVERPROPERTY('ProductVersion') as version, SERVERPROPERTY('productlevel') as productlevel"
objCmd.ActiveConnection = objConn
objCmd.CommandType = adCmdText
objCmd.CommandText = strCommand

Set objRS = objCmd.Execute()
If ErrorOccurred("CHYBA: Nelze provést příkaz """ + strCommand + """ v instanci " + strInstance) = TRUE Then
objConn.Close()
Set objConn = Nothing
ApplyFix = FALSE
Exit Function
End If

strBuildVersion = objRS("version")
strProductLevel = UCase(objRS("productlevel"))

bApplyFix = FALSE
' Použití alternativního řešení pouze pro verze SQL 2000 a SQL 2005 (RTM, SP1 a SP2)
If (CInt(Mid(strBuildVersion,1,1)) = 8) Then
bApplyFix = TRUE
ElseIf CInt(Mid(strBuildVersion,1,1)) = 9 AND (StrComp(strProductLevel,"RTM") = 0 OR StrComp(strProductLevel,"SP1") = 0 OR StrComp(strProductLevel,"SP2") = 0) Then
bApplyFix = TRUE
End If

If bApplyFix = TRUE Then
strCommand = "deny execute on sp_replwritetovarbin to public"
objCmd1.ActiveConnection = objConn
objCmd1.CommandType = adCmdText
objCmd1.CommandText = strCommand
Set objRS1 = objCmd1.Execute()
If ErrorOccurred("CHYBA: Nelze provést příkaz """ + strCommand + """ v instanci " + strInstance) = FALSE Then
WScript.Echo "INFORMACE: Alternativní řešení bylo úspěšně použito pro instanci " + strInstance + " (" + strBuildVersion + ")." + vbCRLF
ApplyFix = TRUE
End If
Else
WScript.Echo "INFORMACE: Shromažďování informací pro instanci " + strInstance + " (" + strBuildVersion + ") bylo vynecháno, protože tato instance není chybou ovlivněna." + vbCRLF
ApplyFix = TRUE
End If

objConn.Close()
Set objConn = Nothing
Set objCmd = Nothing
Set objCmd1 = Nothing
Set objRS = Nothing
Set objRS1 = Nothing
End Function

Private Function GetRegValue (ByVal strMachineName, ByVal hMainKey, ByVal strPath, ByVal strValueName, ByRef strValue, ByVal iValueType, ByVal b32bit)
Err.Clear
ON ERROR RESUME NEXT

Dim objLocator, objServices, objRegistry, objCtx
Dim sMultiStrings, lRc
GetRegValue = TRUE

'Připojení k rozhraní WMI a získání objektu třídy STDREGPROV
Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
If b32bit = TRUE Then
objCtx.Add "__ProviderArchitecture", 32
Else
objCtx.Add "__ProviderArchitecture", 64
End If
objCtx.Add "__RequiredArchitecture", TRUE
set objLocator = createobject("wbemscripting.swbemlocator")
set objServices = objLocator.connectserver(strMachineName,DEFAULTNAMESPACE, "", "",,,,objCtx)
set objRegistry = objServices.get(STDREGPROV)
If ErrorOccurred("CHYBA: Nelze se připojit k oboru názvů WMI " + DEFAULTNAMESPACE) Then
GetRegValue = FALSE
Exit Function
End If

lRc = 0
Select Case iValueType
' Předmět zájmu: pouze REG_MULTI_SZ
Case REG_MULTI_SZ
strValue = ""
lRC = objRegistry.GetMultiStringValue(hMainKey, strPath, strValueName, sMultiStrings)
strValue = sMultiStrings
Case REG_SZ
strValue = ""
lRC = objRegistry.GetStringValue(hMainKey, strPath, strValueName, strValue)
Case Else
GetRegValue = FALSE
End Select

If lRc = 2 Or lRc = 3 Then
GetRegValue = TRUE
strValue = ""
ElseIf Err.Number OR lRc <> 0 Then
GetRegValue = FALSE
End If

Set objLocator = Nothing
Set objServices = Nothing
Set objRegistry = Nothing
End Function

Function IsEmptyNull(sCheck)
IsEmptyNull = FALSE
If IsObject(sCheck) Then Exit Function
If IsArray(sCheck) Then Exit Function
If VarType(sCheck) = vbEmpty Then IsEmptyNull = TRUE : Exit Function
If VarType(sCheck) = vbNull Then IsEmptyNull = TRUE : Exit Function
If sCheck = "" Then IsEmptyNull = TRUE
End Function

Private Function ErrorOccurred (ByVal strIn)
If Err.Number <> 0 Then
WScript.Echo strIn
WScript.Echo "CHYBA: 0x" & Err.Number & " - " & Err.Description
Err.Clear
ErrorOccurred = TRUE
Else
ErrorOccurred = FALSE
End If
End Function

Function IsOs64Bit()
Err.Clear
ON ERROR RESUME NEXT

Dim objProc
Set objProc = GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'")
If objProc.Architecture = 0 Then
IsOs64Bit = FALSE
Else
IsOs64Bit = TRUE
End If
End Function

Function GetFullInstance (ByRef strInstanceName, ByVal b32bit)
Err.Clear
ON ERROR RESUME NEXT

Dim objServices, objClusters, objCluster
Dim strMacName, isEmpty
Dim strKey, strInstID

GetFullInstance = TRUE

If strComp(UCase(strInstanceName), "MICROSOFT##SSEE", 1) = 0 Then
strInstanceName = "np:\\.\pipe\mssql$microsoft##ssee\sql\query"
Exit Function
End if

strMacName = ""
Set objServices = GetObject("winmgmts:root\cimv2")

' Služba Query Cluster
Set objClusters = objServices.ExecQuery ("select * from win32_service where Name='ClusSvc' AND Started = TRUE")
isEmpty = TRUE
If Err.Number = 0 Then
For each objCluster in objClusters
isEmpty = FALSE
Next
End If

Set objServices = Nothing
Set objClusters = Nothing

If isEmpty = TRUE Then
strInstanceName = BuildInstanceName (".", strInstanceName)
Exit Function
End If

' Dosažení tohoto bodu znamená, že počítač je v uzlu clusteru.
' Dotaz na hodnotu registru nyní určí, zda instance SQL je v clusteru nebo ne.
' V případě SQL 2000 bude v dotazu použita následující hodnota
' HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<název_instance>\Cluster
' ClusterName
strKey = "SOFTWARE\Microsoft\Microsoft SQL Server\" + strInstanceName + "\Cluster"
GetRegValue "", HKEY_LOCAL_MACHINE, strKey, "ClusterName", strMacName, REG_SZ, b32bit

If StrComp(strMacName, "") <> 0 Then
strInstanceName = BuildInstanceName (strMacName, strInstanceName)
Exit Function
End If

strKey = "SOFTWARE\Microsoft\" + strInstanceName + "\Cluster"
GetRegValue "", HKEY_LOCAL_MACHINE, strKey, "ClusterName", strMacName, REG_SZ, b32bit

If StrComp(strMacName, "") <> 0 Then
strInstanceName = BuildInstanceName (strMacName, strInstanceName)
Exit Function
End If

' Nyní vyzkoušíme dotaz na hodnotu registru pro instance 2005/2008
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL
' RegValue = InstanceName
strInstID = ""
strKey = "SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL"
GetRegValue "", HKEY_LOCAL_MACHINE, strKey, strInstanceName, strInstID, REG_SZ, b32bit

If StrComp(strInstID, "") = 0 Then
' Pokud tento klíč neexistuje, zpět jako místní instance SQL 2000
strInstanceName = BuildInstanceName (".", strInstanceName)
Exit Function
End If

strKey = "SOFTWARE\Microsoft\Microsoft SQL Server\" + strInstID + "\Cluster"
GetRegValue "", HKEY_LOCAL_MACHINE, strKey, "ClusterName", strMacName, REG_SZ, b32bit

If StrComp(strMacName, "") = 0 Then
strMacName = "."
End If

strInstanceName = BuildInstanceName (strMacName, strInstanceName)
End Function

Function BuildInstanceName (ByVal strMachineName, ByVal strInstanceName)
Dim strPrefix

strPrefix = ""
If StrComp(strMachineName, ".") = 0 Then
strPrefix = "lpc:"
End If

If strComp(UCase(strInstanceName), "MSSQLSERVER", 1) = 0 Then
BuildInstanceName = strPrefix + strMachineName
Else
BuildInstanceName = strPrefix + strMachineName + "\" + strInstanceName
End if
End Function
Další informace o programu CScript.exe naleznete na následujícím webu společnosti Microsoft: Poznámka: Tento skript se nedoporučuje používat v případě, že byla vydána a instalována aktualizace zabezpečení.

ZNÁMÉ PROBLÉMY, KE KTERÝM MŮŽE DOJÍT PŘI SPUŠTĚNÍ TOHOTO SKRIPTU

Problém 1:

Při spuštění skriptu se zobrazí následující chybová zpráva:
CHYBA: Nelze provést příkaz "deny execute on sp_replwritetovarbin to public" v instanci <název_instance>
CHYBA: 0x-2147217900 - Nebyl nalezen objekt 'sp_replwritetovarbin', protože neexistuje nebo nemáte oprávnění pro přístup.
CHYBA: Alternativní řešení nelze použít pro instanci <název_instance>.

Příčina 1:

Tuto chybovou zprávu obdržíte, pokud nemáte oprávnění vyžadovaná k provedení změny. Tato chybová zpráva říká, že bylo možné se úspěšně přihlásit k instanci "<název_instance>."


Tato chybová zpráva se obvykle zobrazí v produktu SQL Server Express, ve kterém má skupina „Built-In\Users“ podle výchozího nastavení možnost se přihlásit k databázi. Tato skupina ale není členem role správce systému.

Tato chybová zpráva se může také zobrazit, pokud jste odstranili proceduru sp_replwritetovarbin. To bylo doporučeno ve zprávě jiného výrobce. My odstranění této uložené procedury nedoporučujeme. Místo toho doporučujeme použití tohoto řešení.

Řešení 1:

Zkontrolujte, že účet použitý k připojení je členem role správce systému pro příslušnou instanci databáze. Pokud účet členem není, buď jej přidejte k roli správce systému, nebo použijte jiný uživatelský účet. V produktu SQL Server 2005 a dřívějších verzích je skupina „Built-in\Administrators“ členem role správce systému standardně. Spouštíte-li tento skript v systému Windows Vista nebo Windows Server 2008, zkontrolujte, že jej spouštíte v příkazovém řádku s vyššími oprávněními.

Problém 2:

Spouštíte-li skript na serveru SQL Server 2005, zobrazí se následující chybová zpráva:
Chyba: Nelze se připojit k instanci <název_instance>
CHYBA: 0x-2147217843 - Přihlášení uživatele '<uživatel>' se nezdařilo.
CHYBA: Alternativní řešení nelze použít pro instanci <název_instance>.

Příčina 2:

Tato chybová zpráva se zobrazí, pokud se nelze připojit k instanci <název_instance>, přestože tato instance existuje.


Tato chybová zpráva se obvykle zobrazí při připojení k instanci interní databáze systému Windows nebo databáze Microsoft SQL Server 2000 Desktop Edition (Windows). Oprávnění přihlásit se k těmto databázím obvykle nemají žádné uživatelské účty.

Řešení 2:

Zkontrolujte, že účet použitý ke spuštění skriptu a přihlášení k databázi je členem role správce systému.

Nedoporučuje se přidávat do interní databáze systému Windows či databáze Microsoft SQL Server 2000 Desktop Edition (Windows) jednotlivé uživatele. Pokud to provedete, přidaní uživatelé mohou bránit standardní činnosti těchto databází. Proto v tomto případě zajistěte, že se připojujete pomocí účtu, který je členem role správce systému. V produktu SQL Server 2005 a dřívějších verzích je skupina „Built-in\Administrators“ členem role správce systému standardně. Spouštíte-li tento skript v systému Windows Vista nebo Windows Server 2008, zkontrolujte, že jej spouštíte v příkazovém řádku s vyššími oprávněními.

Problém 3:

Můžete si všimnout instance databáze s názvem MICROSOFT##SSEE. Tuto databázi jste však neinstalovali.

Příčina 3:

Tato databáze je interní databází systému Windows, také nazývaná „SQL Server Embedded Edition“, případně „Microsoft SQL Server 2000 Desktop Edition (Windows)“. Instaluje se s některými produkty společnosti Microsoft, například se službou SharePoint Services.

Řešení 3:

Skript alternativního řešení je navržen tak, aby fungoval s interní databází systému Windows. Není vyžadována žádná akce.

Některé aplikace při své odinstalaci neodeberou interní databázi systému Windows.
Další informace o odebrání interní databáze systému Windows naleznete v následujícím článku znalostní báze Microsoft Knowledge Base:
920277 Interní databáze systému Windows není uvedena v seznamu ovládacího panelu Přidat nebo odebrat programy a není odebrána při odebrání produktu Windows SharePoint Services 3.0 z počítače (Tento článek může obsahovat odkazy na anglický obsah (dosud nepřeložený).)

Problém 4:

Při spuštění skriptu se zobrazí následující chybová zpráva:

Chyba: Nelze se připojit k instanci .\<název_instance>
CHYBA: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]SQL Server neexistuje nebo byl odepřen přístup

Příčina 4

Tato chybová zpráva se zobrazí v případě splnění následujících podmínek:
  • 32bitová verze serveru SQL Server 2000 je nainstalována v 64bitovém operačním systému.
  • V počítači je nainstalována 64bitová verze serveru SQL Server 2005 nebo SQL Server 2008.

Tato chybová se zobrazí, pokud skript používá 64bitovou verzi souboru dbmslpcn.dll. Tato verze nemůže komunikovat s instancemi WoW serveru SQL Server 2000.

Řešení 4

Ke spuštění skriptu použijte 32bitovou verzi souboru cscript.exe ze složky %WINDOWS%\SysWOW64. Bude načtena 32bitová verze souboru dbmslpcn.dll, která dokáže detekovat instance WoW.

Odkazy

Další informace o určení verze a edice serveru SQL Server naleznete v následujícím článku znalostní báze Microsoft Knowledge Base:
321185 Určení verze a edice serveru SQL Server (Tento článek může obsahovat odkazy na anglický obsah (dosud nepřeložený).)

Další informace

V následující tabulce jsou uvedeny významné technické revize tohoto článku. Číslo revize a datum poslední kontroly tohoto článku mohou odrážet menší editorské nebo strukturální revize tohoto článku, které nejsou obsaženy v tabulce.
DatumRevize
31. prosince 2008Zahrnuje aktualizovaný skript, který detekuje v clusteru instance serveru SQL Server s převzetím služeb při selhání.
30.12.08Zahrnuje aktualizovaný skript, který detekuje 32bitové verze serveru SQL Server spuštěné v 64bitové verzi systému Windows.
Vlastnosti

ID článku: 961040 - Poslední kontrola: 6. 1. 2009 - Revize: 1

Váš názor