﻿# 安裝 URLScan 需注意原始設定會無法處理「許功蓋」字元

真糟糕，知名的「許功蓋」又再次重出江湖，這次出現的地方竟然是 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 工具，我知道有許多專業網管人員都會安裝 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 到網站主機用以提供基礎網站安全防禦，但是當遇到開發人員將網站開發完要上線時無辜的被 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 阻擋時，不瞭解的網管或客戶還可能會以為是程式出問題，而讓軟體工程師改程式改到地老天荒…

不管是[大五碼](http://zh.wikipedia.org/w/index.php?title=%E5%A4%A7%E4%BA%94%E7%A2%BC&variant=zh-tw)(Big5)或是 [GB2312](http://zh.wikipedia.org/wiki/GB_2312) 碼，這些 [CJK](http://en.wikipedia.org/wiki/CJK) 字碼都是在非常有限的字碼中用來表達中文字的字元，我們又通稱為雙位元(Double Byte)字元，也就是一個中文字包括兩個 ANSI 字元所組成，第一個 ANSI 字元我們稱為**高位位元組**(High Byte)，第二個 ANSI 字元我們稱為**低位位元組**(Low Byte)。

以大五碼為例，中文字定義的字碼與可使用範圍如下圖所示：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2aef6c00b60bf9399536-image_3.png "image")

各位應該知道 [ASCII](http://en.wikipedia.org/wiki/ASCII) 字元定義的範圍是從 0x00 - 0x7F，而中文字定義的字碼，在**高位位元組**(High Byte)的部分至少都是從 0x81 開始，所以不會與 ASCII 有任何衝突。但是在 **低位位元組**(Low Byte) 的地方卻定義了 **0x40 ~ 0x7E** 與 0xA1 ~ 0xFE 的區間，所以在 **0x40 ~ 0x7E** 這個區間將會有七千多個中文字會用到「部分」ASCII 碼！

我們回到 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 的預設設定中，你會發現有個 \[DenyUrlSequences\] 區段設定，其中定義了一個「反斜線 ( \\ )」字元，其字元的 ASCII 的十六進制表示的數值為 **0x5C**

![URLScan 的預設設定中，你會發現有個 \[DenyUrlSequences\] 區段設定，其中定義了一個「反斜線 ( \\ )」字元，其字元的 ASCII 的十六進制表示的數值為 0x5C](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3526bf6ecda21fa4d3f0-image_6.png "URLScan 的預設設定中，你會發現有個 [DenyUrlSequences] 區段設定，其中定義了一個「反斜線 ( \ )」字元，其字元的 ASCII 的十六進制表示的數值為 0x5C")

我做了一個簡單的測試，首先我的 IIS 有安裝 URLScan 工具並確認啟用，然後在我的 IIS 預設站台根目錄下新增一個網頁名為 "**成功.htm**"

在 Internet Explorer 中輸入網址為：**http://localhost/****成功.htm**

事實上我們從 Server 端收到的 Request 會被 IE 進行 UrlPathEncode 過，所以正確的 Request 路徑應為：**http://localhost/%E6%88%90%E5%8A%9F.htm**

眼力好的人應該看的出來，"**成功**" 被代換成 UTF-8 編碼了，其中 "**%E6%88%90**" 是 "**成**"，而 "**%E5%8A%9F**" 是 "**功**"，然後你會得到一個 "**HTTP 錯誤 404.0 - Not Found  您尋找的資源已移除、名稱已變更，或暫時無法使用。**" 的錯誤訊息。

然後我們到 **C:\\Windows\\System32\\inetsrv\\urlscan\\logs** 目錄下查看最新的 URLScan 阻擋紀錄，你應會看到 "**Rejected disallowed+URL+sequence URL**" 錯誤訊息：

```
GET /%E6%88%90%E5%8A%9F.htm Rejected disallowed+URL+sequence URL - \
```

網管人員光是看到這些訊息應該完全抓不到任何頭緒，不熟悉文字編碼的網管找到死都找不出問題所在！

由於 Windows 系統內建文字編碼的轉換，在 Windows 檔案系統中有許多的檔案，有的檔名直接以系統**預設 ANSI 編碼** (Big5)，有的檔名直接以 Unicode 編碼，不過使用者的確可以不用知道這些細節，因為 99.9% 的情況下，這些轉換都是自動完成的，而且大多不會影響現有 Windows 程式的運作。

大部分的情況下，檔名都是以 **預設 ANSI 編碼** (Big5) 表示的，也就是說雖然你的 HTTP Request 送到 IIS 的時候是 **%E6%88%90%E5%8A%9F.htm** (Unicode)，但是實際上 Windows 應用程式在內部作業卻會收到 **%a6%a8%a5%5c.htm** (Big5)，而這就是問題最關鍵的地方，因為網址中出現了致命的 %5c 字元 ( \\ )，以致於被 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 檔下，使網頁無法顯示！

"**反斜線 ( \\ )**" 對英語系國家的人來說並不是在網址中常見的字元，反而經常出現在網路攻擊事件中，所以會將 "**反斜線 ( \\ )**" 列為不允許出現的字元。但是對亞洲語系的網站來說，卻是經常出現，尤其是網頁或檔案中有出現中文的地方，雖然在 Big5 中最多只有 116 個字會出現 "**反斜線 ( \\ ) ( %5c )**"，但總是會有人遇到的 。

> [莫非定律](http://zh.wikipedia.org/wiki/%E6%91%A9%E8%8F%B2%E5%AE%9A%E7%90%86) ( [Murphy's law](http://en.wikipedia.org/wiki/Murphy%27s_law) )  
> 任何有可能出錯的事將會出錯 ( Anything that can go wrong will go wrong.)

我個人建議可以將 "**反斜線 ( \\ )**" 從 [URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan) 的 \[DenyUrlSequences\] 區段中移除，此問題就自然迎刃而解。光是移除這個 \\ 字元應該不至於對你的網站造成多大的資安風險，我覺得資安人員可以不用過於擔心調整這個預設設定。

**相關連結**

-   [Using URLScan](https://web.archive.org/web/20120904172731/http://learn.iis.net:80/page.aspx/473/using-urlscan)
-   [大五碼 - 維基百科，自由的百科全書](http://zh.wikipedia.org/w/index.php?title=%E5%A4%A7%E4%BA%94%E7%A2%BC&variant=zh-tw)
-   [ASCII - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/ASCII)
-   [CJK characters - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/CJK)
