本篇繼續對於安全性測試話題,結合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吧。