重要:ASP.NET安全漏洞

  • 23695
  • 0
  • 2011-06-23

摘要:重要:ASP.NET安全漏洞

[原文發表位置]:Important: ASP.NET Security Vulnerability

[原文發表時間]:2010/9/18 4:23 AM

幾個小時前,我們發佈了一個關於ASP.NET安全漏洞的Microsoft 安全警告,該漏洞存在於目前所有的ASP.NET版本。

該漏洞是在上週五的一個安全會議上發現的。我們建議所有的客戶立即採取補救措施(見下文)來預防攻擊者利用此漏洞攻擊您的ASP.NET站點。

920日更新: 我發佈了另一篇部落格,其中包含關於此問題的一些FAQ,您可以從這裡閱讀。

924日更新: 我發佈了另一篇部落格,關於在補救措施中啟用URLScan,您可以從這裡閱讀。

通過該安全漏洞能夠做什麼?

潛在的攻擊者可以通過該漏洞來下載ASP.NET 應用程式中的檔案,比如Web.config (它經常包含一些敏感數據)。

通過進一步利用該漏洞,攻擊者可以解密發送到客戶端的加密數據(如保存在頁面中的ViewState)。

如何利用該漏洞

要理解該漏洞的原理,您需要先瞭解密鑰神諭,即向一個加密系統發出問題,而它會給暗示。目前的這個漏洞就扮演了這樣一個跳板,可以讓攻擊者不斷向伺服器發送加密過的數據,通過檢測傳回的錯誤碼瞭解它是否能被解密,經過許多次嘗試後,攻擊者可以得到足夠多的經驗來解密剩餘的加密內容。

避免該漏洞的臨時方案

一個來避免該漏洞的替代辦法就是啟用ASP.NET的 <customErrors>,並且對它進行顯式配置,使得不管伺服器發生什麼樣的錯誤都總是傳回相同的錯誤頁。通過將不同的錯誤映射到同一個錯誤頁,可以避免讓攻擊者辨別在伺服器上產生的不同錯誤型別。

注意: 僅僅將customErrors設置為RemoteOnly是不夠的。您必須確認所有的錯誤都傳回相同的錯誤頁,這需要您顯示地設置customErrors節點的defaultRedirect屬性,並確認它沒有只針對特定的狀態碼。

ASP.NET V1.0 V3.5版本上啟用臨時方案

如果您正在使用ASP.NET 1.0, ASP.NET 1.1, ASP.NET 2.0 或者 ASP.NET 3.5,那麼您可以通過下面的步驟來設置 <customErrors> 將所有的錯誤映射到相同的錯誤頁。

1) 編輯ASP.NET 應用程式根目錄下的Web.config檔案,如果檔案不存在,則在應用程式的根目錄下建立一個。.

2) 建立或修改 <customErrors> 節點,並做如下設置:

<configuration>

<system.web>

<customErrors mode="On" defaultRedirect="~/error.html" />

</system.web>

</configuration>

3) 您可以在您的程序增加一個適當的error.html檔案(可以包含您喜歡的任意內容),當應用程式發生任何伺服端錯誤時就會顯示這個頁面。

注意:一個重要的事情就是customErrors節點的mode屬性必須設置成 「On」,這樣所有的錯誤才會被重定向到設定的錯誤頁。並且必須不對它指定任何錯誤狀態碼——也就是說 <customErrors /> 節點沒有任何子節點。這是做是為了避免攻擊者能夠區分伺服器發生的錯的型別,並且預防資訊洩露。

ASP.NET V3.5 SP1 ASP.NET 4.0 版本上啟用臨時方案

如果您正在使用ASP.NET 3.5 SP1 或 ASP.NET 4.0,則可以通過下面的步驟來設置 <customErrors> 將所有的錯誤映射到相同的錯誤頁。

1) 編輯ASP.NET 應用程式根目錄下的Web.config檔案,如果檔案不存在,則在應用程式的根目錄下建立一個。.

2) 建立或修改 <customErrors> 節點,並作如下設置,.NET 3.5 SP1 and .NET 4.0中還需要設置redirectMode=」ResponseRewrite」:

<configuration>

<system.web>

<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />

</system.web>

</configuration>

3) 您可以在您的程序增加一個適當的error.aspx檔案(可以包含您喜歡的任意內容),當應用程式發生任何伺服端錯誤時就會顯示這個頁面。

4) 我們推薦您在Error.aspx檔案的伺服端Page_Load() 事件中增加下面的程式碼,設計一個小小的隨機延遲,這將能幫助混淆錯誤。

VB 版本

下面是您可以使用的VB版本的Error.aspx ,在程式碼中實現了一個隨機的延遲。您不需要將它和您的應用程式一起編譯——只需隨意地把Error.aspx檔案保存到伺服器上的某個應用程式目錄。

<%@ Page Language="VB" AutoEventWireup="true" %>

<%@ Import Namespace="System.Security.Cryptography" %>

<%@ Import Namespace="System.Threading" %>

<script runat="server">

Sub Page_Load()

Dim delay As Byte() = New Byte(0) {}

Dim prng As RandomNumberGenerator = New RNGCryptoServiceProvider()

prng.GetBytes(delay)

Thread.Sleep(CType(delay(0), Integer))

Dim disposable As IDisposable = TryCast(prng, IDisposable)

If Not disposable Is Nothing Then

disposable.Dispose()

End If

End Sub

</script>

<html>

<head runat="server">

<title>Error</title>

</head>

<body>

<div>

Sorry – an error occured

</div>

</body>

</html>

C# 版本

下面是您可以使用的C#版本的Error.aspx ,在程式碼中實現了一個隨機的延遲。您不需要將它和您的應用程式一起編譯——只需隨意地把Error.aspx檔案保存到伺服器上的某個應用程式目錄。

<%@ Page Language="C#" AutoEventWireup="true" %>

<%@ Import Namespace="System.Security.Cryptography" %>

<%@ Import Namespace="System.Threading" %>

<script runat="server">

void Page_Load() {

byte[] delay = new byte[1];

RandomNumberGenerator prng = new RNGCryptoServiceProvider();

prng.GetBytes(delay);

Thread.Sleep((int)delay[0]);

IDisposable disposable = prng as IDisposable;

if (disposable != null) { disposable.Dispose(); }

}

</script>

<html>

<head runat="server">

<title>Error</title>

</head>

<body>

<div>

An error occurred while processing your request.

</div>

</body>

</html>

驗證 <customErrors> 節點是否已被正確設置

當完成上述配置後,您可以測試它來驗證設置是否正確且生效,比如在您的網站上請求類似這樣的URL: http://mysite.com/pagethatdoesnotexist.aspx

如果您看到之前設置的錯誤頁被顯示(因為您請求的檔案不存在),那麼配置就是正確的。而如果您看到一個標準的ASP.NET錯誤,則可能是您缺失了上面某個步驟。如果想查看導致錯誤的更多資訊,您可以嘗試設置 <customErrors mode="remoteOnly"  /> ——只在伺服器上的本地瀏覽器進行連接時才可以看見這些錯誤消息。

安裝URLScan並啟用一個自訂規則

如果您還沒有安裝IIS URLScan元件,請下載並進行安裝:

只需要不到一分鐘就可以將它安裝到你的伺服器上。

增加一個新的URL掃瞄規則

URLScan安裝完畢後,在以下位置找到UrlScan.ini檔案,打開並修改它:

  • %windir%\system32\inetsrv\urlscan\UrlScan.ini

在靠近UrlScan.ini檔案內容底部,您可以找到 [DenyQueryStringSequences] 節點,在緊跟它的下面的地方增加 「asoxerrorpath=」並保存:

[DenyQueryStringSequences]

aspxerrorpath=

上面這條規則可以禁止URL在QueryString中包含 「aspxerrorpath=」 這樣的屬性,如果有,則伺服器會傳回一個HTTP錯誤。有了這個規則就可以避免使攻擊者區分伺服器上的錯誤型別——即可以阻擋攻擊者利用這個漏洞。

保存以上修改以後,在命令提示符(需要管理員權限)中運行iisreset使它生效。您可以通過向伺服器的網站或應用程式請求QueryString中包含aspxerrorpath關鍵字的URL地址,來驗證它是否成功,正常情況下IIS應該發回一個HTTP錯誤。

Web伺服器上找出存在安全漏洞的ASP.NET應用程式

我們發佈了一個.vbs指令碼檔案,您可以保存到Web伺服器並運行它,來檢測是否有ASP.NET應用程式沒有關閉 <customErrors />,或它只針對某些錯誤狀態碼。

您可以從這裡下載這個.vbs指令碼檔案。只要把指令碼內容複製/貼上到一個記事本檔案,比如」DetectCustomError.vbs」,並保存到硬碟。打開一個命令提示符窗口(需要管理員權限),然後運行csript DetectCustomErrors.vbs,它會列出Web伺服器上的所有網站應用程式並檢查<customErrors />設置是否正確。

clip_image002

它會標記出那些有問題的應用程式,比如在Web.config中沒有設置 <customErrors />節點 (需要進行添加),或沒有按照正確的方法進行設置(你需要修改它),如果每個應用程式都沒有問題,它則會列印出「OK」的結果,這應該很容易的找出潛在的問題。

注意: 我們僅僅在前面幾個小時內完成了這個檢測指令碼,將在以後對它進行完善,一有修改我即會在這裡發佈更新。

關於此漏洞的更多資訊

您可以從下面這些地方瞭解更多關於該漏洞的資訊:

可提問的論壇

我們已經在www.asp.net 上設置了一個專門的論壇,來幫助回答與該漏洞相關的問題。

可以在這裡提問並獲得與該漏洞有關的幫助。

總結

我們將發表更多細節,並且我們將發佈一個修補檔來從根本上解決這個問題(並且不再需要上面的替代方案)。

在那之前,請繼續執行上面的替代方案來預防攻擊者來利用它。

920日更新: 發佈了另一篇部落格,其中包含關於此問題的一些FAQ,您可以從這裡閱讀。

924日更新: 發佈了另一篇部落格,關於在臨時方案中啟用一個額外步驟URLScan。您可以從這裡閱讀。

希望這能對您有所幫助。

附:[除了寫部落格以外,我現在也使用推特(Twitter)來及時更新狀態和分享連結,您可以到這個地址「推」我一下:twitter.com/scottgu]