1. 程式人生 > >Asp.net安全架構之2:Session hijacking(會話劫持)

Asp.net安全架構之2:Session hijacking(會話劫持)

http://www.cnblogs.com/luminji/archive/2012/05/30/2511357.html

原理

會話劫持是指通過非常規手段,來得到合法使用者在客戶端和伺服器段進行互動的特徵值(一般為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