利用 cookie 篡改來攻擊 Web 應用程式

myattitude發表於2009-04-14
這篇文章闡述了為什麼會話管理和會話管理安全性都是複雜的工作,這就是為什麼它們經常會留給商業產品來處理。這篇文章描述這兩個商業應用程式引擎的語言符號是怎樣產生的。作者分析了每個機制的能力,闡述了它的弱勢,還論證了這樣的弱勢怎樣才能被利用,從而執行模擬和私人違規攻擊。他還討論了攻擊性的可行性。最後,他提出一種將安全性從功能中分開的會話管理的方法,並且後者由應用程式引擎實施,但是前者是由一個專門的應用程式安全產品所提供的。

cookie 篡改風險的特徵

cookie 篡改 (cookie poisoning) 是一項主要以獲取模擬和隱私權洩密著稱的技術,通過維護客戶(或終端使用者)身份的會話資訊操縱來實現的。通過打造這些 cookie ,一個黑客可以模擬一個有效的客戶,因此獲取詳細資訊並執行代表病毒的行為。這種打造的能力,像會話 cookie (或者更通俗地說,會話標識)源自於這些標識不是以安全的方式產生的事實。

內部會話維護的無休止工作

在 Web 應用程式程式設計中,會話管理是複雜且笨拙的。程式設計者會擔心會話管理的許多方面,它能夠將他/她從主要目標中的注意力分散:執行這個使此網站唯一且有用的商業邏輯。

具體問題:

  • 會話的建立和識別:您如何能夠確定何時的確需要一個新的會話,而且它確實已經建立了?程式設計者必須鑑定有一個客戶確實需要一個會話,並建立這個會話以及為這個客戶分配一個會話。
  • 併發問題:當兩個客戶同時訪問這個網站時,每個都需要一個新的會話,就有必要確保這個會話建立過程仍然能夠正確地執行。
  • 會話的終止和暫停:是什麼導致一個會話終止的呢?這些終止的會話資源是如何被重新迴圈使用的呢?當正在進行終止過程時客戶訪問這個網站,又會發生什麼情況呢?當客戶訪問帶有就的會話的網站時會發生什麼情況呢?
  • 會話資料儲存,多個伺服器,失敗。會話的資料儲存在什麼地方呢?磁碟上?隨機儲存器上?會有什麼樣的高效能懲罰?如果一個客戶訪問第一個伺服器(並建立一個會話跟它一起),然後被(負載均衡伺服器)導向到第二個伺服器,那麼在一個多伺服器站點將會發生什麼?如果原始伺服器壞掉,對這個客戶會話資料將會有什麼樣影響?

安明智,下面這些點非常重要,值得思考:

  • 一個客戶要想預測另一個客戶所接受的,或者正在接受的,或者即將接受的標識,幾乎是不可能的。這很顯然是一個必須防止的模擬攻擊,因此也會違背隱私權。
  • 此外,理想的情況是,當訪問一個站點時,客戶不能夠預測下一個他們即將獲取的標識。這對當它來回漫遊(不受阻礙)時最小化竊取標識的損壞很有用處,而且在它儲存在客戶的計算機上也很有用。
  • 任何標識都應該有一個合理的期限——可再次將它被竊取的損壞程度降到最低。

正如您所說,要實現所有的請求並不十分容易,尤其是當這個會話機制發展成無線自組織網時。就會有更復雜的安全需求來明確開發人員,尤其是對安全並不十分熟悉的人員,他們更容易遺忘。

在標識中有很多安全不足的例子。這些在 MIT Laboratory for Computer Science 的著作中有很好的證明(請看Dos and Don'ts of Client Authentication on the Web由 Kevin Fu, Emil Sit, Kendra Smith, 以及 Nick Feamster 合著)。這樣,我們就清楚生產一個良好的會話管理解決方案是相當困難的,更不用說一個安全的會話管理解決方案了。這就是為什麼應用伺服器如此這樣受人歡迎的原因之一。

應用伺服器和引擎:解決方案和問題

一個 Application Server(或者 Application Engine)就是一個軟體程式,是用來使這個應用程式開發者的工作更輕鬆。它通常會為程式開發者提供編寫 HTML 網頁的便利,而且這些網頁中帶有伺服器嵌入的指導,指示這個伺服器來執行各種任務。大多數應用伺服器會為程式開發者提供自動管理會話的環境,將程式開發人員從上皮膚塊中所有提到的擔憂中解救出來。

應用伺服器的案例:

  • Microsoft® ASP .NET, 是在 IIS 頂端進行執行的
  • Macromedia
  • ColdFusion
  • Apache Tomcat
  • Apache JServ
  • PHP
  • BEA WebLogic
  • IBM ® WebSphere® Application Server。

Security Space Web 網站的 Internet Cookie Report 網頁通過將這些 cookie 的名稱和發行它們的伺服器聯合起來,從而提供了一些頻率分析。當然,這樣說是不全面的,因為一些伺服器和站點以引數的形式而不是 cookie 的形式來使用標識的。

應用程式引擎的上面反應了這樣一個事實:他們完全將程式開發者從會話管理的擔憂中釋放出來。會話管理功能的各個方面,通常以更好的方式來管理,而並非內部程式設計師所能達到的。

應用程式引擎的下面反應了這樣的事實:他們看起來是把程式設計師從標識安全性問題的擔憂中釋放出來。然而我們可以從損害的事實顯示中看到,遠不是這樣的。事實上,一些十分受歡迎的應用程式殷勤根本就不提供安全標識。因此,程式設計師對安全性就有錯誤的意識。

我的合作伙伴和我檢測到這些標識是由兩個十分受歡迎的應用伺服器所產生的。在這兩個案例中,我們曾經證明這個標識並不是像它看起來那樣的隨意,它只是可能(在一個案例中,比較簡單)會預測下一個會話(是不同客戶的會話)標識的值。

案例 1. 打敗一個基於時間的標識

這次攻擊的目標是一個非常受歡迎的商業應用程式引擎。這個產品利用兩個 cookie 來鑑定一個會話。由兩個 cookie 形成的這對來鑑定一個會話。第一個 cookie 僅僅是一個計算器,每次有新的會話時就會增加。它大概能確保不可能有兩對是相同的。第二個 cookie 是標識 cookie ,顯然是通過“不可預知”來確保這對的安全。假設可以很輕鬆地預測第一個 cookie ,那麼我們這裡所關注的第一個 cookie ,就會被標識為TOKEN

第一眼看到的時候,TOKEN 看起來是一個隨機的八進位制數字的序列。這裡的熵是108 = 226.57,它可能是經過充分的考慮過,嘗試如此多的請求(一億次)次數是可行的,而不是一個沒有控制警告和人們注意的網站。但是靠近看就會發現,事實上, TOKEN 符合以下的方程式:

我們用t表示 GMT 時間,按秒計算,因為 01/01/1970 00:00,與這個應用伺服器上的設定一樣。
我們用m表示這個應用伺服器上最小單位毫秒。
那麼: TOKEN= ( 31415821 * (t+m) + 1 ) mod 100000000

我們注意到十分有趣的是,t可以從伺服器返回到客戶的 HTTP Date 標頭中提取出來,與這個 cookie 第一次的設定一起。這意味著 TOKEN cookie 是完全可預測的。事實上,如果有人瞭解 cookie 所產生時的時間排列 T - t < T+ΔT (按秒) ,他就可以推斷出 TOKEN 有一個ΔT+1000 值,而不是一些值的簡短列表。對伺服器測試幾千個以上的值可能要花幾分鐘,在這段時間受害者就可能仍然活躍。這就是一次攻擊演算法的大概要點:

			獲取第一對 (id1, TOKEN1)。記錄 t1 –   
			伺服器時間(從 Date HTTP 標頭開始)   
			等待ΔT 秒鐘。獲取第二對 (id22, TOKEN2)。
			記錄 t2–伺服器時間從 Date HTTP 標頭開始)。
			如果 (id2 > id1 +1)   開始 // 
			我們在這裡插入看一個受害者會話。
			對於 (x= t1 ; x < t2+1000 ; x++) //  
			它只是ΔT+1000 迭代開始   
			嘗試這對 (id1 +1, ( 31415821 * x + 1 ) mod 100000000) 終止

事實上,通過利用這樣的事實在某些案例中改進這個演算法是可能的,在有些作業系統上,最小單位的計數器並沒有精確到毫秒的粒度,而是較粗糙的10毫秒的粒度。這可被用來減少更多的搜尋空間。

上面所描述的攻擊可以使攻擊者來扮演一個受害者的角色,假定這樣的受害者被分配到兩個由站點 cookie 構成的樣例攻擊者之間。因為攻擊者可以任意重複很多次這樣的演算法,這樣攻擊者就可能為客戶獲取這些 cookie ,以抽樣這個站點(就是說,每分鐘一個請求)為代價,此外,每次發現新客戶時就有1060個請求。正如上面所暗示的,在更近的間隔(每次一秒)中抽樣以及利用時鐘最小單位粒度的問題是有可能的,在這樣的案例中很可能達到每個新客戶100個請求。

如果在網路擁擠時下載這個站點執行了一個客戶的模擬嘗試,那麼額外的數百或者數千計的請求就會不被注意,至少不會立即被注意。

案例 2. 當 Random() 不是隨機時

在這個例子中,我們處理一個仍舊流行的(然而有些過時的)應用程式引擎。這個引擎為每個新會話產生一個單獨的 cookie (我們稱它為ID),包括三個強制性的區域(F1,F2,以及F3)以及一個可選擇的(伺服器配置從屬)區域(F4,在句號之前)的多連環體。這些區域如下所示:

			F1 = 6 字串(A-Z0-9) – PRNG (Pseudo Random Number Generator) 資料,
			用基礎36附帶領頭的零來表示F2 = 3 字串 (A-Z0-9) –  
			伺服器時間(毫秒),被 2000 除,
			絕對值為 363 (=46656), 用基礎36附帶領頭的零來表示   
			F3 = 3字串(A-Z0-9) – 會話在這兩秒時間內計算,用基礎36來表示 36 
			F4 = 不變的字串(每個伺服器)
			

正如您所看到的,F4 (如果它存在的話) 是常量,因此可以進行瑣碎的預測。 F2 僅僅是這個伺服器時間(以秒計算)除以2,模數為 46656,它是一個完全可預測性的,以及 F3 也不是特別不出名——它隨著時間的推移在每兩秒內連續地增長(通常從1開始)。

唯一有趣的區域是 F1。顯然,它有足夠的熵來確保這個系統的安全,因為它能夠假定 366值(=231.0)。然而,第一眼看起來安全的其實在執行完整的分析時並不那麼安全。在 Appendix A 中闡述了 F1是如何以及為什麼可以被預測的,因為太長所以這裡沒有包含這部分呢內容。我們利用 F1所解決問題的事實是它使用了一個 PRNG (Pseudo Random Number Generator),它本質上就是可預測的。因此瞭解幾個 F1 的值從而全面預測這個 PRNG,也就是未來的(和過去的) F1值。

這就是這樣一次攻擊的概要:

準備工作:
獲取三個 ID,在最短的時間間隔中是可能的。
摘取 PRNG 內部狀態(正如 Appendix A 中所闡述的)。
截獲週期獲得一個 ID,以及記錄伺服器時間,t。
簡單地說,假設t是偶數。
找出 PRNG 內部曾經用來產生這個 ID 的狀態(正如 Appendix 中所描述的) 
等到 ΔT 秒 (這裡的ΔT 是偶數)  就獲取一個新的 ID。
增加這個 PRNG,並記錄舊的 ID 和產生這個 ID 之間的內部狀態(正如 Appendix 中所描述的)。使內部值的列表為 L 
//ΔT/2 迭代:
for (T=t; T

正如您所看到的,它是可行的,儘管比較重要,可以預測一些 ID cookie 。對於可行性,它要求時間間隔(ΔT)很簡短(並且與這臺伺服器的期望使用是相關的),為了最小化 L 的長度(內部 PRNG 狀態可能的列表)。如果這些間隔的確十分簡短(不超過兩秒),並且是正確地計時,是可能的,要分辨一個新的會話是否在當前兩秒鐘時間內被插入,它可以使的這次攻擊有更高的效率(只有當了解一個新的受害者會話的確已經建立後它才需要啟用額外的請求)。它還應該被提到的是,避免丟失與這個網站的同步化 (PRNG 內部狀態的同步化),還需要保持不時地請求新 ID 的狀態,從而加強這個攻擊者對新值的 PRNG 內部狀態。要記住的是,PRNG 很可能因為各種目的而是使用,這樣就導致一個快速的去同步化 (要為它計算,就需要在一個封閉的時間間隔中重新使其同步化,比如每幾分鐘)。從另一方面看,通過檢查應用在這個網站中其它的隨機值,可能更清楚地看清 PRNG 的內部狀態。這樣可能會提供一個捷徑,節省大量的計算能量。

值得注意的是,當這個攻擊者與這個網站同步時,如果 IDs 可以頻繁地被提取,就可能在傳送一些請求的消耗中模擬任何客戶端 (它取決於 PRNG 的使用)。

相關供應商的看法

Vendor 1 承認這些缺陷,並通知我們他的消費客戶對於會與管理應該使用 SSL 資格認證。儘管這對於一些消費者來說可能是一個好訊息 (但是明確地說並不是所有的消費者,因為移動到 SSL 以及 SSL 資格認證的確很重要 並且有時是不可能的),這個產品的文獻引導讀者相信這個內嵌的會話管理是安全的(在他們給開發人員的文獻中,他們稱它為“客戶安全標識”)。當然,這個供應商並沒有把這個建議公開。

Vendor 2 承認了這些缺陷,然後給我們寫信說:“會話 cookie 不是一個可代替的認證標識。一個連線中的會話 cookie 與一個隨機鑑定標識或者鑑定登陸稽核都是合理的機制。這在設計基於指令碼的會話是可實現的——即使這裡的會話標識今天是‘可信任的’。”因此,他們將這個責任交到開發人員的手中。

這兩個供應商,都從技術上承認了這個問題,卻將它解散成一個非安全性問題。也就是說,兩個供應商假設他們的消費客戶執行他們自己的會話安全標識,而不是依賴於這個供應商的標識,因此,他們聲稱他們的標識僅僅是用來(或者應該用來)更好區分不同的使用者,而不是作為一個安全性評估。在這個文獻中,我們沒有找到任何關於將這個標識作為安全會話識別符號的警告。進一步說, Vendor 1的文獻使用了引導使用者相信這個標識是安全的短語。然而實際上,絕大多數站點使用這個由供應商釋出的標識作為安全會話的識別符號,而忽略了它是有缺陷的事實。

從某種意義上說,應用程式開發人員又回到了這個一致性問題:開發人員不能相信這個內嵌的會話確認機制;因此,他們強呼叫他們最大的努力編寫他們自己的機制,從而實現先前所提到的所有需求,避免密碼系統的細微陷阱。

結論

病毒的闖入導致會話安全出現問題的事情發生頻率非常高。Vendors 沒有將它改正,也沒有在乎它,或者將這個責任委託給開發人員。內部的開發是很容易出錯的,並且需要對安全性有深入的理解。這篇文章提供了商業應用程式引擎中以及自身應用程式中不安全的真實案例。

這個結論很簡單: Web 應用程式的世界應該包括三個部:

  • 應用程式(它是在內部開發,表達了商業邏輯,以及這個公司或網站的新穎和獨特之處)。
  • 應用程式的環境(這個應用程式引擎和 Web 伺服器,它使軟體開發變得更容易,並且集中強調應用程式而不是組織結構)。
  • Web 應用程式安全構件,它負責這個軟體的安全性,再次將開發人員(在某種程度上,也是這個應用程式引擎的開發人員!)從他們的應用程式安全執行的擔憂中解救出來。

在這裡所描述的案例中, 很顯然 Web 應用程式防火牆應該加強這個應用程式引擎或者內部開發的應用程式對標識的產生(開發人員甚至不需要意識到這個問題)。他應該確保——通過使用加強的密碼系統和安全測試機制——傳送到應用程式的標識確實是真實的,而非虛假的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780914/viewspace-588984/,如需轉載,請註明出處,否則將追究法律責任。

相關文章