1. 程式人生 > >Session攻擊(會話劫持+固定)與防禦

Session攻擊(會話劫持+固定)與防禦

回到頂部

1、簡介

  Session對於Web應用無疑是最重要的,也是最複雜的。對於web應用程式來說,加強安全性的第一條原則就是 – 不要信任來自客戶端的資料,一定要進行資料驗證以及過濾,才能在程式中使用,進而儲存到資料層。 然而,為了維持來自同一個使用者的不同請求之間的狀態, 客戶端必須要給伺服器端傳送一個唯一的身份識別符號(Session ID)。 很顯然,這和前面提到的安全原則是矛盾的,但是沒有辦法,http協議是無狀態的,為了維持狀態,我們別無選擇。 可以看出,web應用程式中最脆弱的環節就是session,因為伺服器端是通過來自客戶端的一個身份標識來認證使用者的, 所以session是web應用程式中最需要加強安全性的環節。 

  基於session的攻擊有很多種方式。大部分的手段都是首先通過捕獲合法使用者的session, 然後冒充該使用者來訪問系統。也就是說,攻擊者至少必須要獲取到一個有效的session識別符號,用於接下來的身份驗證。 

  攻擊者至少可以通過以下三種方式來獲取一個有效的session識別符號:

  1、預測

  2、捕獲(劫持)

  3、固定

回到頂部

2、會話預測

  預測這種方式,也就是攻擊者需要猜測出系統中使用的有效的session識別符號(PHP中格式為PHPSESSID=1234),有點類似暴力破解。 php內部session的實現機制雖然不是很安全,但是關於生成session id的關節還是比較安全的,這個隨機的session id往往是極其複雜的並且難於被預測出來,所以說,這種攻擊方式基本上是不太可能成功的。 

回到頂部

3、會話劫持

回到頂部

  3.1、含義

  會話劫持(Session hijacking),這是一種通過獲取使用者Session ID後,使用該Session ID登入目標賬號的攻擊方法,此時攻擊者實際上是使用了目標賬戶的有效Session。會話劫持的第一步是取得一個合法的會話標識來偽裝成合法使用者,因此需要保證會話標識不被洩漏。

回到頂部

  3.2、攻擊步驟

  1、 目標使用者需要先登入站點;

  2、 登入成功後,該使用者會得到站點提供的一個會話標識SessionID;

  3、 攻擊者通過某種攻擊手段捕獲Session ID

      4、 攻擊者通過捕獲到的Session ID訪問站點即可獲得目標使用者合法會話。

攻擊者獲取SessionID的方式有多種:

       1、 暴力破解:嘗試各種Session ID,直到破解為止;

       2、 預測:如果Session ID使用非隨機的方式產生,那麼就有可能計算出來;

       3、 竊取:使用網路嗅探,XSS攻擊等方法獲得。

   對於PHP來說,其內部Session的實現機制雖然不是很安全,但是關於生成Session ID的環節還是比較安全的,這個隨機的Session ID往往是極其複雜的並且難於被預測出來,所以,對於第一、第二種攻擊方式基本上是不太可能成功的。

  對於第三種方式大多使用網路資料通訊層進行攻擊獲取,可以使用SSL進行防禦。

  在應用層上也可以做出相應的防禦措施:

  目前有三種廣泛使用的在Web環境中維護會話(傳遞Session ID)的方法:URL引數,隱藏域和Cookie。其中每一種都各有利弊,Cookie已經被證明是三種方法中最方便最安全的。從安全的觀點,如果不是全部也是絕大多數針對基於Cookie的會話管理機制的攻擊對於URL或是隱藏域機制同樣適用,但是反過來卻不一定,這就讓Cookie成為從安全考慮的最佳選擇。

回到頂部

  3.3、防禦方法

1、 更改Session名稱。PHP中Session的預設名稱是PHPSESSID,此變數會儲存在Cookie中,如果攻擊者不分析站點,就不能猜到Session名稱,阻擋部分攻擊。

      2、 關閉透明化Session ID。透明化Session ID指當瀏覽器中的Http請求沒有使用Cookie來存放Session ID時,Session ID則使用URL來傳遞。

      3、 設定HttpOnly。通過設定Cookie的HttpOnly為true,可以防止客戶端指令碼訪問這個Cookie,從而有效的防止XSS攻擊。

      4、 關閉所有phpinfo類dump request資訊的頁面。

      5、驗證HTTP頭部資訊

     在http訪問標頭檔案:[Accept-Charset、Accept-Encoding、Accept-Language、User-Agent],瀏覽器一般發出的頭部不會改

  使用User-Agent檢測請求的一致性。

複製程式碼
 1 GET/HTTP/1.1 2 host:example.org 3 User-Agent:Firefox/1.0 4 Accept:text/html,image/png,image/jpeg,image/gif,*/* 5 Cookie:PHPSESSID=1234 6 <?php 7 session_start(); 8 if(isset($_SESSION['HTTP_USER_AGENT'])) 9 {    10         if($_SESSION['HTTP_USER_AGENT']!=md5($_SERVER['HTTP_USER_AGENT']))11         {12                         /*Promptforpassword*/13                        exit;14         }15 }16 else17 {      
18   $_SESSION['HTTP_USER_AGENT']=md5($_SERVER['HTTP_USER_AGENT']);19 }20 ?>
複製程式碼

  確保User-Agent頭部資訊一致的確是有效的,如果會話標識通過cookie傳遞,攻擊者能取得會話標識,他同時也能取得其它HTTP頭部。由於cookie暴露與瀏覽器漏洞或跨站指令碼漏洞相關,受害者需要訪問攻擊者的網站並暴露所有頭部資訊。則攻擊者只需重建頭部即可進行攻擊了

  因此前提需要做好XSS防禦!

  注意:

在某些版本的IE瀏覽器中,使用者正常訪問一個網頁和重新整理一個網頁時發出的Accept頭部資訊不同,因此Accept頭部不能用來判斷一致性。

  有專家警告不要依賴於檢查User-Agent的一致性。這是因為伺服器群集中的HTTP代理伺服器會對User-Agent進行編輯,而本群集中的多個代理伺服器在編輯該值時可能會不一致。  

  6、 加入Token校驗。同樣是用於檢測請求的一致性,給攻擊者製造一些麻煩,使攻擊者即使獲取了Session ID,也無法進行破壞,能夠減少對系統造成的損失。但Token需要存放在客戶端,如果攻擊者有辦法獲取到Session ID,那麼也同樣可以獲取到Token。

回到頂部

4、會話固定

回到頂部

  4.1、含義

  會話固定(Session fixation)是一種誘騙受害者使用攻擊者指定的會話標識(SessionID)的攻擊手段。這是攻擊者獲取合法會話標識的最簡單的方法。讓合法使用者使用黑客預先設定的sessionID進行登入,從而是Web不再進行生成新的sessionID,從而導致黑客設定的sessionId變成了合法橋樑。

  會話固定也可以看成是會話劫持的一種型別,原因是會話固定的攻擊的主要目的同樣是獲得目標使用者的合法會話,不過會話固定還可以是強迫受害者使用攻擊者設定的一個有效會話,以此來獲得使用者的敏感資訊。

回到頂部

  4.2、攻擊步驟

       1、 攻擊者通過某種手段重置目標使用者的SessionID,然後監聽使用者會話狀態;

       2、 目標使用者攜帶攻擊者設定的Session ID登入站點;

       3、 攻擊者通過Session ID獲得合法會話

Web接收sessionID機制:

  早期瀏覽器存貯的sessionID容易暴露、使用URL來傳送sessionID

首先檢查攜帶cookie是否含有sessionID;若沒有則再檢查getpost資料中是否含有,若有則使用此資料;沒有才會使系統生成一個sessionID發給客戶端。(經測試,get與post都不能設定sessionID【也許是被瀏覽器限制或者被程式碼本身禁止了吧,不過沒關係,咱還有其他方法進行固定sessionID!】)

重置sessionID方式:

  • (一)使用客戶端指令碼來設定Cookie到瀏覽器。大多數瀏覽器都支援用客戶端指令碼來設定Cookie的,例如document.cookie="sessionid=123",這種方式可以採用跨站指令碼攻擊來達到目的。防禦方式可以是設定HttpOnly屬性,但有少數低版本瀏覽器存在漏洞,即使設定了HttpOnly,也可以重寫Cookie。所以還需要加其他方式的校驗,如User-Agent驗證,Token校驗等同樣有效。

測試例子:

html頁面(表單),用於跨站指令碼攻擊

複製程式碼
 1 <!DOCTYPE html> 2 <html> 3 <head> 4     <title>重置sessionID(一)</title> 5     <meta charset="utf-8"> 6 </head> 7 <body> 8 <form action="./test2.php" method="post"> 9 name:<input type="text" name="name"><br/>10 age:<input type="text" name="age"><br/>11 <input type="submit" name="" value="提交">12 </form>13 </body>14 </html>
複製程式碼

接收表單 ,test2.php

複製程式碼
 1 <?php 2 header("content-type:text/html;charset=utf8"); 3 session_start(); 4 if(!isset($_SESSION['count']))  #自增測試 5 { 6     $_SESSION['count']=0; 7 } 8 else 9 {10     $_SESSION['count']++;11 }12 echo '$_POST資料:';13 echo "<pre>";14 print_r($_POST);        #不處理資料直接接收15 echo "</pre>";16 echo '$_SESSION資料:';17 echo "<pre>";18 print_r($_SESSION);19 echo "</pre>";die;20 ?>    
複製程式碼

 測試:

  1、表單中插入資料,並提交。然後不斷重新整理test2.php

<script type='text/javascript'> document.cookie='PHPSESSID=12345' </script>

  2、接著分別檢視sessionID以及count數值

  3、在其他瀏覽器中,執行相同的步驟1(保證sessionID與之前相同)和2,可以看到count初始值不是0,而是在之前的基礎上增加的。

 結論:盜取sessionID成功!

  • (二)使用HTML的<META>標籤加Set-Cookie屬性。伺服器可以靠在返回的HTML文件中增加<META>標籤來設定Cookie。例如<meta http-equiv='Set-Cookie' content='PHPSESSID=22333'>,與客戶端指令碼相比,對<META>標籤的處理目前還不能被瀏覽器禁止。【只要讓此行程式碼在伺服器中執行即可入侵】

 測試:

  只要讓此行程式碼執行即可,(<meta http-equiv='Set-Cookie' content='PHPSESSID=22333'>)即可。我們將它放入表單中然後提交給PHP;接著不斷重新整理,再換瀏覽器執行相同步驟。和上面的測試一樣!接著檢視結果

  • (三)使用Set-Cookie的HTTP響應頭部設定Cookie。攻擊者可以使用一些方法在Web伺服器的響應中加入Set-Cookie的HTTP響應頭部。如會話收養,闖入目標伺服器所在域的任一主機,或者是攻擊使用者的DNS伺服器。

測試:(偽造瀏覽器執行http請求)

  1、攻擊者控制的伺服器(www.test88.com)

  2、www.test88.com/test99.php

  客戶訪問這個頁面,無形之中就簡介訪問第三方網站,並繫結一個sessionID;攻擊者就可以掌握這個sessionID進行相應的攻擊了

複製程式碼
 1 <?php 2 header("content-type:text/html;charset=utf8"); 3 $host='www.linuxtest.com'; 4 $port=80; 5 $a=fsockopen($host,$port); 6  7 //請求行 8 $request_data="Get /test2.php HTTP/1.1\r\n"; 9 //請求頭10 $request_data.="Host: www.linuxtest.com\r\n";11 $request_data.="User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:10.0) Gecko/20100101 Firefox/10.0\r\n";12 $request_data.="Connection: keep-alive\r\n";13 $request_data.="Cookie: PHPSESSID=99999\r\n";   #設定sessionID14 $request_data.="\r\n"; //空行表示頭結束15 //傳送資料16 fwrite($a,$request_data);17 18 #用於測試19 //接收資料20 $inheader=1;21 while(!feof($a))22 {23     //echo fgets($a,1024);24     //除去請求頭,只顯示返回資料25     $data=fgets($a,1024);26     if($inheader && ($data=="\n" || $data=="\r\n"))27     {28         $inheader=0;29     }30     if($inheader==0)31     {32         echo $data;33     }34 }35 //關閉請求36 fclose($a);37 38 ?> 
複製程式碼

  1、使用者訪問這個頁面,並不斷重新整理,然後檢視頁面中的count值

  2、接著,模擬黑客進行攻擊。

  在表單中插入資料(<script type='text/javascript'> document.cookie='PHPSESSID=99999' </script>),然後提交,並不斷重新整理test2.php,並觀察count值。【換不換瀏覽器都可以,本質上講黑客構造的http訪問程式碼就相當於一個獨立的瀏覽器】

  結果顯示:count值是接著上面的4不斷增加!此時證明攻擊成功!

回到頂部

  4.3、防禦方法

1、每當使用者登陸的時候就進行重置sessionID

2、sessionID閒置過久時,進行重置sessionID

3、 大部分防止會話劫持的方法對會話固定攻擊同樣有效。如設定HttpOnly,關閉透明化Session ID,User-Agent驗證,Token校驗等。

【多個方法結合使用】

回到頂部

5、參考文獻

(以上是自己的一些見解,若有不足或者錯誤的地方請各位指出)

 宣告:本部落格文章為原創,只代表本人在工作學習中某一時間內總結的觀點或結論。轉載時請在文章頁面明顯位置給出原文連結