Handling (SEH) frame FS:[0x18] 4 Thread Environment
II. Cross-Site Scripting: Persistent
傳送未驗證的資料到網路瀏覽器(browser)會導致瀏覽器執行惡意程式。
此種漏洞也稱作 Stored XSS,主要出現在以下兩種情形,其一是資料從一 個資料庫或其他後端資料存放區進入網路應用程式。其二是未驗證資料的動態 內容是否存在惡意程式,便將其傳送至網頁使用者。
傳至網路瀏覽器的惡意內容通常為 JavaScript 片段的形式,但也可能包含 HTML、Flash 或其他瀏覽器能執行的程式類型。XSS 通常會傳輸 Cookie 或類似 網路連線之資訊的私人資料給攻擊者,將受害者重新導向(redirect)攻擊者控制下 的網路內容(content);或者利用已偽裝攻擊的網站,在使用者的機器上執行惡意 程式。
protected System.Web.UI.WebControls.Label EmployeeName;
...
string query = "select * from emp where id=" + eid;
sda = new SqlDataAdapter(query, conn);
sda.Fill(dt);
163
string name = dt.Rows[0]["Name"];
...
EmployeeName.Text = name;
以上程式碼片段使用員工的識別碼來查詢員工資料庫,並顯示出與識別碼
III. Denial of Service
此漏洞會讓攻擊者摧毀程式或讓合法的使用者無法使用程式。
攻擊者能夠對應用程式發送大量要求(request),使其拒絕對合法使用者之服 務,但大量攻擊形式通常會在網路層便被排除。較嚴重的問題是讓攻擊者使用 少量要求便可超載應用程式。此種錯誤(bug)可讓攻擊者指定系統資源使用的數 量,或指定持續使用此系統資源的時間。
using (StreamReader sr = new StreamReader("file.zip")) {
String line;
line = sr.ReadLine();
...
}
164
以上程式從 file.zip 檔中讀取字串。因為使用 ReadLine()此函式,讀取輸入直 至換行字元為止。攻擊者可以利用此程式來引發 OutOfMemoryException,或者 消耗大量的記憶體,以致程式需要大量的時間執行垃圾資訊的收集,或在後續 操作過程用盡記憶體。
其解決方法,對於能被使用者指定的系統資源,應避免其被使用者所設定,
程式設計者應以內部情形所制定。
IV. Header Manipulation
在 HTTP 回應(response)表頭(header)中包含未驗證的資料會導致許多針對漏 洞的攻擊。
此漏洞會出現在以下兩種情形,其一是資料經過不可信賴的來源,例如 HTTP 要求,因此進入網路應用程式。其二是未經驗證的資料包含在 HTTP 回應表頭的 情況下,便將其傳送給網頁使用者。
如同許多軟體的安全性漏洞,Header Manipulation 是達到目的的一種手段,
而不是一個目的。此漏洞的基礎很簡單:攻擊者傳送惡意資料至有漏洞的應用 程式,應用程式再將該資料包含於 HTTP 回應表頭中。
最常見的一種 Header Manipulation 攻擊為 HTTP Response Splitting。為了成 功進行 HTTP Response Splitting 攻擊,應用程式必頇允許以下設定,輸入換行字 元(character)CR(Carriage Return,亦由%0d 或\r 指定)與 LF(Line Feed,亦由
%0a 或\n 指定)字元加入表頭。這些字元不僅讓攻擊者控制應用程式所要傳送 的回應表頭和回應內容(body),還允許攻擊者控制並建立額外的回應。
165
protected System.Web.UI.WebControls.TextBox Author;
...
string author = Author.Text;
Cookie cookie = new Cookie("author", author);
...
以上程式碼片段會從 HTTP 要求中讀取網路部落格(weblog)項目的作者名稱
(author),並且將該名稱設定在 HTTP 回應的 Cookie 表頭中。
假設在要求中提交了一個由標準英數字元(alpha-numeric)所組成的字串,如
「Jane Smith」,那麼包含這個 Cookie 的 HTTP 回應可能會表現為以下形式:
HTTP/1.1 200 OK ...
Set-Cookie: author=Jane Smith ...
不過,因為 cookid 的值是由未驗證的使用者輸入而得來,所以只有當傳送 給 Author.Text 的值不包含任何 CR 和 LF 字元,那麼回應才會保留這種形式。如 果攻擊者提交(submit)了一個惡意字串(string),如「Wiley Hacker\r\nHTTP/1.1 200 OK\r\n...」,那麼 HTTP 回應會分割成以下兩種形式的回應:
HTTP/1.1 200 OK ...
Set-Cookie: author=Wiley Hacker HTTP/1.1 200 OK
...
第二個回應被攻擊者所控制,並且能以任何表頭和正文內容來建構。攻擊 者可以用來建構任意 HTTP 回應,來進行不同種類的攻擊,包括:跨用戶(cross-user) 塗 改 (defacement) 、 網 頁 和 瀏 覽 器 快 取 記 憶 體 (cache) 植 入 病 毒 (poisoning) 、 Cross-Site Scripting 和網頁劫持(hijacking)。
166
其解決方法是針對使用者輸入之數值,進行嚴密的驗證,對於每個使用者 輸入之字元掃描,若偵測到使用者輸入危險字元,如 CR 或 LF 字元,則拒絕使 用者的輸入。
V. Log Forging
將未驗證使用者的輸入寫入日誌檔(log file),會允許攻擊者偽造記錄項目,
或將惡意內容注入日誌檔中。
其漏洞主要會出現在以下兩種情形,其一是資料從不可信賴的來源進入應 用程式,其二是將資料寫入應用程式或是系統日誌檔。
應用程式通常使用日誌檔來儲存事件(event)或交易記錄,以便之後檢閱、統 計資料蒐集或除錯(debugging)之用。根據應用程式的本質而定,檢閱日誌檔的工 作在需要時手動執行,或者工具自動選取重要事件或資訊。
如果攻擊者提供資料給逐字記錄內容的應用程式,則可能會誤導日誌檔的 解讀。事實上,攻擊者可能會藉由提供應用程式惡意的輸入,而將錯誤的項目 插入日誌檔。如果日誌檔會自動處理,那麼攻擊者就可以使檔案無法使用,藉 由破壞檔案格式(format)或注入(inject)預期外的字元,並利用日誌檔對程式的漏 洞進行破壞。
...
string val = (string)Session["val"];
try {
int value = Int32.Parse(val);
}
catch (FormatException fe) {
log.Info("Failed to parse val= " + val);
167
} ...
如果使用者提交字串「twenty-one」給 val,則會記錄以下項目:
INFO: Failed to parse val=twenty-one
不 過 , 如 果 攻 擊 者 傳 送 了 字 串
「 twenty-one%0a%0aINFO:+User+logged+out%3dbadguy 」, 則 會 記 錄 以 下 的 項 目:
INFO: Failed to parse val=twenty-one INFO: User logged out=badguy
故攻擊者便將字串加入日誌檔中。
其解決方法是針對日誌檔的紀錄,對於日誌檔的紀錄中,不應該逐字記錄,
可能需要相對應的對字串做切割,而在使用者輸入之字串方面,要做一些限制,
例如不允許輸入%字元,或是輸入數字時,不能輸入文字等等,以確保資料之驗 證。
VI. Often Misused: File Upload
允許使用者上傳檔案,會讓攻擊者注入危險內容或惡意程式,並執行在伺 服器(server)上。
不論撰寫任何語言的程式,最有破壞性的攻擊通常是包含遠端程式的執行,
藉此攻擊者成功的執行惡意程式碼於程式的內文(context)中。若攻擊者能夠上傳 檔 案 至 網 路 可 存 取 的 目 錄 (directory) , 並 將 這 些 檔 案 傳 遞 至 程 式 解 譯 器 (interpreter),則會造成這些檔案內包含的惡意程式碼在伺服器上執行。
HttpPostedFile posted = FileUpload.PostedFile;
以上程式碼收到上傳檔案並將其指派給 posted 物件。FileUpload 屬於
168
System.Web.UI.HtmlControls.HtmlInputFile 類型。
程式上傳的檔案儲存於無法利用網路來存取的目錄下,攻擊者仍可以經由 對伺服器環境(environment)引入惡意內容,來發動其他漏洞攻擊。若程式有其他 的漏洞,則攻擊者會上傳含有惡意內容的檔案並利用這些其他漏洞,使程式讀 取或執行該檔。
其解決方法針對檔案的上傳,程式中對於檔案上傳的撰寫,必頇對使用者 上傳檔案位置作隔離,其使用者只能上傳於自己帳號的目錄內,若其使用者要 使用此檔案,不要於伺服器上執行,將其下載於使用者電腦上並呼叫相對應之 應用程式執行,以確保伺服器之安全性。
VII. Path Manipulation
若使用者的輸入包含用在檔案系統操作的路徑,則攻擊者可存取或修改其 他受保護的系統資源。
此漏洞會發生於以下兩種情況,其一是攻擊者可指定在檔案系統中所使用 的操作路徑,其二是藉由指定資源,使攻擊者可取得一般情況下不被允許的權 限。
String rName = Request.Item("reportName");
...
File.delete("C:\\users\\reports\\" + rName);
以上的程式碼片段使用 HTTP 要求的輸入來建立一個檔案名稱。
程 式 設 計 師 沒 有 考 慮 到 攻 擊 者 也 許 會 提 供 檔 案 名 稱 , 類 似
「..\\..\\Windows\\System32\\krnl386.exe」的可能性,這會導致應用程式刪除本
169
身 krnl386.exe 此系統檔案。
其解決方法對是針對使用者的輸入,對於使用者的輸入必頇做過濾的檢查,
不允許使用者有包含\、/或是%等等許多會被當成操作字元的輸入,必頇拒絕此 輸入,否則可能造成伺服器的危險。
VIII. SQL Injection
使用者的輸入被用來建立動態 SQL 陳述(statement),可讓攻擊者修改陳述的 意義或是執行任意的 SQL 命令(command)。
此漏洞會在以下兩種情形出現,其一是資料從一個不可信賴的來源進入程 式,其二是使用者輸入之資料被用來建構動態 SQL 查詢。
...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '" + userName + "' AND itemname = '" + ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
由於這個查詢是動態的建構,其字串包含基礎查詢字串和輸入字串,所以
170
在 itemName 沒有包含單引號(single-quote)字元的時候,查詢才會正確執行。若 使用者名稱為 wiley 的攻擊者為 itemName 輸入字串 name' OR 'a'='a,那麼查詢 將變成:
SELECT * FROM items WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
附加條件 OR 'a'='a'會使 where 子句永遠為真(True),所以此查詢等同於以下 簡化的查詢:
SELECT * FROM items;
簡化的查詢會允許攻擊者略過”查詢只回傳此使用者所擁有的項目”,故查詢 現在回傳所有儲存在 items 表格中的項目。
其解決方使是針對使用輸入的值,做嚴謹的過濾,如果出現單引號字元的 輸入,將予以拒絕。