Microsoft Güvenlik Danışma Belgesi: SQL Server'daki güvenlik açığı uzaktan kod yürütülmesine izin verebilir

GİRİŞ

Microsoft, Microsoft SQL Server'da uzaktan kod yürütülmesine izin verebilecek bir güvenlik açığına yönelik bir güvenlik danışma belgesi yayımladı. Güvenlik danışma belgesi, güvenlikle ilgili ek bilgiler içerir. Güvenlik danışma belgesini görüntülemek için şu Microsoft Web sitesini ziyaret edin: Bu makale, bir yerel bilgisayarda çalıştırılan tüm SQL Server örneklerine geçici çözümü uygulamak üzere kullanabileceğiniz bir VB komut dosyası içermektedir.

GEÇİCİ ÇÖZÜMÜ UYGULAMAK İÇİN KULLANABİLECEĞİNİZ VB KOMUT DOSYASI ÖRNEĞİ

SQL Server'ın yerel bilgisayarda çalışan ve bu sorundan etkilenen tüm sürümlerinde sp_replwritetovarbin genişletilmiş saklı yordamına ilişkin Genel rolünün Yürütme iznini reddetmek için bu VB komut dosyasını kullanabilirsiniz.

Microsoft, programlama örneklerini yalnızca gösterim amacıyla sağlar; örtülü veya açık garanti vermez. Buna satılabilirlik veya belirli bir amaca uygunluk zımni garantileri de dahildir, ancak bunlarla sınırlı değildir. Bu makale, gösterilen programlama dilini ve yordamları oluşturmak ve hata ayıklamak amacıyla kullanılan araçları kullanmayı bildiğinizi varsayar. Microsoft destek mühendisleri, belirli bir yordamın işlevselliğinin açıklanmasına yardımcı olabilir. Ancak gereksinimlerinizi karşılamaya yönelik olarak ek işlevsellik sağlamak veya yordamlar geliştirmek amacıyla bu örnekleri değiştirmezler.


Bu kodu bir metin dosyasına kopyalayın, dosyayı kaydederken .vbs dosya adı uzantısını kullanın ve ardından CScript.exe'yi kullanarak komut dosyasını çalıştırın. Komut dosyası SQL Server'ın yerel bilgisayarda çalışan örneklerini tek tek inceleyerek etkilenen sürümlere geçici çözümü uygular. Bu geçici çözümü uygulamak için SQL Server'ın her bir örneğinde sysadmin rolünün üyesi olmanız gerekmektedir. SQL Server çalıştıran ve sorundan etkilenen tüm sunucularda sysadmin rolünün üyesi olan bir Windows hesabınız yoksa, bu komut dosyasını birden fazla hesap kullanarak çalıştırmanız gerekebilir. Windows Server 2008 ve Windows Vista'da, sysadmin rolünün üyesi olan bir Windows yönetici hesabınız varsa, bu komut dosyasını “yükseltilmiş” komut isteminden çalıştırmanız gerekir.
'*************************************************************************************
'Açıklama: Bu komut dosyası SQL Server'ın tüm çalışan örneklerini sırayla dolaşır
' ve tüm etkilenen sürümlerde Public rolü için sp_replwritetovarbin genişletilmiş
' saklı yordamındaki Execute iznini reddeder.
' BU BİR GEÇİCİ ÇÖZÜM OLARAK SAĞLANMAKTADIR VE BİR GÜVENLİK GÜNCELLEŞTİRMESİ
' SAĞLANMIŞ VE YÜKLENMİŞSE KULLANILMAMALIDIR.
'*************************************************************************************

OPTION EXPLICIT
ON ERROR RESUME NEXT

' Sabit değerler
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 "BİLGİ: Hiçbir örnek yok.
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 "HATA: Geçici çözüm şu örnekte uygulanamadı: " + sInstances(i,0) + "." + vbCRLF
VBMain = EXIT_FAILURE
End If
Next

WScript.Echo "BİLGİ: Çalışır durumdaki tüm SQL örneklerinin işlenmesi tamamlandı."
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 "HATA: Makinede yüklü SQL örnekleri okunamadı."
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 "HATA: Makinede yüklü SQL örnekleri okunamadı."
Exit Function
End If
End If

If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then
WScript.Echo "BİLGİ: Örnek yok."
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

' Döndürülen değeri başlatın
ApplyFix = FALSE

strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";"
' Kodu kısa turmak için hata denetimi yapılmamaktadır
Set objConn = CreateObject("ADODB.Connection")
Set objCmd = CreateObject("ADODB.Command")
Set objCmd1 = CreateObject("ADODB.Command")

' Ana Veritabanı için bir Bağlantı açın
objConn.Open strConn
If ErrorOccurred("Hata: " + strInstance örneğine bağlanılamadı) Then
Set objConn = Nothing
Exit Function
End If

' Düzeltmeyi uygulamadan önce sürümü doğrulayın
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("HATA: """ + strCommand + """ yürütülemedi (" + strInstance üzerinde)) = TRUE Then
objConn.Close()
Set objConn = Nothing
ApplyFix = FALSE
Exit Function
End If

strBuildVersion = objRS("version")
strProductLevel = UCase(objRS("productlevel"))

bApplyFix = FALSE
' Geçici çözümü yalnızca SQL 2000 ve SQL 2005 (RTM, SP1 ve SP2) sürümlerine uygulayın
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("HATA: """ + strCommand + """ yürütülemedi (" + strInstance üzerinde)) = FALSE Then
WScript.Echo "BİLGİ: Geçici çözüm, " + strInstance + " (" + strBuildVersion + ") üzerine başarıyla uygulandı." + vbCRLF
ApplyFix = TRUE
End If
Else
WScript.Echo "BİLGİ: " + strInstance + " (" + strBuildVersion + ") örneği güvenlik açığından etkilenmediği için bilgi toplama işlemi atlanıyor." + 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

'WMI'ya bağlanıp STDREGPROV sınıfı için bir nesne alın.
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 ("HATA: WMI ad alanına bağlanılamadı: " + DEFAULTNAMESPACE) Then
GetRegValue = FALSE
Exit Function
End If

lRc = 0
Select Case iValueType
' Yalnızca REG_MULTI_SZ önemlidir
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 "HATA: 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")

' 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

' Buraya ulaşıldığında makinenin kümelenmiş bir düğüm olduğu anlaşılır.
' Bu yüzden SQL örneğinin kümelenmiş olup olmadığını anlamak için kayıt defterini sorgulamak gerekir.
' SQL 2000 için şu değeri sorgulayın
' 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

' 2005/2008 örnekleri için kayıt defteri değerini sorgulamayı deneyelim
'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
' Bu anahtar yoksa, SQL 2000 yerel örneği olarak geri dönülsün
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
CScript.exe hakkında daha fazla bilgi için, aşağıdaki Microsoft Web sitesini ziyaret edin: Not Bir güvenlik güncelleştirmesi sağlandıysa ve bu güncelleştirmeyi yüklediyseniz bu komut dosyasını kullanmanızı önermiyoruz.

BU KOMUT DOSYASINI ÇALIŞTIRDIĞINIZDA OLUŞABİLECEĞİ BİLİNEN SORUNLAR

Sorun 1

Komut dosyasını çalıştırdığınızda, şu hata iletisini alıyorsunuz:
HATA: "deny execute on sp_replwritetovarbin to public" yürütülemedi (<örnekadı> üzerinde)
HATA: 0x-2147217900 - 'sp_replwritetovarbin' nesnesi var olmadığı veya izniniz olmadığı için bulunamadı.
HATA: Geçici çözüm <örnekadı> üzerinde uygulanamıyor.

Neden 1

Değişikliği uygulamak için gerekli izinlere sahip değilseniz bu hata iletisini alırsınız. Bu hata iletisi, "<örnekadı>" örneğinde oturum açma girişiminizin başarısız olduğunu gösterir.


Bu hata iletisi genellikle "Built-In\Users" grubunun varsayılan olarak veritabanında oturum açma izninin bulunduğu SQL Server Express'te ortaya çıkar. Ancak, bu grup sysadmin rolünün üyesi değildir.

Bu hata iletisi, sp_replwritetovarbin yordamını sonlandırdıysanız da oluşabilir. Bu, üçüncü taraflara ait bir bildirimdeki öneriydi. Saklı yordamın sonlandırılmasını önermiyoruz. Bunun yerine bu çözümü uygulamanızı öneriyoruz.

Çözüm 1

Bağlanırken kullandığınız hesabın veritabanının ilgili örneğinde sysadmin rolünün üyesi olduğundan emin olun. Hesap bir üye değilse, bağlanmak için kullandığınız kullanıcıyı sysadmin rolüne ekleyin veya başka bir kullanıcı hesabı kullanın. SQL Server 2005 ve önceki sürümler için, "Built-in\Administrators" grubu varsayılan olarak sysadmin rolünün bir üyesidir. Bu komut dosyasını Windows Vista veya Windows Server 2008 üzerinde çalıştırırken, “yükseltilmiş” komut istemini kullandığınızdan emin olun.

Sorun 2

Bu komut dosyasını SQL Server 2005'te çalıştırdığınızda şu hata iletisini alıyorsunuz:
Hata: <örnekadı> örneğine bağlanılamadı
HATA: 0x-2147217843 - '<user>' kullanıcısı için oturum açma başarısız oldu.
HATA: Geçici çözüm <örnekadı> üzerinde uygulanamıyor.

Neden 2

Bu hata iletisini, "<örnekadı>" örneği var olmasına karşın bu örneğe bağlanamazsanız alırsınız.


Bu hata iletisi genelde Windows Internal Database veya Microsoft SQL Server 2000 Desktop Edition (Windows) örneklerine bağlanırken oluşur. Genellikle hiçbir kullanıcı hesabının bu veritabanlarında oturum açma izni yoktur.

Çözüm 2

Komut dosyasını çalıştırmak için kullandığınız hesabın sysadmin rolünün üyesi olduğundan ve veritabanında oturum açma izni bulunduğundan emin olun.

Windows İç Veritabanı'na ve Microsoft SQL Server 2000 Desktop Edition (Windows) veritabanlarına kullanıcı eklemenizi önermiyoruz. Bunu yaparsanız eklediğiniz kullanıcılar bu veritabanlarının olağan çalışmasını etkileyebilir. Bu durumda sysadmin rolünün üyesi olan bir hesabı kullanarak bağlandığınızdan emin olun. Windows'daki "Built-in\Administrators" grubu SQL Server 2005'te ve önceki sürümlerde genellikle varsayılan olarak sysadmin rolünün üyesidir. Bu komut dosyasını Windows Vista veya Windows Server 2008 üzerinde çalıştırdığınızda, "yükseltilmiş" komut istemini kullandığınızdan emin olun.

Sorun 3

MICROSOFT##SSEE adında bir veritabanı örneği bulunduğu dikkatinizi çekebilir. Ancak bu veritabanını siz yüklemediniz.

Neden 3

Bu veritabanı Windows İç Veritabanı'dır, aynı zamanda "SQL Server Embedded Edition" olarak bilinir veya bazen "Windows İç Veritabanı" veya "Microsoft SQL Server 2000 Desktop Edition (Windows)" olarak da adlandırılır. SharePoint Services gibi bazı Microsoft ürünleriyle birlikte yüklenir.

Çözüm 3

Geçici çözümde kullanılan komut dosyası, Windows Internal Database ile birlikte çalışacak biçimde tasarlanmıştır. Herhangi bir işlem yapmanız gerekmez.

Bazı uygulamalar kaldırıldığında Windows Internal Database de kaldırılmaz.
Windows Internal Database'i kaldırma hakkında daha fazla bilgi için, Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
920277 Windows İç Veritabanı Program Ekle veya Kaldır aracında listelenmez ve Windows SharePoint Services 3.0'ı bilgisayarınızdan kaldırdığınızda kaldırılmaz (Bu bağlantı, bir kısmı veya tamamı İngilizce olan içeriğe işaret edebilir)

Sorun 4

Komut dosyasını çalıştırdığınızda, aşağıdaki hata iletisini alıyorsunuz:

Hata: .\<örnekadı> örneğine bağlanılamadı
HATA: 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]SQL Server yok veya erişim reddedildi.

Neden 4

Aşağıdaki koşullar doğru olduğunda bu hata iletisini alabilirsiniz:
  • SQL Server 2000'in x64-bit işletim sistemine yüklü 32 bit sürümünü kullanıyorsunuz.
  • Bilgisayarınızda SQL Server 2005'in veya SQL Server 2008'in 64-bit sürümü yüklü.

Bu hata iletisi, komut dosyası dbmslpcn.dll dosyasının 64 bit sürümünü kullanıyorsa ortaya çıkar. Bu sürüm SQL Server 2000'in WoW örnekleriyle iletişim kuramaz.

Çözüm 4

Komut dosyasını başlatmak için cscript.exe dosyasının %WINDOWS%\SysWOW64 klasöründeki 32 bit sürümünü başlatın. Bu işlemde dbmslpcn.dll dosyasının WoW örnekleri algılayabilen 32 bit sürümü yüklenir.

Referanslar

SQL Server sürümünüzü belirleme hakkında daha fazla bilgi için, Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
321185 SQL Server sürümünüzü nasıl belirleyebilirsiniz

Daha fazla bilgi

Aşağıdaki tabloda, bu makalede yapılan önemli teknik düzenlemeler listelenmektedir. Bu makalenin sürüm numarası ve son düzenleme tarihi, tabloda yer almayan içerik için bu makalede küçük düzenlemeler veya yapısal değişiklikler içerebilir.
TarihDüzenlemeler
31 Aralık 2008SQL Server yük devretme kümelemesi örneklerini algılayan güncelleştirilmiş bir komut dosyası içerir.
30 Aralık 2008SQL Server'ın Windows'un 64 bit sürümlerinde çalışan 32 bit sürümlerini algılayan güncelleştirilmiş bir komut dosyası içerir.
Özellikler

Makale No: 961040 - Son İnceleme: 6 Oca 2009 - Düzeltme: 1

Geri bildirim