EINFÜHRUNG
Microsoft hat eine Sicherheitsempfehlung zu einem Sicherheitsrisiko in Microsoft SQL Server herausgegeben, das eine Remotecodeausführung ermöglichen kann. Diese Sicherheitsempfehlung enthält zusätzliche sicherheitsrelevante Informationen. Sie finden die Sicherheitsempfehlung auf folgender Microsoft-Website:
http://www.microsoft.com/germany/technet/sicherheit/empfehlungen/961040.mspxDieser Artikel enthält ein VB-Skript, mit dem Sie eine Problemumgehung auf alle auf einem lokalen Computer ausgeführten Instanzen von SQL Server anwenden können.
BEISPIEL FÜR EIN VB-SKRIPT, MIT DEM SIE DIE PROBLEMUMGEHUNG ANWENDEN KÖNNEN
Mithilfe dieses VB-Skripts können Sie die Berechtigung "Execute" für die Rolle "Public" in der erweiterten gespeicherten Prozedur "sp_replwritetovarbin" für alle betroffenen Versionen von SQL Server, die auf dem lokalen Computer ausgeführt werden, verweigern.Die Verwendung der hier aufgeführten Informationen, Makro- oder Programmcodes geschieht auf Ihre eigene Verantwortung. Microsoft stellt Ihnen diese Informationen sowie Makro- und Programmlistings ohne Gewähr auf Richtigkeit, Vollständigkeit und/oder Funktionalität sowie ohne Anspruch auf Support zur Verfügung. Die zur Verfügung gestellten Makro- und Programmierungsbeispiele sollen lediglich exemplarisch die Funktionsweise des Beispiels aufzeigen. Die Mitarbeiter der Microsoft Product Support Services erklären Ihnen gerne die Funktionsweise einer bestimmten Prozedur. Sie werden diese Beispiele jedoch weder modifizieren, um zusätzliche Funktionalität zu schaffen, noch Prozeduren entwickeln, die auf Ihre spezifischen Bedürfnisse zugeschnitten sind. Kopieren Sie diesen Code in eine Textdatei, speichern Sie die Datei mit der Dateinamenerweiterung VBS, und führen Sie die Skriptdatei anschließend unter Verwendung von "CScript.exe" aus. Das Skript wird für alle ausgeführten Instanzen von SQL Server auf dem lokalen Computer wiederholt und wendet die Problemumgehung auf die betroffenen Versionen an. Sie müssen für jede Instanz von SQL Server ein Mitglied der Rolle "sysadmin" sein, um die Problemumgehung anwenden zu können. Wenn Sie über kein Windows-Konto verfügen, das für alle betroffenen Server, auf denen SQL Server ausgeführt wird, ein Mitglied der Rolle "sysadmin" ist, müssen Sie dieses Skript möglicherweise unter mehreren Konten ausführen. Wenn Sie unter Windows Server 2008 und Windows Vista ein Windows-Administratorkonto verwenden, das ein Mitglied der Rolle "sysadmin" ist, müssen Sie dieses Skript in einer Eingabeaufforderung mit erhöhten Rechten ausführen.
'*************************************************************************************'Beschreibung: Dieses Skript wird für alle ausgeführten Instanzen von SQL Server wiederholt' und verweigert die "execute"-Berechtigung für "sp_replwritetovarbin" für "public"' in allen betroffenen Versionen.' DIESE PROBLEMUMGEHUNG SOLLTE NICHT VERWENDET WERDEN, WENN' EIN SICHERHEITSUPDATE BEREITGESTELLT UND INSTALLIERT WURDE.'*************************************************************************************OPTION EXPLICITON ERROR RESUME NEXT' Werte der KonstantenCONST EXIT_SUCCESS = 0CONST EXIT_FAILURE = 1CONST EXIT_NOINSTANCES = -1CONST DEFAULTNAMESPACE = "root\default"CONST STDREGPROV = "stdregprov"CONST HKEY_LOCAL_MACHINE = &H80000002CONST REG_MULTI_SZ = 7CONST REG_SZ = 1CONST adCmdText = 1Call 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 "INFO: Es sind keine Instanzen vorhanden." 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 "FEHLER: Problemumgehung konnte auf " + sInstances(i,0) + " nicht angewendet werden." + vbCRLF VBMain = EXIT_FAILURE End If Next WScript.Echo "INFO: Verarbeitung aller ausgeführten SQL-Instanzen abgeschlossen."End FunctionFunction 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 "FEHLER: Fehler beim Lesen der auf dem Computer installierten SQL-Instanzen." 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 "FEHLER: Fehler beim Lesen der auf dem Computer installierten SQL-Instanzen." Exit Function End If End If If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then WScript.Echo "INFO: Keine Instanzen vorhanden." 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 = TRUEEnd FunctionFunction ApplyFix(ByVal strInstance, ByVal strServerName) Err.Clear ON ERROR RESUME NEXT Dim objConn, objCmd, objCmd1, objRS, objRS1 Dim strCommand, strConn Dim strBuildVersion, strProductLevel, bApplyFix ' Rückgabewert initialisieren ApplyFix = FALSE strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";" ' Fehlerprüfung absichtlich beendet, um den Code kurz zu halten Set objConn = CreateObject("ADODB.Connection") Set objCmd = CreateObject("ADODB.Command") Set objCmd1 = CreateObject("ADODB.Command") ' Öffnen einer Verbindung zur Masterdatenbank objConn.Open strConn If ErrorOccurred("Fehler: Keine Verbindung zu " + strInstance) Then Set objConn = Nothing Exit Function End If ' Prüfen der Version vor Anwendung des Fixes strCommand = "SERVERPROPERTY('ProductVersion') als Version auswählen, SERVERPROPERTY('productlevel') als Produktebene auswählen" objCmd.ActiveConnection = objConn objCmd.CommandType = adCmdText objCmd.CommandText = strCommand Set objRS = objCmd.Execute() If ErrorOccurred("FEHLER: Fehler bei Ausführung von """ + strCommand + """ in " + strInstance) = TRUE Then objConn.Close() Set objConn = Nothing ApplyFix = FALSE Exit Function End If strBuildVersion = objRS("version") strProductLevel = UCase(objRS("productlevel")) bApplyFix = FALSE ' Problemumgehung nur für SQL 2000 und SQL 2005 (RTM, SP1 und SP2) anwenden 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 = "execute für sp_replwritetovarbin für public verweigern" objCmd1.ActiveConnection = objConn objCmd1.CommandType = adCmdText objCmd1.CommandText = strCommand Set objRS1 = objCmd1.Execute() If ErrorOccurred("FEHLER: Fehler bei Ausführung von """ + strCommand + """ in " + strInstance) = FALSE Then WScript.Echo "INFO: Problemumgehung erfolgreich angewendet für " + strInstance + " (" + strBuildVersion + ")." + vbCRLF ApplyFix = TRUE End If Else WScript.Echo "INFO: Datenerfassung für " + strInstance + " (" + strBuildVersion + ") ausgelassen, da diese Instanz nicht anfällig ist." + vbCRLF ApplyFix = TRUE End If objConn.Close() Set objConn = Nothing Set objCmd = Nothing Set objCmd1 = Nothing Set objRS = Nothing Set objRS1 = NothingEnd FunctionPrivate 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 'Verbinden mit WMI und Abrufen eines Objekts zu Klasse 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 ("FEHLER: Keine Verbindung zu WMI-Namespace " + DEFAULTNAMESPACE) Then GetRegValue = FALSE Exit Function End If lRc = 0 Select Case iValueType ' Von Interesse nur 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 = NothingEnd FunctionFunction 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 = TRUEEnd FunctionPrivate Function ErrorOccurred (ByVal strIn) If Err.Number <> 0 Then WScript.Echo strIn WScript.Echo "FEHLER: 0x" & Err.Number & " - " & Err.Description Err.Clear ErrorOccurred = TRUE Else ErrorOccurred = FALSE End IfEnd FunctionFunction 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 IfEnd FunctionFunction 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") ' Abfragen des Clusterdiensts Set objClusters = objServices.ExecQuery ("* aus win32_service auswählen, wobei 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 ' Wenn Sie hier ankommen, bedeutet dies, dass der Computer ein Clusterknoten ist. ' Fragen Sie daher jetzt die Registrierung ab, um zu ermitteln, ob die SQL-Instanz geclustert ist oder nicht. ' Fragen Sie für SQL 2000 den folgenden Wert ab: ' HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<InstanceName>\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 ' Überprüfen Sie die Registrierung nun auf Werte für 2005/2008-Instanzen: '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 ' Wenn dieser Schlüssel nicht existiert, als lokale SQL 2000-Instanz zurückgeben. 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 FunctionFunction 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 ifEnd Function
Weitere Informationen zu "CScript.exe" finden Sie auf folgender Website von Microsoft:
http://technet.microsoft.com/de-de/library/bb490887.aspxHinweis Sie sollten dieses Skript nicht verwenden, wenn ein Sicherheitsupdate bereitgestellt und installiert wurde.
BEKANNTE PROBLEME, DIE BEI DER AUSFÜHRUNG DIESES SKRIPTS AUFTRETEN KÖNNEN
Problem 1
Wenn Sie das Skript ausführen, wird die folgende Fehlermeldung angezeigt:
FEHLER: "execute für sp_replwritetovarbin für public verweigern" konnte für <instancename> nicht ausgeführt werden. FEHLER: 0x-2147217900 - Objekt 'sp_replwritetovarbin' wurde nicht gefunden, weil es nicht vorhanden ist oder Sie nicht die erforderliche Berechtigung haben. FEHLER: Problemumgehung konnte auf <instancename> nicht angewendet werden.
Ursache 1
Diese Fehlermeldung wird angezeigt, wenn Sie nicht über die zum Anwenden der Änderung erforderlichen Berechtigungen verfügen. Diese Fehlermeldung deutet darauf hin, dass Sie sich erfolgreich bei der Instanz "<instancename>" anmelden konnten.Der Fehler tritt typischerweise in SQL Server Express auf, wenn die Gruppe "Vordefiniert\Benutzer" standardmäßig über ein Login für die Datenbank verfügt. Die Gruppe ist jedoch kein Mitglied der Rolle "sysadmin". Die Fehlermeldung kann auch auftreten, wenn Sie die Prozedur "sp_replwritetovarbin" verworfen haben. So lautete die Empfehlung in einem Bericht eines anderen Anbieters. Wir empfehlen das Verwerfen der gespeicherten Prozedur nicht. Stattdessen empfehlen wir die Anwendung dieser Lösung.
Lösung 1
Stellen Sie sicher, dass das Konto, mit dem Sie die Verbindung herstellen, ein Mitglied der Rolle "sysadmin" für diese Instanz der Datenbank ist. Wenn das Konto kein Mitglied ist, fügen Sie entweder das Benutzerkonto, mit dem Sie die Verbindung herstellen, zur Rolle "sysadmin" hinzu, oder verwenden Sie ein anderes Benutzerkonto. In SQL Server 2005 und früheren Versionen ist die Gruppe "Vordefiniert\Administratoren" standardmäßig ein Mitglied der Rolle "sysadmin". Wenn Sie dieses Skript unter Windows Vista oder Windows Server 2008 ausführen, stellen Sie sicher, dass Sie es in einer Eingabeaufforderung mit erhöhten Rechten ausführen.
Problem 2
Wenn Sie das Skript in SQL Server 2005 ausführen, wird die folgende Fehlermeldung angezeigt:
Fehler: Die Verbindung mit <instancename> konnte nicht hergestellt werden. FEHLER: 0x-2147217843 - Fehler bei der Anmeldung für den Benutzer '<user>'. FEHLER: Problemumgehung konnte auf <instancename> nicht angewendet werden.
Ursache 2
Diese Fehlermeldung wird angezeigt, wenn Sie keine Verbindung zur Instanz "<instancename>" herstellen konnten, obwohl die Instanz vorhanden ist. Die Fehlermeldung tritt typischerweise auf, wenn Sie eine Verbindung mit Instanzen von Windows Internal Database oder Microsoft SQL Server 2000 Desktop Edition (Windows) herstellen. Typischerweise verfügen Benutzerkonten nicht über Logins für diese Datenbanken.
Lösung 2
Stellen Sie sicher, dass das zum Ausführen des Skripts verwendete Konto für die Datenbank über ein Login verfügt, das Mitglied der Rolle "sysadmin" ist. Es empfiehlt sich nicht, einzelne Benutzer zu Windows Internal Database und zu den Datenbanken von Microsoft SQL Server 2000 Desktop Edition (Windows) hinzuzufügen. Wenn Sie dies tun, können die hinzugefügten Benutzer den ordentlichen Betrieb der Datenbanken stören. Stellen Sie in diesem Fall sicher, dass Sie die Verbindung mit einem Konto herstellen, das Mitglied der Rolle "sysadmin" ist. Die Gruppe "Vordefiniert\Administratoren" in Windows ist typischerweise standardmäßig ein Mitglied der Rolle "sysadmin" in SQL Server 2005 und früheren Versionen. Wenn Sie dieses Skript unter Windows Vista oder Windows Server 2008 ausführen, stellen Sie sicher, dass Sie es in einer Eingabeaufforderung mit erhöhten Rechten ausführen.
Problem 3
Möglicherweise treffen Sie auf eine Instanz einer Datenbank mit dem Namen MICROSOFT##SSEE. Sie haben diese Datenbank jedoch nicht installiert.
Ursache 3
Bei dieser Datenbank handelt es sich um die Windows-interne Datenbank, die auch als "SQL Server Embedded Edition" oder manchmal als "Windows Internal Database" oder "Microsoft SQL Server 2000 Desktop Edition (Windows)" bezeichnet wird. Sie wird mit einigen Produkten von Microsoft installiert, beispielsweise SharePoint Services.
Lösung 3
Das Problemumgehungsskript funktioniert für die Windows-interne Datenbank. Es ist keine Aktion Ihrerseits erforderlich. Bei der Deinstallation einiger Anwendungen wird Windows Internal Database nicht gelöscht. Weitere Informationen zum Entfernen von Windows Internal Database finden Sie im folgenden Artikel der Microsoft Knowledge Base:
920277 Windows Internal Database wird nicht im Programm Software aufgelistet und nicht entfernt, wenn Sie Windows SharePoint Services 3.0 vom Computer entfernen
Problem 4
Wenn Sie das Skript ausführen, wird die folgende Fehlermeldung angezeigt:
Fehler: Die Verbindung mit .\<instancename> konnte nicht hergestellt werden.FEHLER: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]SQL-Server existiert nicht oder Zugriff verweigert
Ursache 4
Die Fehlermeldung wird angezeigt, wenn die folgenden Bedingungen vorliegen:
-
Sie haben eine 32-Bit-Version von SQL Server 2000 auf einem x64-Bit-Betriebssystem installiert.
-
Sie haben eine 64-Bit-Version von SQL Server 2005 oder SQL Server 2008 auf dem Computer installiert.
Die Fehlermeldung tritt auf, wenn das Skript die 64-Bit-Version der Datei "dbmslpcn.dll" verwendet. Diese Version kann nicht mit den WoW-Instanzen von SQL Server 2000 kommunizieren.
Lösung 4
Starten Sie das Skript mit der 32-Bit-Version der Datei "cscript.exe" aus dem Ordner "%WINDOWS%\SysWOW64". Dadurch wird die 32-Bit-Version der Datei "dbmslpcn.dll" geladen, die WoW-Instanzen erkennen kann.
Informationsquellen
Weitere Informationen darüber, wie Sie Version und Edition von SQL Server ermitteln, finden Sie im folgenden Artikel der Microsoft Knowledge Base:
321185Ermitteln der SQL Server-Version und -Edition
Weitere Informationen
In der folgenden Tabelle sind wichtige technische Revisionen zu diesem Artikel aufgeführt. Die Versionsnummer und die Datumsangabe bei "Geändert am" in diesem Artikel können auf geringfügige redaktionelle oder strukturelle Änderungen an den Inhalten hinweisen, die nicht in der Tabelle aufgelistet sind.
|
Datum |
Revisionen |
|---|---|
|
31. Dezember 2008 |
Enthält ein aktualisiertes Skript, das SQL Server-Failoverclusterinstanzen erkennt. |
|
30. Dezember 2008 |
Enthält ein aktualisiertes Skript, das 32-Bit-Versionen von SQL Server erkennt, die unter 64-Bit-Versionen von Windows ausgeführt werden. |