本篇繼續對於安全性測試話題,結合DVWA進行研習。
Session Hijacking使用者會話劫持
1. Session和Cookies
這篇嚴格來說是使用者會話劫持諸多情況中的一種,通過會話標識規則來破解使用者session。
而且與前幾篇不同,我們有必要先來理解一下Session和Cookie的工作機制。
實際上要談論這兩個小夥伴,又要先理解http協議的運作機制,這樣討論下去可就篇幅太長了。
我們只需要瞭解以下事實:
- http協議是無狀態的
就好像兩個人用老式的手搖電話機通電話。每一次http請求和資料交換就像這樣的一次電話通話過程,當請求完畢以後,再進行下一次請求時,http協議是無法追蹤上一則通話記錄的。這樣每一次使用者與伺服器的互動都是獨立的一次通話,對於一個web應用而言顯然是存在問題的,因為使用者的請求十有八九具有連續性。就比如一個使用者在商城新增了某商品到購物車,當他去結賬時,又是一次新的請求,他的購物車http協議僅僅通過連線狀態是無法追蹤的!
- Session:來來來 給你分配個號碼牌
為了解決使用者的接續訪問問題,一個簡單的想法就是,將每一次使用者與伺服器之間的持續通話做為一個“會話”存放在伺服器端。
當使用者第一次打call進來的時候,你先別說話,先給你個小牌牌,這個小牌牌就用來做為這次使用者會話的跟蹤。
在我們的應用內通常使用sessionID或者類似的形式進行記錄。
- Cookie:請你證明你是你,你媽是你媽
在會話中我們有了標識自己身份的號碼牌,由伺服器生成頒發。使用者拿到小牌牌,當然要妥善保管啦,將他存放到cookie裡面就是現在的主流手段。當使用者繼續向伺服器發出互動時,每一次接線員都先看一看這個小牌牌,證明你是你,然後再繼續給你服務,不然別怪我翻臉不認人。
他們關係就類似這樣嬸兒的:
下圖就是在DVWA上面我的使用者cookie,使用JS彈框將其展示出來的效果:
2. Session Hijacking會話劫持攻擊
瞭解session和cookie的原理機制之後,我們來思考,如果我是攻擊者,我有沒有方法利用到使用者的cookie和session?
這種思路是有很多的:
- 一種思路是,攻擊者不獲取使用者的cookie和session,而是想辦法讓使用者在不知情的情況自己去踩坑。
比如上一篇我們講CSRF跨站指令碼偽造時,就是讓已經被伺服器驗證通過的使用者來幫我做一個操作。
- 另一種思路是,攻擊者自己創造一個session資訊,然後誘使使用者使用這套session。
如果使用者使用這套session進行了登入,那麼攻擊者使用同樣的session去訪問,就擷取到了使用者這次會話了。(這種攻擊叫Session Fiaxtion - 固定會話攻擊)
- 另一種思路則更直接,我想辦法獲取到使用者的會話資訊,那麼我就能夠盜取使用者的身份了。
這些就是所謂的session hijacking,使用者會話劫持。
那麼接下來的問題是,攻擊者如何能獲取到使用者會話呢?
通過XSS攻擊漏洞就可以達成目標,這個我們會在後續去探討。
其實還有更簡單的方式,伺服器所頒發的這個session的識別符號,也是基於一定的規則生成的。如果這套規則過於簡單,那麼通過猜都能猜出來!
DVWA的weak session IDs 模組
DVWA就給我們演示了什麼叫過於簡單的session規則:
真是。。。太簡單了,簡單的數字遞增。想要攻擊,很容易就可以猜出sessionid,然後加以利用。
3. sessionID的更合理頒發機制
下面我們同樣看看DVWA是如何加強session頒發機制的:
Medium級別防禦
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = time();
setcookie("dvwaSession", $cookie_value);
}
?>
使用時間戳來生成session標識,還是挺好猜的。
High級別防禦
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0;
}
$_SESSION['last_session_id_high']++;
$cookie_value = md5($_SESSION['last_session_id_high']);
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
?>
頒發完了的sessionID長這樣:
看起來好厲害哦,MD5加密了。
然鵝,破解他只需要0.05秒的MD5線上解密瞭解一下?
Impossible防禦
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = sha1(mt_rand() . time() . "Impossible");
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], true, true);
}
?>
使用隨機數+時間戳+常量字串+sha1加密。好吧,確實很難猜出來了,是不是impossible呢?唔。。。
4. 會話劫持的測試
事實上到此為止我們還不能全面討論會話劫持的測試,因為還有很多種劫持的方法我們沒有去了解。
不過呢,我們可以借這個機會來解釋一下安全測試的大方向。
路是一步步走出來的,同樣的道理,產品的安全能力也是一層一層構建起來的。
一個產品的防禦機制是一種典型的1+1>2的概念。
我在專案中間經常看到這種現象:由於現在的前端技術也比較成熟了,很多後端工程師就依賴於前端去完成資料校驗工作,後端校驗就省去了。
但是實際上任何產品的安全機制都應該是層層疊加的體系,任何單層的防禦都不能確保產品的絕對安全。
上面提到的前後端校驗就是很好的例子:前端校驗實在太容易繞過了,後端必須要做好二重校驗,這就是個雙保險的概念。
回到使用者劫持攻擊的測試,session標識頒發規則就是產品層疊防禦機制中的其中一層。
測試人員可以通過解讀這一規則來判斷他的合理性。簡單來說,如果你們的session標識規則,你能夠想辦法破解掉,不用想了報bug吧。