Du arbetar offline, väntar på att återansluta till Internet

Microsoft-säkerhetsmeddelande: Säkerhetsproblem i SQL Server möjliggör fjärrkörning av kod

INLEDNING
Microsoft har gett ut ett säkerhetsmeddelande för ett säkerhetsproblem i Microsoft SQL Server som möjliggör fjärrkörning av kod. Säkerhetsmeddelandet, som innehåller ytterligare säkerhetsrelaterad information, finns på följande Microsoft-webbplats: Denna artikel innehåller ett VB-skript som kan användas för att tillämpa en lösning på alla instanser av SQL Server som körs på en lokal dator.
EXEMPEL PÅ ETT VB-SKRIPT SOM KAN ANVÄNDAS FÖR ATT TILLÄMPA LÖSNINGEN
Du kan använda detta VB-skript för att neka Public-rollen körbehörighet för den utökade lagrade sp_replwritetovarbin-proceduren i alla berörda versioner av SQL Server som körs på den lokala datorn.

Microsoft tillhandahåller programmeringsexempel enbart i förklarande syfte och gör inga utfästelser, varken uttryckligen eller underförstått. Detta omfattar men begränsas inte till underförstådd garanti för säljbarhet eller lämplighet för ett visst syfte. I denna artikel förutsätts att du känner till det programmeringsspråk som demonstreras och de verktyg som används för att skapa och felsöka procedurer. Microsofts supporttekniker kan förklara hur en viss procedur fungerar, men de ändrar inte exemplen för att utöka funktionerna och konstruera procedurer som motsvarar dina behov.

Kopiera denna kod till en textfil, spara filen med filnamnstillägget .vbs och kör sedan skriptfilen med hjälp av CScript.exe. Skriptet upprepas för de instanser av SQL Server som körs på den lokala datorn, och lösningen används på de versioner som berörs. Du måste vara medlem av rollen sysadmin i varje instans av SQL Server för att kunna använda lösningen. Om du inte har ett Windows-konto som är medlem av rollen sysadmin på alla berörda servrar där SQL Server körs, måste du kanske köra skriptet från flera konton. I Windows Server 2008 och Windows Vista måste du köra skriptet från en kommandotolk med "förhöjd rättighet", om du använder ett Windows-administratörskonto som är medlem av rollen sysadmin.
'*************************************************************************************'Beskrivning: Detta skript upprepas i alla instanser av SQL Server som körs'            och nekar Public-rollen körbehörighet på sp_replwritetovarbin i alla'            berörda versioner.'            DETTA ÄR EN TILLFÄLLIG LÖSNING OCH BÖR INTE ANVÄNDAS OM EN SÄKERHETSUPPDATERING '            HAR GJORTS TILLGÄNGLIG OCH INSTALLERATS.'*************************************************************************************OPTION EXPLICITON ERROR RESUME NEXT' Konstanta värdenCONST 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: Det finns inte några instanser."        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 "FEL: Det gick inte att använda lösningen på " + sInstances(i,0) + "." + vbCRLF            VBMain = EXIT_FAILURE        End If    Next	    WScript.Echo "INFO: Alla SQL-instanser som körs har bearbetats."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 "FEL:Det går inte att läsa SQL-instanser som är installerade på datorn."        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 "FEL:Det går inte att läsa SQL-instanser som är installerade på datorn."            Exit Function        End If    End If    If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then         WScript.Echo "INFO: Det finns inte några instanser."        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    ' Initiera returvärde    ApplyFix = FALSE        strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";"    ' Felkontroll utesluts avsiktligt för att koden ska bli kort    Set objConn = CreateObject("ADODB.Connection")    Set objCmd = CreateObject("ADODB.Command")    Set objCmd1 = CreateObject("ADODB.Command")        ' Öppna en anslutning till huvuddatabasen    objConn.Open strConn     If ErrorOccurred("Fel: Det gick inte att ansluta till " + strInstance) Then        Set objConn = Nothing        Exit Function    End If    ' Kontrollera versionen innan korrigeringen installeras    strCommand = "välj SERVERPROPERTY('ProductVersion') som version, SERVERPROPERTY('productlevel') som produktnivå"    objCmd.ActiveConnection = objConn    objCmd.CommandType = adCmdText    objCmd.CommandText = strCommand    	    Set objRS = objCmd.Execute()    If ErrorOccurred("FEL: Det gick inte att köra """ + strCommand + """ på " + strInstance) = TRUE Then        objConn.Close()        Set objConn = Nothing        ApplyFix = FALSE        Exit Function       End If    strBuildVersion = objRS("version")    strProductLevel = UCase(objRS("productlevel"))    bApplyFix = FALSE    ' Lösningen ska endast användas på SQL 2000 och SQL 2005 (RTM, SP1 och 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 = "neka Public-rollen körbehörighet på sp_replwritetovarbin"        objCmd1.ActiveConnection = objConn        objCmd1.CommandType = adCmdText        objCmd1.CommandText = strCommand        Set objRS1 = objCmd1.Execute()        If ErrorOccurred("FEL: Det gick inte att köra """ + strCommand + """ på " + strInstance) = FALSE Then            WScript.Echo "INFO: Lösningen har installerats på " + strInstance + " (" + strBuildVersion + ")." + vbCRLF            ApplyFix = TRUE        End If    Else        WScript.Echo "INFO: Information för " + strInstance + " (" + strBuildVersion + ") samlas inte in, eftersom denna instans inte är sårbar." + 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    'Anslut till WMI och få ett objekt till STDREGPROV-klassen.    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 ("FEL: Det gick inte att ansluta till WMI-namnområde " + DEFAULTNAMESPACE) Then        GetRegValue = FALSE        Exit Function    End If    lRc = 0    Select Case iValueType        ' Endast REG_MULTI_SZ är av intresse        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 "FEL: 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")    ' Fråga klustertjänst    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        ' Om vi kommer hit innebär det att datorn är en klusternod.    ' Låt oss därför förfråga registret för att fastställa om SQL-instansen är klustrad.    ' Förfråga följande värde för SQL 2000    ' HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<Instansnamn>\Cluster    ' Klusternamn    strKey = "SOFTWARE\Microsoft\Microsoft SQL Server\" + strInstanceName + "\Cluster"    GetRegValue "", HKEY_LOCAL_MACHINE, strKey, "Klusternamn", 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, "Klusternamn", strMacName, REG_SZ, b32bit    If StrComp(strMacName, "") <> 0 Then        strInstanceName = BuildInstanceName (strMacName, strInstanceName)        Exit Function    End If    ' Låt oss försöka förfråga registervärdet för 2005/2008-instanser    '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        ' Om denna nyckel inte finns, återgå som en lokal SQL 2000-instans        strInstanceName = BuildInstanceName (".", strInstanceName)        Exit Function    End If    strKey = "SOFTWARE\Microsoft\Microsoft SQL Server\" + strInstID + "\Cluster"    GetRegValue "", HKEY_LOCAL_MACHINE, strKey, "Klusternamn", 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
Mer information om CScript.exe finns på följande Microsoft-webbplats: Obs! Vi rekommenderar att du inte använder detta skript om en säkerhetsuppdatering har tillhandahållits och du har installerat den.
KÄNDA PROBLEM SOM KAN UPPSTÅ VID KÖRNING AV DETTA SKRIPT

Problem 1

När skriptet körs visas följande felmeddelande:
FEL: Det gick inte att köra "neka Public-rollen körbehörighet på sp_replwritetovarbin" på <instansnamn>
FEL: 0x-2147217900 - Det går inte att hitta objektet 'sp_replwritetovarbin'. Objektet finns inte eller så har du inte den behörighet som krävs.
FEL: Det gick inte att använda lösningen på <instansnamn>.

Orsak 1

Detta felmeddelande visas om du inte har den behörighet som krävs för att göra ändringen. Felmeddelandet anger att du kunde logga in på instansen "<instansnamn>".

Detta felmeddelande förekommer vanligen i SQL Server Express, där gruppen "Built-In\Users" har ett inloggningsnamn till databasen som standard. Denna grupp är emellertid inte medlem av rollen sysadmin.

Felmeddelandet kan även förekomma om du har släppt proceduren sp_replwritetovarbin, vilket rekommenderades i en tredjepartsrapport. Vi rekommenderar inte att du släpper den lagrade proceduren, utan att du i stället använder denna lösning.

Lösning 1

Se till att det konto du ansluter med är medlem av rollen sysadmin i denna instans av databasen. Om kontot inte är medlem lägger du till den användare du ansluter som till rollen sysadmin eller använder ett annat användarkonto. För SQL Server 2005 och tidigare är gruppen "Built-in\Administrators" medlem av rollen sysadmin som standard. När du kör detta skript i Windows Vista eller Windows Server 2008 måste du se till att köra det från en kommandotolk med "förhöjd behörighet".

Problem 2

Om du kör detta skript i SQL Server 2005 visas följande felmeddelande:
Fel: Det gick inte att ansluta till <instansnamn>
FEL: 0x-2147217843 - Inloggning misslyckades för användare '<användare>'.
FEL: Det gick inte att använda lösningen på <instansnamn>.

Orsak 2

Detta felmeddelande visas om du inte har kunnat ansluta till instansen "<instansnamn>", trots att den finns.

Felmeddelandet visas vanligen när du ansluter till Windows Internal Database eller till Microsoft SQL Server 2000 Desktop Edition (Windows)-instanser. Normalt har inga användarkonton inloggningsnamn för dessa databaser.

Lösning 2

Se till att det konto du använder för att köra skriptet har ett databasinloggningsnamn som är medlem av rollen sysadmin.

Vi rekommenderar inte att du lägger till enskilda användare till Windows Internal Database och till Microsoft SQL Server 2000 Desktop Edition (Windows)-databaser. Om du gör detta kan de användare du lägger till störa den normala funktionen hos dessa databaser. I detta fall måste du se till att ansluta från ett konto som är medlem av rollen sysadmin. Gruppen "Built-in\Administrators" i Windows brukar i standardfallet vara medlem av rollen sysadmin i SQL Server 2005 och i tidigare versioner. När du kör detta skript i Windows Vista eller Windows Server 2008 måste du se till att köra det från en kommandotolk med "förhöjd behörighet".

Problem 3

Det kan förekomma en instans av en databas med beteckningen MICROSOFT##SSEE, som du inte har installerat.

Orsak 3

Denna databas är Windows Internal Database, även kallad "SQL Server Embedded Edition" eller ibland "Windows Internal Database" eller "Microsoft SQL Server 2000 Desktop Edition (Windows)". Den installeras tillsammans med vissa produkter från Microsoft, däribland SharePoint Services.

Lösning 3

Lösningsskriptet är konstruerat för att fungera med Windows Internal Database, och du behöver inte vidta några åtgärder.

Vissa program tar inte bort Windows Internal Database när de avinstalleras. Om du vill veta mer om hur du tar bort Windows Internal Database, klickar du på följande artikelnummer och läser artikeln i Microsoft Knowledge Base:
920277 Windows Internal Database visas inte i Lägg till eller ta bort program och tas inte bort när Windows SharePoint Services 3.0 tas bort från datorn (Länken kan leda till en webbplats som är helt eller delvis på engelska)

Problem 4

När skriptet körs visas följande felmeddelande:
Fel: Det gick inte att ansluta till .\<instansnamn>
FEL: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]SQL Server finns inte eller åtkomst nekad

Orsak 4

Detta felmeddelande visas under följande förutsättningar:
  • En 32-bitars version av SQL Server 2000 är installerad i ett x64-bitars operativsystem.
  • En 64-bitars version av SQL Server 2005 eller SQL Server 2008 är installerad på datorn.
Detta felmeddelande visas när en 64-bitars version av filen dbmslpcn.dll används av skriptet. Denna version kan inte kommunicera med WoW-instanserna av SQL Server 2000.

Lösning 4

Använd 32-bitarsversionen av filen cscript.exe från mappen %WINDOWS%\SysWOW64 för att starta skriptet. Därmed läser du in 32-bitarsversionen av filen dbmslpcn.dll, som kan identifiera WoW-instanser.
Referenser
Om du vill veta mer om hur du tar reda på version och utgåva för SQL Server, klickar du på följande artikelnummer och läser artikeln i Microsoft Knowledge Base:
321185Identifiera version och utgåva för SQL Server (Länken kan leda till en webbplats som är helt eller delvis på engelska)
Mer Information
Viktiga tekniska revideringar av den här artikeln anges i följande tabell. Revisionsnummer och datum för senaste granskning i artikeln kan avspegla mindre redaktionella eller strukturella revideringar som inte ingår i tabellen.
DatumRevideringar
31 december 2008Innehåller ett uppdaterat skript som identifierar SQL Server-instanser av kluster för växling vid fel.
30 december 2008Innehåller ett uppdaterat skript som identifierar 32-bitars versioner av SQL Server som körs i 64-bitars versioner av Windows.
update security_patch security_update security bug flaw vulnerability malicious attacker exploit registry unauthenticated buffer overrun overflow specially-formed scope specially-crafted denial of service
Egenskaper

Artikel-id: 961040 – senaste granskning 01/07/2009 13:32:10 – revision: 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
Feedback