DVWA V1.9:Reflected Cross Site Scripting(存儲型XSS)

存儲型 XSS 介紹

“跨站點腳本(XSS)”攻擊是一種注入問題,其中惡意腳本被注入到其他良性的和可信的網站中。
當攻擊者使用Web應用程序將惡意代碼(通常以瀏覽器端腳本的形式)發送給不同的最終用戶時,會發生XSS攻擊。
允許這些攻擊成功的缺陷非常普遍,並且在Web應用程序的任何地方使用來自用戶的輸入在輸出中發生,而不驗證或編碼它。

攻擊者可以使用XSS向惡意的用戶發送惡意腳本。
終端用戶的瀏覽器沒有辦法知道腳本不應該被信任,並且將執行JavaScript。

因爲它認爲腳本來自可信來源,惡意腳本可以訪問任何cookie、會話令牌或瀏覽器保留的其他敏感信息,並與該站點一起使用。
這些腳本甚至可以重寫HTML頁面的內容。

XSS存儲在數據庫中。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漏洞。

官方提示

低電平將不檢查請求輸入,然後將其包含在輸出文本中使用。

Spoiler: Either name or message field: <script>alert("XSS");</script>.

漏洞利用

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

在這裏插入圖片描述
在這裏插入圖片描述

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

在這裏插入圖片描述
在這裏插入圖片描述

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的標籤,但允許使用標籤。

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

可以看到,由於對message參數使用了htmlspecialchars函數進行編碼,因此無法再通過message參數注入XSS代碼,但是對於name參數,只是簡單過濾了《script》字符串,仍然存在存儲型的XSS。

官方提示

開發者已經添加了一些保護,但是並沒有以相同的方式完成每一個領域。

Spoiler: name field: <sCriPt>alert("XSS");</sCriPt>.

漏洞利用

雙寫繞過,大小寫繞過,兩個方法都行,步驟一樣不復述了。

雙寫:<sc<script>ript>alert(/xss/)</script>
大小寫:<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 = 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();
}

?>

可以看到,這裏使用正則表達式過濾了

官方提示

開發人員現在相信他們可以通過刪除模式 “<scrip*t” 來禁用所有JavaScript

Spoiler: HTML events.

漏洞利用

步驟差不多,就不復述了。

利用格式:<img src=1 onerror=alert(1)>

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

?>

High Stored XSS Source
<?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();
}

?>

Medium Stored XSS Source
<?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();
}

?>

Low Stored XSS Source
<?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();
}

?>

可以看到,通過使用htmlspecialchars函數,解決了XSS,但是要注意的是,如果htmlspecialchars函數使用不當,攻擊者就可以通過編碼的方式繞過函數進行XSS注入,尤其是DOM型的XSS。

官方提示

使用內置PHP函數(如htmlspecialchars()“”它可以逃避任何會改變輸入行爲的值。

參考鏈接:
新手指南:DVWA-1.9全級別教程(完結篇,附實例)之XSS

發佈了198 篇原創文章 · 獲贊 27 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章