原理
會話劫持是指通過非常規手段,來得到合法用戶在客戶端和服務器段進行交互的特征值(一般為sessionid),然后偽造請求,去訪問授權用戶的數據。
獲取特征值的非常規有段主要有如下幾種:
首先是猜測的方式,如果我們的sessionid的生成是有規律的,那么使用猜測的方式就可以到達非法獲取的目的,如圖所示:
其次是session fixation攻擊。session fixation攻擊是指用戶通過XSS、網絡嗅探、本地木馬來得到特征值,這些交互的特征值一般來說放置在瀏覽器的Cookie中(當然,我們也知道sessionid也可以通過URL來傳遞,這樣的話,獲取就簡單多了)。然后誘使用戶去完成一次登錄(誘使的方法可使發郵件,發鏈接等)。如果服務器沒有更新這個SessionID,則攻擊者可以憑借此SessionID登錄系統,如圖所示:
在特征值被獲取到之后,攻擊者還可以使用Session保持攻擊,這一般是指寫一段小代碼,定時發送請求,保持Session有效。這樣,攻擊者,就可以一直利用這個合法用戶進行非法活動。
實際案例
在http://yourdomain.com/default.aspx界面,我們偷到了sessionID,然后就可以模擬這樣的請求來完成一次攻擊。一次攻擊是指,拿上如下的請求,我們可以在任意客戶端進行登錄。
User-Agent: Fiddler
Host: 192.168.40.193
Cookie: LoginName=luminji; ASP.NET_SessionId=xzyplp45wgl3rf45ssxt5h55;
同時,在客戶端寫一段腳本,還可以完成Session保持攻擊。經過這樣的處理后,非法用戶不用登錄系統就可以訪問任意頁面了。
應對策略
1:為Cookie設置httpOnly,就可以有效防止Cookie被非法讀取,從而防止劫持;
2:每次登錄更換SessionID。
具體措施
n 查看sessionid生成策略,確保不可被猜測
備注,sessionid在asp.net程序中是被自動生成為GUID形式的,所以在Asp.net程序中該項不需要被修改。
n 查看sessionid保存策略,確保不通過URL進行傳遞
n 每次登錄更換sessionid
改進登錄模塊,每次登錄更換sessionid。更換sessionid並不會影響有些站點的類似“一個星期”都不用登錄的功能。如果攻擊者不是從合法用戶的本機獲取的sessionid,那么完成此次升級后,session fixation攻擊就被阻斷了。
更換SessionID的函數為:
private void ChangeSessionID() { SessionIDManager m = new SessionIDManager(); m.RemoveSessionID(Context); HttpApplication ctx = (HttpApplication)Context.ApplicationInstance; HttpModuleCollection mods = ctx.Modules; SessionStateModule sessionStateModule = (SessionStateModule)mods.Get("Session"); System.Reflection.MethodInfo CreateSessionId = sessionStateModule.GetType().GetMethod( "CreateSessionId", BindingFlags.Instance | BindingFlags.NonPublic); System.Reflection.MethodInfo InitStateStoreItem = sessionStateModule.GetType().GetMethod( "InitStateStoreItem", BindingFlags.Instance | BindingFlags.NonPublic); CreateSessionId.Invoke(sessionStateModule, null); SessionStateUtility.RemoveHttpSessionStateFromContext(Context); InitStateStoreItem.Invoke(sessionStateModule, new object[] { true }); FieldInfo sessioninfo = this.GetType().BaseType.BaseType.GetField( "_session", BindingFlags.NonPublic | BindingFlags.Instance ); sessioninfo.SetValue(this, HttpContext.Current.Session); }
n 確保登錄邏輯不僅僅依賴sessionid
如果登錄邏輯不僅僅依賴sessionid,攻擊者將需要得到全部的特征值(一般情況下,就是說意味着他要得到全部和登錄相關的cookie值),這加大了攻擊難度。
n 確保Cookie的httponly
通過文件查找所有的”cookie”,找出所有設置cookie的地方,為用於認證的cookie設置如下的格式:
Set-Cookie: cookieName=cookieValue;httponly