INLEIDING
Microsoft heeft een beveiligingsadvies uitgebracht over een beveiligingsprobleem in Microsoft SQL Server dat kan leiden tot de uitvoering van externe code. Dit beveiligingsadvies bevat aanvullende beveiligingsinformatie. Het beveiligingsadvies kunt u vinden op de volgende website van Microsoft:
http://www.microsoft.com/netherlands/technet/security/advisory/961040.mspxDit artikel bevat een VB-script dat u kunt gebruiken om een tijdelijke oplossing te implementeren op alle actieve exemplaren van SQL Server op een lokale computer.
VOORBEELD VAN EEN VB-SCRIPT DAT U KUNT GEBRUIKEN OM DE TIJDELIJKE OPLOSSING TE IMPLEMENTEREN
Met dit VB-script kunt u de machtiging Uitvoeren weigeren voor de publieke rol op de uitgebreide opgeslagen procedure sp_replwritetovarbin op alle getroffen versies van SQL Server die op de lokale computer actief zijn.
Microsoft verstrekt deze code zonder enige expliciete of impliciete garantie, daaronder mede begrepen, maar niet beperkt tot impliciete garanties met betrekking tot de verkoopbaarheid en/of geschiktheid voor een bepaald doel. In dit artikel wordt ervan uitgegaan dat u bekend bent met de programmeertaal VBScript, alsmede met de hulpprogramma's waarmee procedures worden gemaakt en waarmee fouten in procedures worden opgespoord. U kunt desgewenst contact opnemen met de ondersteuningsmedewerkers van Microsoft voor uitleg over de functionaliteit van een bepaalde procedure. Deze medewerkers zullen de voorbeelden echter niet aanpassen om extra functionaliteit toe te voegen of om procedures te maken die aan uw specifieke eisen voldoen. Kopieer deze code naar een tekstbestand, sla het bestand op met de bestandsnaamextensie .vbs en voer het script vervolgens uit met behulp van CScript.exe. Het script doorloopt de actieve exemplaren van SQL Server op de lokale computer en implementeert de tijdelijke oplossing op de getroffen versies. U moet voor elk exemplaar van SQL Server lid zijn van de rol sysadmin om de oplossing te kunnen implementeren. Als u geen Windows-account hebt dat lid is van de rol sysadmin op alle getroffen servers waarop SQL Server actief is, moet u dit script mogelijk vanaf meerdere accounts uitvoeren. Als u op Windows Server 2008 of Windows Vista gebruik maakt van een Windows-beheerdersaccount dat lid is van de rol sysadmin, moet u dit script uitvoeren vanaf een opdrachtprompt met verhoogde rechten.'*************************************************************************************
'Beschrijving: Dit script doorloopt alle actieve versies van SQL Server ' en weigert machtiging voor uitvoeren op sp_replwritetovarbin voor publiek ' op alle getroffen versies. ' DIT IS EEN TIJDELIJKE OPLOSSING DIE NIET MOET WORDEN GEBRUIKT INDIEN ' EEN BEVEILIGINGSUPDATE IS GELEVERD EN GEÏNSTALLEERD. '************************************************************************************* OPTION EXPLICIT ON ERROR RESUME NEXT * Constante waarden 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 "INFO: Er zijn geen exemplaren aanwezig." 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 "FOUT: Kan de oplossing niet implementeren op " + sInstances(i,0) + "." + vbCRLF VBMain = EXIT_FAILURE End If Next WScript.Echo "INFO: Verwerking van alle actieve SQL-exemplaren is voltooid." 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 "FOUT: Lezen van op de machine geïnstalleerde SQL-exemplaren is mislukt." 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 "FOUT: Lezen van op de machine geïnstalleerde SQL-exemplaren is mislukt." Exit Function End If End If If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then WScript.Echo "INFO: Geen exemplaren aanwezig." 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 ' Retourwaarde initialiseren ApplyFix = FALSE strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";" ' Foutcontrole met opzet weggelaten om de code kort te houden Set objConn = CreateObject("ADODB.Connection") Set objCmd = CreateObject("ADODB.Command") Set objCmd1 = CreateObject("ADODB.Command") ' Verbinding met de hoofddatabase openen objConn.Open strConn If ErrorOccurred("Fout: Kan geen verbinding maken met " + strInstance) Then Set objConn = Nothing Exit Function End If ' Versie valideren voordat de correctie wordt geïmplementeerd 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("FOUT: Kan """ + strCommand + """ niet uitvoeren op " + strInstance) = TRUE Then objConn.Close() Set objConn = Nothing ApplyFix = FALSE Exit Function End If strBuildVersion = objRS("version") strProductLevel = UCase(objRS("productlevel")) bApplyFix = FALSE ' Oplossing alleen implementeren voor versies van SQL 2000 en SQL 2005 (RTM, SP1 and 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 = "uitvoeren weigeren op sp_replwritetovarbin voor publiek" objCmd1.ActiveConnection = objConn objCmd1.CommandType = adCmdText objCmd1.CommandText = strCommand Set objRS1 = objCmd1.Execute() If ErrorOccurred("FOUT: Kan """ + strCommand + """ niet uitvoeren op " + strInstance) = FALSE Then WScript.Echo "INFO: De tijdelijke oplossing is met succes geïmplementeerd op " + strInstance + " (" + strBuildVersion + ")." + vbCRLF ApplyFix = TRUE End If Else WScript.Echo "INFO: Het verzamelen van informatie voor " + strInstance + " (" + strBuildVersion + ") wordt overgeslagen omdat dit exemplaar geen beveiligingsprobleem heeft." + 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 ' Verbinden met WMI en een object ophalen voor 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("FOUT: Kan geen verbinding maken met WMI-naamruimte " + DEFAULTNAMESPACE) Then GetRegValue = FALSE Exit Function End If lRc = 0 Select Case iValueType ' Het gaat ons alleen maar om 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 "FOUT: 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") ' Queryclusterservice 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 ' Als we dit punt bereiken, betekent dit dat de machine een geclusterd knooppunt is. ' We bevragen het register om te bepalen of het SQL-exemplaar al dan niet geclusterd is. ' Zoek voor SQL 2000 de volgende waarde op ' 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 ' We proberen de registerwaarde op voor 2005/2008-exemplaren te zoeken '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 ' Als deze sleutel niet bestaat, ga dan terug als een lokaal exemplaar van 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
Als u meer informatie wilt over CScript.exe, gaat u naar de volgende Microsoft-website:
http://technet.microsoft.com/en-us/library/bb490887.aspxOpmerking Wij adviseren om dit script niet te gebruiken als er een beveiligingsupdate is geleverd en u deze hebt geïnstalleerd.
BEKENDE PROBLEMEN DIE ZICH KUNNEN VOORDOEN WANNEER U DIT SCRIPT UITVOERT
Probleem 1
Wanneer u het script uitvoert, krijgt u de volgende foutmelding:
FOUT: Kan "uitvoeren weigeren op sp_replwritetovarbin voor publiek" niet uitvoeren op <instancename>
FOUT: 0x-2147217900 - Kan het object 'sp_replwritetovarbin' niet vinden, omdat het niet bestaat of omdat u geen machtiging heeft. FOUT: Kan de tijdelijke oplossing niet implementeren op <instancename>.Oorzaak 1
U krijgt deze foutmelding als u niet beschikt over de machtigingen die zijn vereist om de wijziging te implementeren. Deze foutmelding geeft aan dat u zich hebt kunnen aanmelden op de instance '<instancename>'.
Deze foutmelding doet zich meestal voor bij SQL Server Express, waarin de groep 'Ingebouwd\Gebruikers' standaard een login op de database heeft. Deze groep is echter geen lid van de groep sysadmin. Deze foutmelding kan zich ook voordoen als u de procedure sp_replwritetovarbin hebt genegeerd. Dit was de aanbeveling in een rapport van derden. Wij adviseren om de opgeslagen procedure niet te negeren. Wij adviseren om, in plaats daarvan, deze oplossing te implementeren.Oplossing 1
Zorg ervoor dat het account waarmee u verbinding maakt, lid is van de rol sysadmin op dat exemplaar van de database. Als het account geen lid is, moet u de gebruiker waarmee u verbinding maakt, toevoegen aan de rol sysadmin, of een ander gebruikersaccount kiezen. Voor SQL Server 2005 en eerder is de groep 'Ingebouwd\Administrators' standaard lid van de rol sysadmin. Als u dit script uitvoert op Windows Vista of op Windows Server 2008, moet u er voor zorgen dat u het uitvoert vanaf een opdrachtprompt met verhoogde rechten.
Probleem 2
Wanneer u dit script uitvoert in SQL Server 2005, krijgt u de volgende foutmelding:
Fout: Kan geen verbinding maken met <instancename>
FOUT: 0x-2147217843 - Aanmelden mislukt voor gebruiker '<user>'. FOUT: Kan de tijdelijke oplossing niet implementeren op <instancename>.Oorzaak 2
U krijgt deze foutmelding als u geen verbinding kunt maken met het exemplaar '<instancename>' hoewel dit exemplaar wel bestaat.
Deze foutmelding doet zich meestal voor als u verbinding maakt met exemplaren van Windows Internal Database of Microsoft SQL Server 2000 Desktop Edition (Windows). In het algemeen zijn er geen gebruikersaccounts die kunnen worden aangemeld op deze databases.Oplossing 2
Zorg er voor dat het account waarmee u het script uitvoert, op de database wordt aangemeld als lid van de rol sysadmin.
Het is niet aan te bevelen om individuele gebruikers toe te voegen aan de databases van Windows Internal Database en Microsoft SQL Server 2000 Desktop Edition (Windows). Als u dit doet, kunnen de toegevoegde gebruikers de normale werking van deze databases verstoren. Zorg er in dit geval voor dat u verbinding maakt vanaf een account dat lid is van de rol sysadmin. De groep 'Ingebouwd\Administrators' in Windows is in SQL Server 2005 en eerdere versies meestal standaard lid van de rol sysadmin. Als u dit script uitvoert op Windows Vista of Windows Server 2008, moet u er voor zorgen dat u het uitvoert vanaf een opdrachtprompt met verhoogde rechten.Probleem 3
Mogelijk ziet u een exemplaar van een database met de naam MICROSOFT##SSEE. U hebt deze database echter niet geïnstalleerd.
Oorzaak 3
Deze database is de Windows Internal Database, ook bekend als 'SQL Server Embedded Edition' of soms als 'Windows Internal Database' of 'Microsoft SQL Server 2000 Desktop Edition (Windows).' Deze wordt geïnstalleerd bij sommige Microsoft-producten, waaronder SharePoint Services.
Oplossing 3
Het script met de tijdelijke oplossing is zo ontworpen, dat het ook werkt met de Windows Internal Database. Er is geen actie van uw kant nodig.
Sommige toepassingen verwijderen de Windows Internal Database niet wanneer zij worden verwijderd. Klik op het volgende artikelnummer in de Microsoft Knowledge Base voor meer informatie over het verwijderen van de Windows Internal Database:920277 De Windows Internal Database wordt niet weergegeven in het hulpprogramma Software en wordt niet verwijderd wanneer u Windows SharePoint Services 3.0 van uw computer verwijdert. (Het Engels)
Probleem 4
Wanneer u het script uitvoert, krijgt u de volgende foutmelding:
Fout: Kan geen verbinding maken met .\<instancename> FOUT: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]De SQL-server bestaat niet of de toegang tot de server is geweigerd.
Oorzaak 4
U krijgt deze foutmelding als aan de volgende voorwaarden voldaan is:
-
U hebt een 32-bits versie van SQL Server 2000 geïnstalleerd op een x64-bits besturingssysteem.
-
U hebt een 64-bits versie van SQL Server 2005 of van SQL Server 2008 geïnstalleerd op de computer.
Deze foutmelding doet zich voor wanneer het script gebruik maakt van de 64-bits versie van het bestand dbmslpcn.dll. Deze versie kan niet communiceren met de WoW-exemplaren van SQL Server 2000.
Oplossing 4
Gebruik de 32-bits versie van het bestand cscript.exe uit de map %WINDOWS%\SysWOW64 om het script op te starten. Hiermee wordt de 32-bits versie geladen van het bestand dbmslpcn.dll, dat WoW-exemplaren kan detecteren.
Referenties
Als u meer informatie wilt over het bepalen van de SQL Server-versie, klikt u op het volgende artikelnummer in de Microsoft Knowledge Base:
321185De versie en editie van SQL Server bepalen (Het Engels)
Meer informatie
De volgende tabel vermeldt belangrijke technische aanpassingen van dit artikel. Het revisienummer en de datum van de laatste revisie in dit artikel kunnen wijzen op minder belangrijke inhoudelijke of structurele wijzigingen die niet in deze tabel zijn opgenomen.
Datum |
Revisies |
---|---|
31-dec-2008 |
Bevat een bijgewerkt script dat failover-clusteringexemplaren van SQL Server detecteert. |
30-dec-2008 |
Bevat een bijgewerkt script dat 32-bits versies van SQL Server detecteert die worden uitgevoerd op 64-bits versies van Windows. |