同事分享資安知識一則:在網頁引用 Host Header 可能形成資安弱點,給予攻擊者操作重新導向或引用惡意程式的機會。特筆記備忘。

使用 IIS + ASP.NET 示範如下:

<%@Page Language="C#"%>
<html>
    <head>
        <title>Host Header 弱點示範</title>
    </head>
    <body>
        <ul>
            <li>Request.Url.Host = <%=Request.Url.Host%></li>
            <li>Request.Headers["Host"] = <%=Request.Headers["Host"]%></li>
        </ul>
        <!-- 危險做法:依 Host 決定網址, 可能被惡意竄改 -->
        <script src="://<%=Request.Url.Host%>/scripts/app.js"></script>
    </body>
</html>

在一般情況下,瀏覽器或 HTTP 客戶端開啟 https://blog.darkthread.net/ 時會帶入 Host: blog.darkthread.net,同樣是 80 Port,網站可依不同 Host 導向不同站台,實現多站台共用 80 Port 的效果。而伺服器端 ASP.NET 可由 Request.Url.HostRequest.Headers["Host"] 讀取 blog.darkthread.net。

以下使用 curl 工具觀察 Host Header 依 URL 改變的行為及伺服器端讀取結果:

curl -v http://localhost/aspnet45/vulnerable.aspx
curl -v http://127.0.0.1/aspnet45/vulnerable.aspx

但問題出在以上是標準行為,若瀏覽器或客戶端遭惡意軟體控制或傳輸過程遭攔截,Host 就可能被偷改。若伺服器端依據 Request.Url.Host 決定重導位址或是 JavaScript 載入位址,攻擊者便能上下其手,將使用者導向詐騙網站或下載惡意程式。例如以下範例,curl 送出請求時使用參數覆寫 Host Header,ASP.NET 將讀到有毒的值,若還拿來指定 JavaScript 下載位址就危險了。

curl -v http://localhost/aspnet45/vulnerable.aspx -H "Host: you-are-hacked.com"

針對這類風險,IIS 部落格提供以下建議:

  1. 避免在程式中使用 Request.Url.Host 或 Request.Headers["Host"],應假設他們可能被偽造竄改,如要使用務必確實檢核
  2. 在 IIS Binding 限定 Host 名稱可防範這類攻擊,例如:

    若攻擊者竄改 Host Header,將得到 404:
  3. 在 Reverse Proxy 情境會用 X-Forwarded-Host 取代 Host Header,請用相同標準看待,不要信任。
  4. 若不指定 Binding,可考慮使用 UrlRewrite 檢查 Host Header,發現被竄改時執行阻擋或重新導向。以下範例在 UrlRewrite 模組新增 Request Blocking Rule,比對 Host Header 不吻合 RegularExpression ^(127.0.0.1|localhost)$ 時傳回 403:

    實測也能阻擋偽造 Host Header:

Introduction to HTTP Host header attacks and how to prevent them.


Comments

# by Ming

curl -v http: //localhost/aspnet45/vulnerable.aspx -H "Header: you-are-hacked.com" 圖文不符 XD

# by Jeffrey

to Ming, 已校正,謝~

# by 小黑

黑哥最頂

# by hill

請問黑大,您是怎麼做測試的,最近也遇到這個資安問題

# by Jeffrey

to hill,可參考文章範例,用 curl 修改 Host Header 檢測伺服器回應。

# by aliku

黑大,請問IIS修改的UrlRewrite 第4點,可否請你提供修改好後的 web.config 裡的 rule 參考呢? 謝謝。

# by Jeffrey

to aliku, 一時找不到當初的測試環境,你如果已裝好 UrlRewrite 模組,照著設定後可在 web.config 找到 rule。

# by aliku

謝謝黑大回覆,因為IIS的UrlRewrite畫面與上面的不太一樣,看起來比你的畫面還複雜,無法參考上面畫面去對應設定,才想說若有 web.config 的 rule 設定,可以往回推看 IIS 的 UrlRewrite的欄位設定。

# by Jeffrey

to aliku, 選 Add Rules / Inbound rules / Request blocking 應該會看到相同畫面。我有弄了一個環境完成相同操作,在 web.config 產生結果如下,供你參考: <rewrite> <rules> <rule name="RequestBlockingRule1" stopProcessing="true"> <match url=".*" /> <conditions> <add input="{HTTP_HOST}" pattern="^(127.0.0.1|localhost)$" negate="true" /> </conditions> <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." /> </rule> </rules> </rewrite>

# by Dante

Hi, Dark boss for lighttpd server, how could we prevent this attack by config lighttpd.conf, many thanks.

Post a comment