מבוא

Microsoft פרסמה עלון יידוע בנושא אבטחה אודות פגיעות ב- Microsoft SQL Server אשר עלולה לאפשר ביצוע קוד מרחוק. עלון היידוע כולל תוספת מידע בנושא אבטחה. כדי להציג את עלון היידוע בנושא אבטחה, בקר באתר האינטרנט הבא של Microsoft:

http://www.microsoft.com/technet/security/advisory/961040.mspx מאמר זה כולל VB script שבאפשרותך להשתמש בו כדי להחיל פתרון עוקף על כל המופעים הפועלים של SQL Server במחשב מקומי.

דוגמה של VB SCRIPT שבאפשרותך להשתמש בו כדי להחיל את הפתרון העוקף

באפשרותך להשתמש ב- VB script זה כדי למנוע הרשאת ביצוע לתפקיד הציבורי בפרוצדורה המאוחסנת המורחבת sp_replwritetovarbin בכל הגירסאות המושפעות של SQL Server הפועלות במחשב המקומי.Microsoft מספקת את דוגמאות התכנות שלהלן להמחשה בלבד וללא כל אחריות, בין מפורשת ובין משתמעת, ובכלל זה, אך לא רק, אחריות לגבי סחירות או התאמה למטרה מסוימת. מאמר זה מבוסס על ההנחה שאתה מכיר את שפת התכנות המודגמת ובקי בהפעלת הכלים המשמשים ליצירת פרוצדורות ולניפוי שגיאות. מהנדסי התמיכה של Microsoft יכולים לסייע להסביר את הפונקציונליות של הליך מסוים. עם זאת, הם לא ישנו דוגמאות אלה כדי לספק פונקציונליות נוספת או יבנו הליכים כדי לספק מענה לצרכיך הספציפיים. העתק קוד זה לקובץ טקסט, שמור את הקובץ תוך שימוש בסיומת שם קובץ .vbs ולאחר מכן הפעל את קובץ ה- script באמצעות CScript.exe. ה- script סובב בין המופעים הפועלים של SQL Server במחשב המקומי ומחיל את הפתרון העוקף על הגירסאות המושפעות. עליך להיות חבר בתפקיד מנהל מערכת בכל מופע של SQL Server כדי להחיל את הפתרון העוקף. אם אין לך חשבון Windows החבר בתפקיד מנהל מערכת בכל השרתים המושפעים שבהם פועלת התוכנית SQL Server, ייתכן שיהיה עליך להפעיל script זה ממספר חשבונות. ב- Windows Server 2008 וב- Windows Vista, אם אתה משתמש בחשבון מנהל של Windows החבר בתפקיד מנהל מערכת, עליך להפעיל script זה משורת פקודה "גבוהה".

'*************************************************************************************'תיאור: script זה סובב סביב כל המופעים הפועלים של SQL Server'            ומונע הרשאת ביצוע ב- sp_replwritetovarbin לציבור בכל'            הגירסאות המושפעות.'            מסופק כפתרון עוקף ואינו מיועד לשימוש במקרה '            שעדכון אבטחה מסופק ומותקן.'*************************************************************************************OPTION EXPLICITON ERROR RESUME NEXT' ערכי ConstantCONST 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: No instances are present."        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 "ERROR: Could not apply the workaround on " + sInstances(i,0) + "." + vbCRLF            VBMain = EXIT_FAILURE        End If    הבא    WScript.Echo "INFO: Completed processing all the running SQL instances."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 "ERROR:Failed to read SQL instances installed on the machine."        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 "ERROR:Failed to read SQL instances installed on the machine."            Exit Function        End If    End If    If IsEmptyNull(sInstances1) AND IsEmptyNull(sInstances2) Then         WScript.Echo "INFO: No instances present."        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        הבא    End If    If instCount2 >0 Then        For i = 0 To UBound(sInstances2)            sInstances(i+instCount1,0) = sInstances2(i)            sInstances(i+instCount1,1) = FALSE        הבא    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    ' Initialize return value    ApplyFix = FALSE    strConn = "Provider=sqloledb;Initial Catalog=master;Integrated Security=SSPI;Data Source=" + strServerName + ";"    ' Error checking is intentionally left to keep the code short    Set objConn = CreateObject("ADODB.Connection")    Set objCmd = CreateObject("ADODB.Command")    Set objCmd1 = CreateObject("ADODB.Command")    ' Open a Connection to the master Database    objConn.Open strConn     If ErrorOccurred("Error: Could not connect to " + strInstance) Then        Set objConn = Nothing        Exit Function    End If    ' Validate the version before applying the fix    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("ERROR: Could not execute """ + strCommand + """ on " + strInstance) = TRUE Then        objConn.Close()        Set objConn = Nothing        ApplyFix = FALSE        Exit Function    End If    strBuildVersion = objRS("version")    strProductLevel = UCase(objRS("productlevel"))    bApplyFix = FALSE    ' Apply the workaround only for SQL 2000 and SQL 2005 (RTM, SP1 and SP2) versions    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("ERROR: Could not execute """ + strCommand + """ on " + strInstance) = FALSE Then            WScript.Echo "INFO: Successfully applied the workaround on " + strInstance + " (" + strBuildVersion + ")." + vbCRLF            ApplyFix = TRUE        End If    Else        WScript.Echo "INFO: Skipping collecting information for " + strInstance + " (" + strBuildVersion + ") as this instance is not vulnerable." + 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    'Connect to WMI and get an object to STDREGPROV class.    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("ERROR: Could not connect to WMI namespace " + DEFAULTNAMESPACE) Then        GetRegValue = FALSE        Exit Function    End If     lRc = 0    Select Case iValueType        ' We only care about 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 "ERROR: 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        הבא    End If    Set objServices = Nothing    Set objClusters = Nothing    If isEmpty = TRUE Then        strInstanceName = BuildInstanceName (".", strInstanceName)        Exit Function    End If    ' If we reach here that means the machine is a clustered node.    ' So lets query registry to determine whether the SQL instance is clustered or not.    ' For SQL 2000 query the following value    ' 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    ' Lets try querying the registry value for 2005/2008 instances    '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        ' If this key doesnt exist, then return back as a SQL 2000 local instance        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

למידע נוסף אודות CScript.exe, בקר באתר האינטרנט הבא של Microsoft:

http://technet.microsoft.com/en-us/library/bb490887.aspxהערה מומלץ שלא תשתמש ב- script זה אם סופק עדכון אבטחה והתקנת אותו.

בעיות מוכרות שעלולות להתרחש בעת הפעלת SCRIPT זה

בעיה 1

בעת הפעלת script זה, תקבל הודעת שגיאה זו:

:ERROR Could not execute "deny execute on sp_replwritetovarbin to public" on <instancename> :ERROR 0x-2147217900 - Cannot find the object 'sp_replwritetovarbin', because it does not exist or you do not have permission.(אין אפשרות למצוא את האובייקט 'sp_replwritetovarbin', מכיוון שאינו קיים או שאין לך הרשאה). :ERROR Could not apply the workaround on <instancename>.(אין אפשרות להחיל את הפתרון העוקף על [שם המופע]).

סיבה 1

אתה מקבל הודעת שגיאה זו אם אין לך את ההרשאות הדרושות להחלת השינוי. הודעת שגיאה זו מציינת שלא הצלחת להיכנס בהצלחה למופע "<instancename>".הודעת שגיאה זו מתרחשת בדרך כלל ב- SQL Server Express שבה הקבוצה "Built-In\Users" כוללת כניסה למסד הנתונים כברירת מחדל. עם זאת, קבוצה זו אינה חברה בתפקיד מנהל המערכת. כמו כן, הודעת שגיאה זו עלולה להתרחש אם שחררת את הפרוצדורה sp_replwritetovarbin זו היתה ההמלצה מדוח של ספק חיצוני. Microsoft אינה ממליצה על שחרור הפרוצדורה המאוחסנת. במקום זאת, מומלץ להחיל פתרון זה.

פתרון 1

ודא שהחשבון שאליו אתה מתחבר הוא חבר בתפקיד מנהל המערכת במופע זה של מסד הנתונים. אם החשבון אינו חבר, הוסף את המשתמש שאתה מחבר לתפקיד מנהל המערכת, או השתמש בחשבון של משתמש אחר. עבור SQL Server 2005 וגירסאות קודמות, הקבוצה "Built-in\Administrators" היא חברה בתפקיד מנהל המערכת כברירת מחדל. כאשר אתה מפעיל script זה ב- Windows Vista או ב- Windows Server 2008, ודא שאתה מפעיל אותו משורת פקודה "גבוהה".

בעיה 2

אם אתה מפעיל script זה ב- SQL Server 2005, אתה מקבל את הודעת השגיאה הבאה:

Error: Could not connect to <instancename> (אין אפשרות להתחבר ל[שם המופע]). :ERROR 0x-2147217843 - Login failed for user '<user>'. (כניסה נכשלה עבור המשתמש [שם משתמש]) :ERROR Could not apply the workaround on <instancename>.(אין אפשרות להחיל את הפתרון העוקף על [שם המופע]).

סיבה 2

אתה מקבל הודעת שגיאה זו אם לא הצלחת להתחבר למופע ">instancename<" על-אף שמופע זה קיים.הודעת שגיאה זו מופיעה בדרך כלל כאשר אתה מתחבר למופעים של Windows Internal Database או שלMicrosoft SQL Server 2000 Desktop Edition (Windows). בדרך כלל, לאף חשבון משתמש אין כניסה למסדי נתונים אלה.

פתרון 2

ודא שלחשבון שבו אתה משתמש כדי להפעיל את ה- script יש כניסה למסד הנתונים החבר בתפקיד מנהל המערכת. לא מומלץ להוסיף משתמשים בודדים למסדי נתונים של Windows Internal Database ושלMicrosoft SQL Server 2000 Desktop Edition (Windows). אם תעשה זאת, המשתמשים שתוסיף עלולים להפריע לפעילותם הסדירה של מסדי נתונים אלה. במקרה זה, ודא שאתה מתחבר מחשבון החבר בתפקיד מנהל המערכת. הקבוצה "Built-in\Administrators" ב- Windows היא חברה בתפקיד מנהל המערכת כברירת מחדל עבור SQL Server 2005 וגירסאות קודמות. כאשר אתה מפעיל script זה ב- Windows Vista או ב- Windows Server 2008, ודא שאתה מפעיל אותו משורת פקודה "גבוהה".

בעיה 3

ייתכן שתראה מופע של מסד נתונים ששמו MICROSOFT##SSEE. אולם לא התקנת מסד נתונים זה.

סיבה 3

מסד נתונים זה הוא Windows Internal Database, הידוע גם בשם "SQL Server Embedded Edition" או לעתים מכונה גם "Windows Internal Database" או "Microsoft SQL Server 2000 Desktop Edition (Windows)". הוא מותקן עם כמה מוצרים מאת Microsoft, ביניהם SharePoint Services.

פתרון 3

ה- script של הפתרון העוקף מיועד לפעול עם Windows Internal Database. אין צורך בפעולה מצדך. מספר יישומים אינם מסירים את Windows Internal Database כאשר התקנתם מוסרת. לקבלת מידע נוסף אודות אופן ההסרה של Windows Internal Database, לחץ על מספר המאמר שלהלן כדי להציגו מתוך מאגר הידע Microsoft Knowledge Base:

920277 Windows Internal Database אינו מופיע ברשימה של הכלי הוספה/הסרה של תוכניות ואינו מוסר כאשר אתה מסיר את Windows SharePoint Services 3.0 מהמחשב. (ייתכן שקישור זה מפנה לתוכן שחלק ממנו או כולו מופיע באנגלית)

בעיה 4

בעת הפעלת script זה, תקבל הודעת שגיאה זו:

Error: Could not connect to .\<instancename>‎ (אין אפשרות להתחבר ל[שם המופע]).:ERROR 0x-2147467259 - [DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied ‏(SQL Server אינו קיים או שהגישה נדחתה)

סיבה 4

הודעת שגיאה זו מופיעה כאשר התנאים הבאים מתקיימים:

  • גירסת 32 סיביות של SQL Server 2000 מותקנת במערכת הפעלה של 64 סיביות.

  • במחשב שלך מותקנת גירסת 64 סיביות של SQL Server 2005 או של SQL Server 2008.

הודעת שגיאה זו מופיעה כאשר קובץ Script משתמש בגירסת 64 הסיביות של הקובץ dbmslpcn.dll. לגירסה זו אין אפשרות לנהל תקשורת עם מופעי WoW של SQL Server 2000.

פתרון 4

השתמש בגירסת 32 סיביות של הקובץ cscript.exe שנמצא בתיקיה ‎%WINDOWS%\SysWOW64 כדי להפעיל את קובץ ה- Script. פעולה זו טוענת את גירסת 32 הסיביות של הוקבץ dbmslpcn.dll, שיכולה לזהות מופעי WoW.

מידע נוסף

לקבלת מידע נוסף כיצד לזהות את הגירסה והמהדורה של SQL Server, לחץ על מספר המאמר שלהלן כדי להציג את המאמר ב-Microsoft Knowledge Base:

321185כיצד לזהות את הגירסה והמהדורה של SQL Server

מידע נוסף

בטבלה הבאה רשומים שינויים טכניים משמעותיים שנעשו במאמר זה. מספר המהדורה ותאריך הסקירה במאמר זה עשויים להצביע על שינויי עריכה או שינויי מבנה קטנים במאמר זה שאינם כלולים בטבלה.

תאריך

מהדורות

31 בדצמבר 2008

כולל קובץ Script מעודכן המזהה מופעי אשכולות של מעבר לגיבוי בעת כשל של SQL Server.

30 בדצמבר 2008

כולל קובץ Script מעודכן המזהה גירסאות 32 סיביות של SQL Server שמפעילות גירסאות 64 סיביות של Windows.

זקוק לעזרה נוספת?

מעוניין באפשרויות נוספות?

גלה את יתרונות המנוי, עיין בקורסי הדרכה, למד כיצד לאבטח את המכשיר שלך ועוד.