【白帽子学习笔记13】DVWA 存储型XSS(跨站点脚本攻击)
文章目录
什么是存储型XSS
- 长时间存储在服务器端
- 每次用户访问都会被执行javascript脚本
DVWA实战
安全级别:LOW
1、源码解析:
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// 获取输入
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// 过滤信息
$message = stripslashes( $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)) ? "" : ""));
// Sanitize name input
$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();
}
?>
函数分析:
1、 trim(string,charlist):移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,可选参数charlist支持添加额外需要删除的字符;
2、mysql_real_escape_string(string,connection):对字符串中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)进行转义;
3、stripslashes(string):删除字符串中的反斜杠。
源码并没有对name参数和message参数进行XSS方面的过滤和检查,并且数据储存在数据集中,属于明显的XSS漏洞;
2、漏洞利用
可以看到当用户访问这个页面的时候也就触发了,这个js代码,利用这个漏洞我们还可以完成Cookie获取,重定向啊等操作
安全级别: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进行html转义
$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();
}
?>
- message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码
- 对于name参数,这里是基于黑名单的思想,使用str_replace函数将输入中的
<script>
删除,把script脚本当作字符串来处理,仍然存在存储型的XSS
破解方法
1、大小写混合<ScRipt>alert("XSS")</ScripT>
2、script嵌套
, <sc<script>ript>
安全级别:High
-
对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码;
-
对于name参数,High级别的代码使用preg_replace() 函数用于正则表达式的搜索和替换,将script前后相关的内容都替换为空,使得双写绕过、大小写混淆绕过不再有效;(正则表达式中i表示不区分大小写)
-
虽然在name参数中无法使用
<script>
标签注入XSS代码,但是可以通过img、body等标签事件或者iframe等标签的src注入恶意的js代码。
安全等级Impossiable
- 当安全级别为impossible时,对name、message参数均使用了htmlspecialchars函数进行编码,因此无法再通过name、message参数注入XSS代码,不能实现存储型XSS攻击。