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 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: 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:
321185 De 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.
Eigenschappen

Artikel-id: 961040 - Laatst bijgewerkt: 6 jan. 2009 - Revisie: 1

Feedback