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 else
17 {      
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";   #設置sessionID
14 $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、參考文獻

1. 《Session攻擊手段(會話劫持/固定)及其安全防御措施

 

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

 作者:那一葉隨風   http://www.cnblogs.com/phpstudy2015-6/

 原文地址:http://www.cnblogs.com/phpstudy2015-6/p/6776919.html

 聲明:本博客文章為原創,只代表本人在工作學習中某一時間內總結的觀點或結論。轉載時請在文章頁面明顯位置給出原文鏈接

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM