按一下以給予評分及指教
Related Articles

Windows Communication Foundation (WCF) 的角色型系統以及功能更強大與複雜的宣告型 API,可以讓您輕鬆實作服務的授權。

Dominick Baier and Christian Weyer

MSDN Magazine October 2008

...

Read more!

我們的安全性專家 Michael Howard 在此提出 10 個有安全性弱點的程式碼。您的任務是要在程式碼中找出問題 (不良安全性做法) 的所在。

Michael Howard 以及 Bryan Sullivan

MSDN Magazine 十一月 2008

...

Read more!

充分了解控制權限 (Permission) 和權限/權利 (Right) 的 ACL,再決定是否允許作業的執行,是增強安全性的關鍵。

John R. Michener

MSDN Magazine 十一月 2008

...

Read more!

我們將探索下一版 Visual Studio 預定提供的平行程式設計支援,其中包括適用於 Managed 程式碼和原生程式碼的支援。

Stephen Toub and Hazim Shafi

MSDN Magazine October 2008

...

Read more!

Bryan Sullivan 針對發表週期很短的 Web 應用程式和 Agile 專案,討論新的 SDL。

Bryan Sullivan

MSDN Magazine 十一月 2008

...

Read more!

Also by this Author

Reviewing code for security defects is a key ingredient in the software creation process, ranking alongside planning, design, and testing. Here the author reflects over his years of code security reviews to identify patterns and best practices that all developers can follow when tracking down potential security loopholes. The process begins by examining the environment the code runs in, considering the roles of the users who will run it, and studying the history of any security issues the code may have had. After gaining an understanding of these ...

Read more!

In this article, Microsoft security expert Michael Howard outlines how to apply the Security Development Lifecycle to your own software development processes. He explains how you can take some of the lessons learned at Microsoft when implementing SDL and use them in your own development process.

Michael Howard

MSDN Magazine November 2005

...

Read more!

五年前,比爾蓋茲向所有員工發佈加強安全性的指示。從此以後,人們就從建置更安全軟體的寶貴經驗中學習。

Michael Howard

MSDN Magazine November 2007

...

Read more!

一說到安全性,惹上麻煩的方式可說是林林總總。您可能會信任在您網路上執行的所有程式碼,讓任何使用者都能存取重要檔案,而從來不去檢查機器上的程式碼是否有變更;您可能會在沒有防毒軟體下執行,而不將安全性建入您自己的程式碼中,並授予太多權限給太多帳戶;您甚至可能會粗心地使用一堆內建功能,而讓他人有機會闖入,然後也可能讓伺服器連接埠開著而無人監視。很顯然,這些情況是多得不勝枚舉。到底真正重要的問題有哪些?您現在應該注意的最大錯誤是什麼?才不致於危害到您的資料或系統。安全性專家 Michael Howard 和 Keith Brown 為您提供十大秘訣,讓您免於遭殃。

Michael Howard and Keith Brown

MSDN Magazine September 2002

...

Read more!

透過威脅分析模型即可驅動安全機制的設計工程,來制訂程式碼檢閱的優先順序、模糊 (Fuzz) 測試的優先順序,以及分析攻擊面。

Michael Howard

MSDN Magazine 十一月 2008

...

Read more!

Popular Articles

When incorporating the ASP.NET DataGrid control into your Web apps, common operations such as paging, sorting, editing, and deleting data require more effort than you might like to expend. But all that is about to change. The GridView control--the successor to the DataGrid-- extends the DataGrid's functionality it in a number of ways. First, it fully supports data source components and can automatically handle data operations, such as paging, sorting, and editing, as long as its bound data source object supports these capabilities. In addition, ...

Read more!

This article introduces 10 development tools that can increase your productivity, give you a better understanding of .NET, and maybe even change the way that you develop applications. The tools covered include NUnit to write unit tests, Reflector to examine assemblies, FxCop to police your code, Regulator to build regular expressions, NDoc to create code documentation and five more.

James Avery

MSDN Magazine July 2004

...

Read more!

Jeff Prosise 說明何時該使用 UpdatePanel,以及何時該改用 WebMethods 或頁面方法。

Jeff Prosise

MSDN Magazine June 2007

...

Read more!

C# allows developers to embed XML comments into their source files-a useful facility, especially when more than one programmer is working on the same code. The C# parser can expand these XML tags to provide additional information and export them to an external document for further processing. This article shows how to use XML comments and explains the relevant tags. The author demonstrates how to set up your project to export your XML comments into convenient documentation for the benefit of other developers. He also shows how to use comments ...

Read more!

這個月 Dino Esposito 將透過 Ajax Control Toolkit 與一些聰明的程式碼撰寫技巧,告訴您如何為 Web 應用程式取得 Windows 樣式的強制回應對話方塊。

Dino Esposito

MSDN Magazine Launch 2008

...

Read more!

Our Blog

C# developers can use the Visual Studio Tools for the Office System (VSTO) Power Tools Office interop API extensions to streamline Office application development. The extensions provide a thin, strongly typed layer over the loosely typed Office object models.

In the December 2008 issue of MSDN Magazine, Andrew Whitechapel, Phillip Hoff, and Vladimir Morozov walk you through developing ...

Read more!

A team project is simply a bucket that stores and partitions all of the artifacts you track and use within a Team Foundation Server (TFS) project.

In the December 2008 issue of MSDN Magazine, Brian A. Randell explains how you can use and customize the MSF Agile and MFS CMMI process templates to get the most out of them for your ...

Read more!

Silverlight provides a browser interoperability layer that allows managed code to access the document object model (DOM) of the underlying page. At the same time, JavaScript code running in the page can access the XAML content of the plug-in and even make modifications.

In the November 2008 issue of MSDN Magazine, Dino Esposito discusses the ...

Read more!

Testability is both as an important quality of your designs and another tool you can use to create and think through designs.

In the December 2008 issue of MSDN Magazine, Jeremy Miller examines the design issues, patterns, and principles that can enhance testability in your apps.

For more articles ...

Read more!

digg_url = "http://blogs.msdn.com/msdnmagazine/archive/2008/12/15/9221908.aspx";digg_title = "x64 Debugging With Pseudo Variables";digg_bgcolor = "#FFFFFF";digg_skin = "normal";digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;

For many years, Visual ...

Read more!

安全性簡報
使用 Visual C++ 的防禦功能來保護您的程式碼
Michael Howard

很 多程式碼都是使用 C 與 C++ 撰寫,不幸的是,這些程式碼大多包含許多開發人員尚未察覺的安全性弱點。無論使用哪種語言撰寫程式,都可能包含讓使用者易受攻擊的弱點,不過 C 和 C++ 語言在網際網路歷史上佔有特殊地位,因為許多安全性弱點產生的原因,正是源自這兩種程式設計語言大受歡迎的特質:自由存取電腦硬體和隨之而來的高效能。每當您閱讀有關安全性的文章時,只要一看到 C 或 C++,通常很快也會看到「緩衝區」及「滿溢」等字眼,因為緩衝區通常是直接存取記憶體的例子之一。這種直接存取的功能非常強大,但也極度危險。
造成實際執行的 C 和 C++ 程式碼中有這麼多緩衝區滿溢的原因有數個。第一個原因是我剛才提過的:這些語言可讓您直接存取脆弱的記憶體。其次是開發人員的人為疏失。第三個原因是編譯器通常不會提供防禦功能。針對第一個原因,可以採取一些補救方法來解決,但是這麼一來,C 和 C++ 也失去原味了。
至於開發人員的人為疏失,可以透過教育訓練來解決一部分的問題,不過我卻看不到任何教育機構安排此類課程。當然,業界本身也可以提供安全性教育訓練,但是我們都是局內人 (無論就解決方案或問題而言),因此期盼大專院校可以教導學生更多有關軟體安全性的議題。您可能會問:「教育機構為何不試著教導這麼重要的主題?」坦白說,我也不知道,這種情況真的蠻讓人沮喪的。
最後,即使提供了絕佳的教育訓練,有些安全性問題實在太複雜了,即使是訓練紮實的工程師也有百密一疏的時候,畢竟人非聖賢。
針對在編譯器中建置更多防禦功能的需求,Microsoft Visual C++ 小組多年來一直在努力,並藉助安全性小組之力持續地在進步中。本專欄將概述 Visual C++® 2005 及更新版本中提供的一些緩衝區滿溢防禦功能。要注意的是,其他某些編譯器也提供防禦功能,但是 Visual C++ 擁有 GCC 等類似產品所沒有的兩大優點。首先,這些防禦功能在預設情況下都已放入工具組中;您無須再下載一些古哩古怪的增益集。其次,這些選項都很容易使用。
Visual C++ 工具組提供的防禦功能如下 (排列順序無特定意義):
  • 以堆疊為主的緩衝區滿溢偵測 (/GS)
  • 安全例外處理 (/SafeSEH)
  • 資料執行防止 (DEP) 相容性 (/NXCompat)
  • 映像隨機處理 (/DynamicBase)
  • 自動使用更安全的函式呼叫
  • C++ operator::new
開始詳細討論之前,必須先提醒您,這些防禦功能無法補救不安全的程式碼。您應該竭盡所能建立最安全的程式碼,如果不知道該怎麼做,您最好立即起身去找一些關於這個主題的好書來看。
Typical Stack Compared to One Compiled with /GS  (按影像可放大)
另外我必須指出這些都已納入 Microsoft 的安全性開發循環 (Security Development Lifecycle,SDL) 需求,也就是說,C 和 C++ 程式碼在發行前都必須使用這些選項。有時也會有例外情況,但較為罕見,我在此就不再多加細述了。
最後,您必須謹記一個重點:根據所寫的程式碼而定,有一些辦法可能可以規避這些精心設計的防禦功能。程式碼使用的防禦功能越多,就越難閃避它們,但是沒有任何防禦機制是十全十美的。它們都只是降低惡意入侵得逞機率的安全措施。別說我沒警告過您!唯一的例外就是更安全的函式呼叫用法,它們是真正有效的防禦措施,可以移除安全性弱點。我們現在就來逐一審視各項防禦功能。

以堆疊為主的緩衝區滿溢偵測 (/GS)
以堆疊為主的緩衝區滿溢偵測是 Visual C++ 最早提供且最知名的防禦功能。/GS 編譯器旗標的目標很簡單:減少惡意程式碼順利執行的風險。Visual C++ 2003 和更新版本預設會啟用 /GS 選項,此選項會在執行階段偵測特定類型的堆疊瓦解。它的作法是在堆疊的傳回位址的前面加入一個隨機數字,當函式傳回時,函式終解程式碼會檢查這個數值以確認它不變。如果在呼叫時 Cookie 改變了,執行動作就會停止。
設定此 Cookie 的函式初構程式碼如下所示:
sub    esp, 8
mov    eax, DWORD PTR ___security_cookie
xor    eax, esp
mov    DWORD PTR __$ArrayPad$[esp+8], eax
mov    eax, DWORD PTR _input$[esp+4]
下面顯示的是檢查 Cookie 的函式終解程式碼:
mov    ecx, DWORD PTR __$ArrayPad$[esp+12]
add    esp, 4
xor    ecx, esp
call    @__security_check_cookie@4
add    esp, 8
Visual C++ 2005 也會移動堆疊上的資料,讓資料更不容易被損毀。將緩衝區移到比非緩衝區更高的記憶體就是其中一個例子。舉例來說,這個步驟有助於保護堆疊上的函式指標。或者,在執行階段將指標和緩衝區引數移到下層的記憶體,也能避免各種緩衝區滿溢攻擊。請參閱圖表來比較一般堆疊與 /GS 堆疊。
/GS 編譯器選項不適用於下列任一情況:
  • 函式不包含緩衝區。
  • 未啟用最佳化。
  • 函式定義為包含可變個數引數清單。
  • 函式標記為 Naked 關鍵字 (C++)。
  • 函式在第一個陳述式中包含內嵌組件程式碼。
  • 緩衝區並非 8 位元類型,而且大小低於 4 位元。
Visual C++ 2005 SP1 中加入了一個選項,好讓 /GS 啟發式技術能夠更積極地保護更多函式。Microsoft 加入此選項的原因是,少部分發佈的資訊安全佈告欄內容所使用的程式碼具有以堆疊為主的緩衝區滿溢,而且雖然以 /GS 編譯,但程式碼仍未受 Cookie 保護。這個新選項可大幅增加被保護的函式數量。
在您要增添保護的模組中 (例如,處理來自網際網路的資料的程式碼),插入下行程式碼即可使用此選項:
#pragma strict_gs_check(on)
此 pragma 是 Microsoft 不斷提升 /GS 功能的例子之一。Visual C++ 2003 中的原始版本很簡單,接著在 Visual C++ 2005 SP1 中有了更新版本,然後在 Visual C++ 2008 中,我們學習到新的攻擊模式,同時也找出新的方法來阻擋現有的攻擊。根據我們的分析,/GS 並不會造成實際的相容性或效能問題。

安全例外處理 (/SafeSEH)
影響 Internet Information Server (IIS) 4.0 的 CodeRed 蠕蟲是由以堆疊為主的緩衝區滿溢所造成的。有趣的是,/GS 抓不到這個被蠕蟲利用的問題,原因是程式碼不是讓受影響函式的傳回位址滿溢,而是破壞了堆疊上的例外處理常式。這個例子讓我們很清楚的知道,重點是要致力於撰寫安全的程式碼,而不是完全依賴這類編譯器架構的防禦機制。
例外處理常式是指在發生例外狀況 (例如,除數為零) 時執行的程式碼。處理常式的位址保留在函式的堆疊框架上,因此有可能受到損毀。Visual Studio® 2003 和更新版本隨附的連結器包含一個選項,可在編譯時期將有效的例外處理常式清單存放在映像的 PE 標頭中。當執行階段發生例外狀況時,作業系統會檢查映像標頭以確認例外處理常式位址是否正確;若不正確,應用程式便會終止。如果這項技術在連結程式碼時已經存在,便可以防止 CodeRed 入侵。除非發生例外狀況,/SafeSEH 選項不會造成什麼效能衝擊,因此您應該隨時連結此選項。

DEP 相容性 (/NXCompat)
市面上的 CPU 幾乎都支援禁止執行 (No Execute,NX) 功能,也就是說,CPU 不會執行非程式碼頁面。稍微思索一下背後的含意:幾乎所有緩衝區滿溢弱點都是源自資料錯誤 (Data Bug);攻擊者接著經由緩衝區滿溢將資料插入處理序中,然後繼續在惡意資料緩衝區內執行。問題是 CPU 根本就不應該執行資料。
連結 /NXCompat 選項,即可讓您的可執行檔受到 CPU 禁止執行功能的保護。根據我們的經驗,Microsoft 的安全性小組幾乎從未見過這個選項會導致相容性問題,而且也沒有任何效能降低的疑慮。
Windows Vista® SP1 也加入了新的 API,此 API 會針對執行中的處理程序啟用 DEP,而且一經設定就無法取消:
SetProcessDEPPolicy(PROCESS_DEP_ENABLE);

映像隨機處理 (/DynamicBase)
Windows Vista 與 Windows Server® 2008 都支援映像隨機處理,這表示系統在開機時會隨機排列記憶體中的作業系統映像。這項功能的用意只是要讓攻擊者不容易預測。這就是所謂的位址空間隨機配置 (Address Space Layout Randomization,ASLR)。請注意,無論要採取何種方式使用 ASLR,都必須同時啟用 DEP。
根據預設,Windows® 只會移動系統元件。如果您希望作業系統隨機移動您的映像 (強烈建議您這麼做),那麼就應該與 /DynamicBase 選項連結 (Visual Studio 2005 SP1 和更新版本的工具組會提供此選項)。連結 /DynamicBase 將產生一個有趣的副作用 -- 作業系統也會隨機處理您的堆疊,這樣有助於降低可預測性,也會讓攻擊者更難危害系統。另外要注意的是,在 Windows Vista 和 Windows Server 2008 中也會隨機處理堆積,但這是預設情況,您無須編譯或連結任何特殊選項。

更安全的函式呼叫
請看一下下面幾行程式碼:
void func(char *p) {
    char d[20];
    strcpy(d,p);
    // etc
}
假設 *p 包含不受信任的資料,那麼這段程式碼就代表一個安全性弱點。此程式碼的陷阱在於,編譯器可能會將 strcpy 的呼叫升級到較安全的函式呼叫,並且將複製作業限制為目標緩衝區的大小。為什麼呢?因為緩衝區大小是靜態的,而且在編譯時期就已得知!
藉由 Visual C++,您可以將下行加入 stdafx.h 標頭檔中:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
編譯器接著就會直接從不安全的初始函式發出下列程式碼:
void func(char *p) {
    char d[20];
    strcpy_s(d,__countof(d), p);
    // etc
}
如您所見,這段程式碼現在已變成安全的程式碼,但是開發人員只不過是加入了 #define 而已。這是我最喜歡的 Visual C++ 新功能之一,因為大約有 50% 的不安全函式呼叫可自動升級為更安全的呼叫。

C++ Operator::new
最後,Visual C++ 2005 和更新版本新增了一項防禦功能,可在呼叫 operator::new 時偵測整數溢位。您可以從以下程式碼開始:
CFoo *p = new CFoo[count];
Visual C++ 會將它編譯為:
00004    33 c9           xor    ecx, ecx
00006    8b c6           mov    eax, esi
00008    ba 04 00 00 00  mov    edx, 4
0000d    f7 e2           mul    edx
0000f    0f 90 c1       seto    cl
00012    f7 d9           neg    ecx
00014    0b c8            or    ecx, eax
00016    51             push    ecx
00017    e8 00 00 00 00 call    ??2@YAPAXI@Z    ; operator new
要配置的記憶體量經過計算 (mul edx) 後,會根據乘法運算後的溢位旗標值來設定或不設定 CL 登錄,因此 ECX 將會是 0x00000000 或 0xFFFFFFFF。根據下一個操作 (或 ecx),ECX 登錄可能是 0xFFFFFFFF 或 EAX 中的值,也就是最初的乘法運算的結果。這接著會傳送到 operator::new,且在 2^N-1 配置時便會失敗。
此防禦功能不必花任何代價。其中沒有任何編譯器參數;純粹是編譯器原本的操作。

萬一失敗該怎麼辦?
唉呀,這個問題真尖銳!如果觸發上述任一防禦功能,可能會產生一個討厭的結果:應用程式會結束執行囉。這絕非理想狀況,但總比執行攻擊者的惡意程式碼來得好多了。
SDL 要求新的程式碼使用上述所有防禦選項,理由很簡單,因為外面有太多攻擊危機,您永遠無法斷定自己的程式碼是 100% 零弱點。SDL 有一句標語:「您要一律假設程式碼會失敗;然後考慮因應措施。」在現實生活中,「因應措施」就是要「奮力一搏!」不要輕易放任攻擊者的程式碼;要盡力讓攻擊者的入侵手段發揮不了作用。千萬別氣餒!
請務必使用最新版的 C++ 編譯器來取得更好的 /GS 進行編譯,並連結最新的連結器以善用 CPU 的優勢與作業系統的防禦功能。

若有任何疑問或意見,請將郵件寄至 briefs@microsoft.com.


Michael Howard 是 Microsoft 的首席安全性專案經理,工作重心為安全流程的改進及最佳作法。他是五本安全性著作的共同執筆者,其中包括 Writing Secure Code for Windows VistaThe Security Development LifecycleWriting Secure Code19 Deadly Sins of Software Security。他的部落格網址為 blogs.msdn.com/michael_howard

Page view tracker