Microsoft-beveiligingsadvies: Beveiligingsprobleem in SQL Server kan leiden tot uitvoering van externe code

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: Dit 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 EXPLICITON ERROR RESUME NEXT* Constante waardenCONST 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: 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 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 "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 = 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    ' 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 = 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 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 = 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 "FOUT: 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")    ' 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 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
Als u meer informatie wilt over CScript.exe, gaat u naar de volgende Microsoft-website: Opmerking 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.
DatumRevisies
31-dec-2008Bevat een bijgewerkt script dat failover-clusteringexemplaren van SQL Server detecteert.
30-dec-2008Bevat een bijgewerkt script dat 32-bits versies van SQL Server detecteert die worden uitgevoerd op 64-bits versies van Windows.
update beveiligingspatch beveiligingsupdate beveiliging bug lek fout beveiligingsfout beveiligingsprobleem kwaadwillende aanvaller misbruik register niet-gemachtigd bufferoverschrijding overloop speciaal gevormd vervaardigd bereik denial of service
Egenskaper

Artikkel-ID: 961040 – Forrige gjennomgang: 01/06/2009 15:41:05 – Revisjon: 3.0

Windows Internal Database, Microsoft SQL Server 2005 Service Pack 2, Microsoft SQL Server 2000 Desktop Engine (Windows), Microsoft SQL Server 2000 Desktop Engine (Windows), Microsoft SQL Server 2000 Service Pack 4

  • kbpubtypekc kbfix kbbug kbsecvulnerability kbsecbulletin kbsecurity KB961040
Tilbakemelding