2007.8月號-163期 程式開發安全自我評量解答  解答名師/王寧疆、楊志強

◎科目:程式

維繫資訊系統的安全性,很多層面都要依靠妥善保護機密資料才不會為原本相當安全的系統創造出原可避免的安全性漏洞。最常見的機密資料就是登入系統的密碼,當然要經由網路傳送到其他的電腦的機密資料,例如信用卡卡號和身分証字號,都是需要加以保護的對象。

在這一期的題目中,我們專門為保護機密資料相關的課題設計了5個題目,測驗讀者對妥善保護機密資料的動作是否具備正確的觀念。

正確答案:C

說明:
將密碼抄在個人記事本上並非是很安全的做法,因為如果記事本遺失或是被偷窺,機密資料就會有洩露的危險。很多粗心的使用者因為記不住登入系統的密碼,為求方便,將密碼抄在紙上,再將抄有密碼的紙貼在電腦的螢幕上,雖然需要登入系統的時候,只要抬頭看一下螢幕,就可以看到登入電腦需要的密碼,但是有心人士想要登入你的電腦,同樣可以利用螢幕上貼的密碼內容,成功地登入系統,造成電腦的登入管制功能形同虛設,是最要不得的做法。保管登入系統密碼最好的做法是只記在腦袋中,不要形諸於文字,並記載在任何有機會被其他人看到的地方,避免機密資料外洩。將登入系統的密碼設定成和登入系統的帳號一樣的內容避免忘記,去除登入系統的障礙,也是需要特別禁止的做法,因為當駭客要入侵系統的時候,通常都會使用和帳號一樣的內容當做密碼,嘗試入侵系統。如果要達到更佳的安全境界,最好連系統預設的管理員帳號,例如Administrator,和sa都禁用掉,避免駭客不需要猜測就可以得知使用者的帳號

正確答案:C

說明:
使用Microsoft Visual Studio程式開發工具開發的.NET應用程式和Java程式一樣都會翻譯成中間碼(Intermediate Code),而不是二進位碼。翻譯成中間碼的程式較翻譯成二進位碼的程式容易被還原成原始程式(Source Code),嚴重危害程式原作者的智慧財產,如果原始程式中存放有機密資料,例如登入資料庫的帳號與密碼,則只要程式被有心人士還原成原始程式,原始程式中的機密資料就會曝光,間接危害到系統的安全。

針對翻譯成中間碼的應用程式容易被還原成原始程式的問題,程式設計師可以利用一種叫做混淆器的工具,將原始程式編譯後得到的中間碼加上凌亂處理,使應用程式編譯後的中間碼被還原的難度變高,保障程式開發者的智慧財產。

對Visual Studio 2005程式開發工具的程式設計師而言,Visual Studio 2005提供的Dotfuscator Community Edition就是一個具有基本功能的中間碼混淆工具,可以將Visual Studio 2005編譯後的中間碼加上凌亂處理。不過請特別注意Visual Studio 2005附贈的Dotfuscator Community Edition並未提供對字串執行加密的功能,所以程式如果需要將機密資料(例如密碼)放在變數中的話,記得要使用功能比較進階,可以將字串內容加密的混淆器(例如Dotfuscator Professional Edition),以免應用程式被還原後,連機密資料都一併外洩。

要使用Visual Studio 2005附贈的Dotfuscator Community Edition混淆器處理編譯成中間碼的應用程式,可以先到C:\Program Files\Microsoft Visual Studio 8\Application\PreEmptive Solutions\Dotfuscator Community Edition\samples目錄下將檔案名稱為hello_config.xml的XML文件,複製到欲加上混淆處理的應用程式所在的目錄,然後將檔案內容中底下的<file></file>標籤的name屬性的內容值設定成應用程式的名稱,再將<mapoutput></mapoutput>底下的<file></file>標籤的name屬性的內容值也設定成應用程式的名稱。例如欲加上混淆處理的應用程式名稱為:WindowsApplication1.exe,給Dotfuscator Community Edition 混淆器使用的XML文件的內容就應該改成以下的樣子:

準備好給Dotfuscator Community Edition 混淆器使用的XML文件的內容之後,請選擇Visual Studio 2005的[工具 | Dotfuscator Community Edition]功能,啟動Dotfuscator Community Edition 混淆器,螢幕上就會出現如圖1的畫面:


圖1:Dotfuscator Community Edition 混淆器的啟動畫面


請按下圖1畫面中的[否,我不想註冊]鍵,關閉Dotfuscator Community Edition 混淆器的啟動畫面,螢幕上就會出現如圖2的畫面,要求你建立新專案,或是開啟現有專案。


圖2:要求你建立新專案,或是開啟現有專案的操作畫面


因為我們已經準備好Dotfuscator Community Edition混淆器需要的XML文件內容,所以請選擇圖2畫面中的[開啟現有專案]項目,螢幕上就會出現Dotfuscator Community Edition混淆器的執行畫面,如圖3所示。


圖3:Dotfuscator Community Edition混淆器的執行畫面


請選擇圖3畫面中的[檔案 | 建置]功能,表示要對專案的XML文件中指定的應用程式執行混淆處理,你就會看到如圖4的報告畫面,告訴你經過混淆處理後的統計數據。


圖4:應用程式經過混淆處理後的統計數據


請按下圖4畫面中的[確定]鍵關閉顯示統計資料的畫面,完成對應用程式執行混淆處理的動作。經過混淆處理的應用程式可以使用ildasm.exe工具檢視混淆後的內容,你可以執行[所有程式 | Microsoft .NET Framework SDK v2.0 | SDK命令提示字元]功能,開啟[SDK命令提示字元]視窗,並切換到經過混淆處理的應用程式所在的目錄底下名稱為output的子目錄,然後執行以下的命令(假設經過混淆處理的應用程式名稱叫做WindowsApplication1.exe):

C:\進行混淆處理的應用程式所在的目錄\output>ildasm WindowsApplication1.exe

表示要檢視經過混淆器處理過的.NET程式的內容,你將可以看到經過混淆器處理過的.NET程式的內容已經變成一堆由a,b,c,d,…之類的英文字母組成的內容,如圖5所示。


圖5:使用ildasm.exe工具檢視經過混淆器處理過的應用程式的內容的情形

經過混淆處理的.NET應用程式沒有辦法很容易地透過還原工具將已經編譯成中間碼的內容還原成原始碼的狀態,所以程式開發者的智慧財產可以得到比較好的保障,不過應用程式如果有將機密資料存在字串變數中,要記得使用可以將字串內容加密的混淆器對程式進行混淆處理。
 

正確答案:D

說明:
Microsoft .NET 2.0提供的SecureString類別可以用來儲存應用程式使用的機密資料,例如使用者的密碼就很適合存放到SecureString類別的物件中。存放到SecureString類別的物件中的機密資料會自動經過加密處理,而且SecureString類別的物件在被消滅時會將物件所佔用的記憶體的內容全部清除,就好像機密文件不再使用後會很謹慎地燒掉一樣,是安全性較佳的做法。

存放在SecureString類別的物件中的機密資料無法利用程式開發工具的偵錯功能進行檢視,也沒有辦法比較其內容是否和某個字串的內容相等,當然也不能經由ToString方法轉型後來觀察。以下就是使用SecureString類別存放使用者輸入的密碼的範例,假設使用者輸入到應用程式的密碼已經存放到名稱為txtPassword的控制項中,則程式可以先宣告一個用來儲存使用者輸入密碼的SecureString類別的物件,如下:

Private m_Password As SecureString = New System.Security.SecureString()

然後利用以下的迴圈讀出使用者的密碼內容,再逐字元地串連到SecureString類別的物件中存放,字串在串到SecureString類別的物件的過程中就會做好加密的處理:

做好之後請呼叫SecureString類別的MakeReadOnly方法,將SecureString類別的物件做成唯讀的內容,避免被惡意程式塗改,最後再把存放使用者密碼的TextBox控制項的內容清成0,以免留下任何可趁之機:

存放在SecureString類別的物件中的密碼可以不需要還原成加密之前的內容,而直接交給.NET 2.0的SymmetricKey、X509Certificate、Credentials、或是ProcessStartInfo等類別進行處理。如果應用程式有需要將存放在SecureString類別的物件中的密碼原成加密之前的內容,還是可以透過Marshal類別的SecureStringToGlobalAllocUnicode方法與PtrToStringUni方法進行還原。例如以下的例子就會將型態為SecureString類別的m_Password變數中加密過的密碼還原成未加密前的內容:

正確答案:D

說明:
要維繫資訊系統的安全性,基本有三個安全管制動作要做,第一就是身份驗証。身分驗証是資訊系統的第一道安全管制,有加上身份驗証機制功能的資訊系統可以要求使用者必須提供正確的帳號和密碼,才能夠成功登入系統,並執行必要的作業,不具備合法帳號和密碼的使用者當然就無法使用系統提供的功能。資訊系統身份驗証機制的安全強度有賴於系統所有的使用者妥善地保管個人的密碼,如果使用者未妥善地保管個人的密碼,直接將密碼貼在電腦的螢幕上,則資訊系統的身份驗証機制做的再強固也會形同虛設。

資訊系統的第二道安全管制機制就是權限管制,權限管制主要的作用是在使用者成功地登入系統之後,依據使用者的帳號或帳號所屬的角色附予使用者執行某些工作的權限,例如系統可以依據使用者的帳號或帳號所屬的角色,決定使用者是否可以存取某個目錄中的檔案?是否可以讀取事件日誌的資料?是否可以存取Windows的登錄資訊,是否能夠存取資料庫中的記錄,或是可以使用程式提供的某個按鍵或是某個功能表。透過對電腦重要資源的使用權限管制,可以提升系統的安全性,因為一旦重要資源能夠被惡意程式取用,系統的安全性就會出現重大的漏洞。

系統安全管制的第三道防線是安全通訊,當電腦與電腦之間需要透過網路連線傳遞機密資料,例如密碼,身分証字號,或是信用卡號碼的時候,要記得機密資料必須加密後再行傳送,避免在網路上傳送的機密資料被偷窺,造成機密資料曝光,間接對系統的安全性形成傷害。例如使用者的密碼未經加密就經由透過網路傳遞,一旦被有心人士窺知,就可以冒用使用者的身分登入系統,並使用使用者本身的權限操作系統的功能。

正確答案:E

說明:
對系統使用的機密資料進行加密處理是保障系統安全的正確做法,但是如果沒有妥善保管機密資料加密時使用的金鑰,就好像沒有妥善保管使用者登入系統的密碼一樣,會讓機密資料的加密保護功虧一匱。病毒碼未即時更新的防毒程式當然好過沒有防毒程式,因為沒有防毒程式的保護,連基本的防護能力都沒有了。

為應用程式加上數位簽章,可以提供比利用比對病毒碼來判斷程式是否有被惡意竄改更佳的安全保護,因為經過數位簽章的程式只要被病毒感染,程式就無法被執行,不像依賴病毒碼的防毒程式,其防毒能力取決於病毒碼是否有即時更新。

電腦的安全性和系統管理員是否具備完備的資訊安全概念息息相關,因為資訊安全概念完善的系統管理員會勤於執行系統的安全性更新,妥善設定電腦的身分驗証機制,以及為欲經由網路傳輸的密碼加上加密保護。隨便在電腦中安裝未經安全驗証的應用程式是一件危險的動作,就好像將來路不明的食物吃到肚子裏一樣,很容易就病從口入。系統要達到更好的安全性,最好安裝經過數位簽章的應用程式。

◎科目:資料庫

說明:
執行SQL Server 2005備份的過程,如果需要將備份檔案,直接指向另外一台電腦的磁碟路徑,如「\\leader\c$\AdventureWorks.bak」,過程中假設執行備份的SQL Server 2005機器與另外一台電腦,不是屬於相同網域的狀況下兩台獨立伺服器,請問該設定哪些重要參數,才可以完成這樣的需求?
1. 儲存備份電腦,建立一個帳戶的帳號密碼等同SQL Server 2005的啟動帳戶。
2. 針對該帳戶,加入到該儲存備份電腦的local administrators群組。
3. 完成後就可以執行以下的指令:

說明:
交易記錄檔的使用狀況,攸關系統執行效能,因此該利用哪些方式,檢視現有的交易記錄檔使用狀況?除此之外,交易記錄檔該如何利用哪一種備份方式,進行有效的管理?
1. 檢視交易記錄檔使用狀況,可以執行DBCC SQLPERF(LOGSPACE)。
2. 正確的管理交易記錄檔的方式,就是定期執行交易記錄備份,讓備份的過程中,自動將交易記錄一併清除。

說明:
當資料庫使用者看到圖6的錯誤現象的時候,初步判斷是發生交易記錄檔快要爆滿,身為資料庫管理員的你,該如何判斷與最快速的方法,解決該問題?
圖6:收到交易記錄檔過滿的警訊

快速清除交易記錄檔的方式,可以使用以下的指令:

說明:
某些情況下,資料庫還原的過程可能需要被終止,但是因為尚未還原到最後一個備份,此時身為資料庫管理員的你,該如何快速讓該資料庫可以接受使用者的連線,圖7是正處於還原過程中的資料庫狀態?
圖7:資料庫正處於還原的狀態

快速啟動還原中的資料庫,可以使用以下的指令:
RESTORE DATABASE SalesDB WITH RECOVERY

說明:
某些情況下,為了要實作出自動根據執行日期,產生備份的資料庫檔案名稱,例如AdventureWorks資料庫會根據每天產生一份如AdventureWorksYYYYMMDD.bak的備份檔案,該參考圖8,請問該如何實作出該解決方案?
圖8:檢視每日產生的備份檔案

如果要根據每天的日期,進行備份輸出可以參考以下的格式:

DECLARE @DB sysname

DECLARE @DBPath varchar(120)

DECLARE cur CURSOR  --宣告資料指標變數

 FOR SELECT name FROM sys.databases

     WHERE name not in ('tempdb','ReportServerTempDB')

     --指定tempdb與報表服務使用ReportServerTempDB不進行備份

OPEN cur --開啟資料指標

FETCH NEXT FROM cur INTO @DB --從資料指標中取出資料庫名稱指定到變數

WHILE (@@FETCH_STATUS=0)

BEGIN     --以下就是上一個範例中搭配變數備份的陳述式

        SET @DBPath='C:\BAK\'+@DB

                +CONVERT(varchar(10),GETDATE(),112)

                +'.BAK'

        BACKUP DATABASE @DB TO DISK=@DBPath WITH INIT --重點

--執行備份作業並且覆蓋上一個備份資料

FETCH NEXT FROM cur INTO @DB

END

CLOSE cur

DEALLOCATE cur


Copyright© FLAG INFORMATION CO., LTD. 旗訊科技(股)公司. All rights reserved. 本站圖文著作權所有 未經授權 不得任意轉載使用