Jesteś obecnie w trybie offline. Czekamy na ponowne połączenie z Internetem.

Microsoft Security Advisory: Luka w zabezpieczeniach programu SQL Server umożliwia zdalne wykonywanie kodu

WPROWADZENIE
Firma Microsoft wydała dokument Security Advisory dotyczący luki w zabezpieczeniach programu Microsoft SQL Server umożliwiającej zdalne wykonywanie kodu. Zawiera on dodatkowe informacje związane z zabezpieczeniami. Aby przeczytać ten dokument, odwiedź następującą witrynę firmy Microsoft w sieci Web: Niniejszy artykuł zawiera skrypt w języku Visual Basic umożliwiający zastosowanie obejścia problemu we wszystkich działających wystąpieniach programu SQL Server na komputerze lokalnym.
PRZYKŁADOWY SKRYPT VISUAL BASIC UMOŻLIWIAJĄCY OBEJŚCIE PROBLEMU
Ten skrypt w języku Visual Basic odmawia uprawnienia do wykonywania roli publicznej (Public) w rozszerzonej procedurze składowanej sp_replwritetovarbin dla wszystkich wersji programu SQL Server, których dotyczy ten problem, uruchomionych na komputerze lokalnym.

Firma Microsoft podaje przykłady programowania wyłącznie do celów informacyjnych, bez jakichkolwiek gwarancji wyrażonych wprost lub domyślnie. Dotyczy to także, ale nie ograniczając się do tego zapisu, gwarancji przydatności handlowej lub do określonego celu. W tym artykule zakłada się, że czytelnik zna prezentowany język programowania oraz narzędzia używane do tworzenia i debugowania procedur. Pracownicy pomocy technicznej firmy Microsoft mogą służyć pomocą, wyjaśniając funkcję konkretnej procedury. Nie będą jednak modyfikować tych przykładów ani dodawać żadnej funkcji i konstruować nowych procedur w celu dostosowania ich do konkretnych potrzeb użytkownika.

Należy skopiować poniższy kod do pliku tekstowego, zapisać plik z rozszerzeniem vbs, a następnie uruchomić skrypt za pomocą programu CScript.exe. Skrypt będzie wykonywany (jako iteracja) kolejno dla wszystkich wystąpień programu SQL Server na komputerze lokalnym i spowoduje zastosowanie obejścia problemu w odpowiednich wersjach. Aby można było zastosować obejście, użytkownik musi mieć uprawnienia administratora systemu (rola sysadmin) w poszczególnych wystąpieniach programu SQL Server. W przypadku braku dostępu do konta systemu Windows z uprawnieniami roli sysadmin na wszystkich serwerach z uruchomionym programem SQL Server, których dotyczy problem, może być konieczne uruchomienie tego skryptu z kilku różnych kont. W systemach Windows Server 2008 i Windows Vista uruchomienie tego skryptu za pomocą konta administratora systemu Windows z uprawnieniami roli sysadmin wymaga podniesienia poziomu uprawnień w wierszu polecenia.
'*************************************************************************************'Opis: Ten skrypt będzie wykonywany (jako iteracja) kolejno dla wszystkich uruchomionych wystąpień programu SQL Server'            i odmówi uprawnienia do wykonywania roli publicznej w procedurze sp_replwritetovarbin'            dla wszystkich wersji, których dotyczy ten problem.'            JEST TO TYLKO OBEJŚCIE PROBLEMU I NIE NALEŻY GO UŻYWAĆ W PRZYPADKU'            UDOSTĘPNIENIA I ZAINSTALOWANIA AKTUALIZACJI ZABEZPIECZEŃ.'*************************************************************************************OPTION EXPLICITON ERROR RESUME NEXT' Wartości stałychCONST 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 "INFORMACJA: Brak wystąpień."        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 "BŁĄD: nie można zastosować obejścia dla wystąpienia " + sInstances(i,0) + "." + vbCRLF            VBMain = EXIT_FAILURE        End If    Next	    WScript.Echo "INFORMACJA: Przetwarzanie wszystkich uruchomionych wystąpień programu SQL zostało zakończone."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 "BŁĄD: nie można odczytać wystąpień programu SQL zainstalowanych na komputerze."        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 "BŁĄD: nie można odczytać wystąpień programu SQL zainstalowanych na komputerze."            Exit Function        End If    End If    If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then         WScript.Echo "INFORMACJA: Brak wystąpień."        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    ' Inicjowanie wartości zwracanej    ApplyFix = FALSE        strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";"    ' Sprawdanie błędów zostało celowo pominięte, aby nie przedłużać kodu    Set objConn = CreateObject("ADODB.Connection")    Set objCmd = CreateObject("ADODB.Command")    Set objCmd1 = CreateObject("ADODB.Command")        ' Otwieranie połączenia z wzorcem bazy danych    objConn.Open strConn     If ErrorOccurred("Błąd: nie można nawiązać połączenia z " + strInstance) Then        Set objConn = Nothing        Exit Function    End If    ' Sprawdzanie wersji przed zastosowaniem poprawki    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("BŁĄD: nie można wykonać polecenia """ + strCommand + """ dla " + strInstance) = TRUE Then        objConn.Close()        Set objConn = Nothing        ApplyFix = FALSE        Exit Function       End If    strBuildVersion = objRS("version")    strProductLevel = UCase(objRS("productlevel"))    bApplyFix = FALSE    ' Zastosowanie obejścia tylko dla wersji SQL 2000 i SQL 2005 (RTM, SP1 i 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 = "deny execute on sp_replwritetovarbin to public"        objCmd1.ActiveConnection = objConn        objCmd1.CommandType = adCmdText        objCmd1.CommandText = strCommand        Set objRS1 = objCmd1.Execute()        If ErrorOccurred("BŁĄD: nie można wykonać polecenia """ + strCommand + """ dla " + strInstance) = FALSE Then            WScript.Echo "INFORMACJA: pomyślnie zastosowano obejście dla wystąpienia " + strInstance + " (" + strBuildVersion + ")." + vbCRLF            ApplyFix = TRUE        End If    Else        WScript.Echo "INFORMACJA: pomijanie gromadzenia informacji dla wystąpienia " + strInstance + " (" + strBuildVersion + "), ponieważ nie dotyczy go problem." + 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    'Połączenie z usługą WMI i pobranie obiektu do klasy 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("BŁĄD: nie można nawiązać połączenia z obszarem nazw WMI " + DEFAULTNAMESPACE) Then        GetRegValue = FALSE        Exit Function    End If     lRc = 0    Select Case iValueType        ' Chodzi tylko o wartość 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 "BŁĄD: 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")    ' Query Cluster service    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        ' Osiągnięcie tego miejsca oznacza, że komputer jest węzłem klastrowanym.    ' Dlatego należy wykonać kwerendę w rejestrze sprawdzającą, czy wystąpienie programu SQL jest klastrowane.    ' Dla wersji SQL 2000 kwerenda powinna dotyczyć następującej wartości:    ' HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<nazwa_wystąpienia>\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    ' Kwerenda zwracająca wartości rejestru dla wystąpień programu SQL 2005/2008    '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        ' Jeśli ten klucz nie istnieje, przyjmowane jest założenie, że jest to lokalne wystąpienie programu 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
Aby uzyskać więcej informacji o programie CScript.exe, odwiedź następującą witrynę firmy Microsoft w sieci Web: Uwaga Nie zaleca się korzystania z tego skryptu w przypadku zainstalowania wydanej aktualizacji zabezpieczeń.
ZNANE PROBLEMY MOGĄCE WYSTĄPIĆ PO URUCHOMIENIU TEGO SKRYPTU

Problem 1

Komunikat o błędzie po uruchomieniu skryptu:
BŁĄD: nie można wykonać polecenia "deny execute on sp_replwritetovarbin to public" dla <nazwa_wystąpienia>
BŁĄD: 0x-2147217900 - Nie można odnaleźć obiektu „sp_replwritetovarbin”, ponieważ obiekt nie istnieje lub nie masz do niego uprawnień dostępu.
BŁĄD: nie można zastosować obejścia dla wystąpienia <nazwa_wystąpienia>.

Przyczyna 1

Ten komunikat o błędzie pojawia się w przypadku braku uprawnień wymaganych do wprowadzenia zmiany. Oznacza on, że udało się pomyślnie zalogować do wystąpienia <nazwa_wystąpienia>.

Ten błąd występuje zwykle w programie SQL Server Express, w którym grupa „Built-In\Users” ma domyślnie uprawnienia do logowania w bazie danych. Nie ma ona jednak uprawnień roli sysadmin.

Ten komunikat o błędzie może także pojawić się po porzuceniu procedury sp_replwritetovarbin. Takie zalecenie zostało zgłoszone zewnętrznie. Firma Microsoft nie zaleca porzucania tej procedury składowanej. Zamiast tego zaleca się zastosowanie następującego rozwiązania.

Rozwiązanie 1

Upewnij się, że konto, z którego nawiązujesz połączenie, ma uprawnienia roli sysadmin w tym wystąpieniu bazy danych. Jeśli tak nie jest, dodaj nazwę użytkownika konta do grupy roli sysadmin lub użyj innego konta. W przypadku programu SQL Server 2005 i starszych wersji grupa „Built-in\Administrators” domyślnie należy do roli sysadmin. W systemach Windows Server 2008 i Windows Vista pamiętaj, aby uruchamiać ten skrypt z podniesionym poziomem uprawnień w wierszu polecenia.

Problem 2

Komunikat o błędzie po uruchomieniu skryptu w programie SQL Server 2005:
Błąd: nie można nawiązać połączenia z <nazwa_wystąpienia>
BŁĄD: 0x-2147217843 - Logowanie użytkownika <użytkownik> nie powiodło się.
BŁĄD: nie można zastosować obejścia dla wystąpienia <nazwa_wystąpienia>.

Przyczyna 2

Ten komunikat o błędzie pojawia się, gdy nie można połączyć się z wystąpieniem <nazwa_wystąpienia>, nawet jeśli to wystąpienie istnieje.

Ten błąd występuje zwykle w przypadku połączenia z wystąpieniem wewnętrznej bazy danych systemu Windows lub bazy danych programu Microsoft SQL Server 2000 Desktop Edition (Windows). Najczęściej żadne konta użytkowników nie mają uprawnień do logowania do tych baz danych.

Rozwiązanie 2

Upewnij się, że konto, z którego uruchamiasz skrypt, ma uprawnienia do logowania w bazie danych na poziomie roli sysadmin.

Nie zaleca się dodawania pojedynczych użytkowników do wewnętrznej bazy danych systemu Windows lub do bazy danych programu Microsoft SQL Server 2000 Desktop Edition (Windows). Dodanie użytkowników może zakłócić normalne działanie tych baz danych. W takim przypadku należy pamiętać, aby nawiązywać połączenie z konta należącego do grupy roli sysadmin. W programie SQL Server 2005 i starszych wersjach grupa „Built-in\Administrators” w systemie Windows zazwyczaj domyślnie należy do roli sysadmin. W systemach Windows Server 2008 i Windows Vista pamiętaj, aby uruchamiać ten skrypt z podniesionym poziomem uprawnień w wierszu polecenia.

Problem 3

Może pojawić się wystąpienie bazy danych o nazwie MICROSOFT##SSEE. Taka baza danych nie została jednak zainstalowana.

Przyczyna 3

Ta baza danych to wewnętrzna baza danych systemu Windows (inne jej nazwy to SQL Server Embedded Edition lub Microsoft SQL Server 2000 Desktop Edition). Jest ona instalowana wraz z niektórymi produktami firmy Microsoft, na przykład z programem SharePoint Services.

Rozwiązanie 3

Skrypt obejścia został zaprojektowany pod kątem współpracy z wewnętrzną bazą danych systemu Windows. Nie jest wymagana żadna akcja ze strony użytkownika.

Niektóre aplikacje podczas dezinstalacji nie usuwają wewnętrznej bazy danych systemu Windows. Aby uzyskać więcej informacji dotyczących usuwania wewnętrznej bazy danych systemu Windows, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Microsoft Knowledge Base:
920277 Wewnętrzna baza danych systemu Windows nie jest wymieniona na liście narzędzia Dodaj lub usuń programy i nie jest usuwana po usunięciu z komputera programu Windows SharePoint Services 3.0 (j. ang.)

Problem 4

Komunikat o błędzie po uruchomieniu skryptu:
Błąd: nie można nawiązać połączenia z .\<nazwa_wystąpienia>
BŁĄD: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]Serwer SQL nie istnieje lub odmówiono do niego dostępu.

Przyczyna 4

Ten komunikat o błędzie jest wyświetlany, gdy są spełnione następujące warunki:
  • W 64-bitowym systemie operacyjnym jest zainstalowana 32-bitowa wersja programu SQL Server 2000.
  • Na komputerze jest zainstalowana 64-bitowa wersja programu SQL Server 2005 lub SQL Server 2008.
Ten błąd występuje, gdy skrypt używa 64-bitowej wersji pliku dbmslpcn.dll. Ta wersja nie komunikuje się z wystąpieniami programu SQL Server 2000 w trybie WoW.

Rozwiązanie 4

Należy uruchomić skrypt przy użyciu 32-bitowej wersji pliku cscript.exe z folderu %WINDOWS%\SysWOW64. Zostanie wówczas załadowana 32-bitowa wersja pliku dbmslpcn.dll, która wykrywa wystąpienia w trybie WoW.
Materiały referencyjne
Aby uzyskać więcej informacji dotyczących sposobu ustalania wersji i wydania programu SQL Server, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Microsoft Knowledge Base:
321185 JAK: Identyfikowanie wersji i wydania dodatku Service dla programu SQL Server
Więcej informacji
W poniższej tabeli wymieniono ważne poprawki techniczne w tym artykule. Numer poprawki i data ostatniej korekty tego artykułu mogą dotyczyć drobnych poprawek redakcyjnych lub strukturalnych, które nie zostały wymienione w tabeli.
DataPoprawki
31 grudnia 2008Zaktualizowany skrypt wykrywa wystąpienia programu SQL Server w ramach klastra pracy awaryjnej.
30 grudnia 2008Zaktualizowany skrypt wykrywa 32-bitowe wersje programu SQL Server działające w 64-bitowych wersjach systemu Windows.
aktualizacja poprawka_zabezpieczeń aktualizacja_zabezpieczeń zabezpieczenia usterka luka złośliwy atakujący wykorzystać rejestr nieuwierzytelniony bufor przekroczenie przepełnienie specjalnie_uformowany zakres specjalnie_przygotowany odmowa usługi
Właściwości

Identyfikator artykułu: 961040 — ostatni przegląd: 01/06/2009 15:41:05 — zmiana: 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
Opinia
t=">