三详解 DVWA_Stored存储型XSS
Posted 在下小黄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三详解 DVWA_Stored存储型XSS相关的知识,希望对你有一定的参考价值。
创建时间:2022年5月16日21:56:10
作者:在下小黄
存储区:后端数据库
插入点:html
- 定义:
攻击者直接将恶意JS代码上传或者存储到漏洞服务器中,当其他用户浏览该页面时,站点即从数据库中读取恶意用户存入的非法数据,即可在受害者浏览器上来执行恶意代码;持久型XSS常出现在网站的留言板、评论、博客日志等交互处
- 特点:
不需要用户单击特定URL便可执行跨站脚本
- 利用方式:
直接向服务器中存储恶意代码,用户访问此页面即中招
XSS蠕虫
- 总结:
存在用户交互的地方,带有用户保存数据功能的地方,就容易出现存储型XSS(留言板、论坛发帖、商品评论、用户私信、博客日志等)
一、Stored Low 级别:
- 我们拿到这个题目的时候,首先对代码进行审计:
<?php
if( isset( $_POST[ 'btnSign' ] ) )
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input 对 message 输入进行过滤
$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 输入进行过滤
$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();
?>
---------------------------------------------------------------------------------------
PHP $_POST 变量:在 PHP 中,预定义的 $_POST 变量用于收集来自 method="post" 的表单中的值。
isset()函数在php中用来检测变量是否设置,该函数返回的是布尔类型的值,即true/false
trim()函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括\\0、\\t、\\n、\\x0B、\\r以及空格,可选参数charlist支持添加额外需要删除的字符。
stripslashes()函数用于删除字符串中的反斜杠
is_object() 函数用于检测变量是否是一个对象。
$GLOBALS :引用全局作用域中可用的全部变量。$GLOBALS 这种全局变量用于在 PHP 脚本中的任意位置访问全局变量(从函数或方法中均可)。PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。
trigger_error() 函数创建用户自定义的错误消息。函数用于在用户指定的条件下触发一个错误消息。它可以与内建的错误处理程序一起使用,或者与由 set_error_handler() 函数设置的用户自定义函数一起使用。
SQL INSERT INTO 语句用于向表中插入新记录。此代码中涉及到的是第二种用法,需要指定列名和被插入的值
mysqli_query() 函数执行某个针对数据库的查询。
mysqli_real_escape_string()函数会对字符串中的特殊符号(\\x00,\\n,\\r,\\,',",\\x1a)进行转义在代码中对message,name输入框内容没有进行XSS方面的过滤和检查。且通过query语句插入到数据库中。所以存在存储型XSS漏洞
- 代码含义:
- 首先判断输入,接收前台传递的
method="post"
表单数据 - 对接收到的数据进行预处理一次,清除传递表单数据以外的东西
stripslashes(string)
函数对'txtName',
无处理stripslashes(string)
函数对'mtxMessage'
清除传递数据中的反斜杠/
, 利用mysqli_real_escape_string()
函数对name
和message
进行转义,一般用于防止数据库撞库。- 下面就是对数据进行处理,更新写入数据库
- 接下来我们在name框中插入恶意代码,可以发现输入框对长度有所限制,一种方法我们通过bp抓包修改长度,另一种方法我们直接在控制台中修改maxlength来触发xss,如下图所示
<script>alert(document.cookie)</script>
二、Stored 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();
?>
---------------------------------------------------------------------------------------
strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。该函数始终会剥离 HTML 注释。这点无法通过 allow 参数改变。
addslashes()函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。
可以看到,由于对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS。
htmlspecialchars(string): 把预定义的字符 "<" (小于)、 ">" (大于)、& 、‘’、“” 转换为 HTML 实体,防止浏览器将其作为HTML元素
- 双写绕过
- Burpsuite抓包改name参数为:
<sc<script>ript>alert(/xss/)</script>
- 大小写混淆绕过
- Burpsuite抓包改name参数为
<ScRipt>alert(/xss/);</ScRipt>:
- 使用非
** script **
标签的** xss payload**
: - 例如:img标签:
- Burpsuite抓包改name参数为
<img src=1 onerror=alert(/xss/)>>
- 其他标签和利用还有很多很多….
- 以上抓包修改数据Forward后,均成功弹窗:
三、Stored 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 = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
可以看到,这里使用正则表达式过滤了<script>标签,但是却忽略了img、iframe等其它危险的标签,因此name参数依旧存在存储型XSS。
- Burpsuite抓包改name参数为
<img src=1 onerror=alert(/xss/)>:
- Forward后,成功弹窗:
四、Stored **Impossible **级别:
<?php
if( isset( $_POST[ 'btnSign' ] ) )
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$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)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = stripslashes( $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)) ? "" : ""));
$name = htmlspecialchars( $name );
// Update database
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
// Generate Anti-CSRF token
generateSessionToken();
?>
----------------------------------------------------------------------------------------
可以看到,通过使用htmlspecialchars函数将几种特殊字符转义为HTML实体,mysqli_real_escape_string函数对单引号'转义,防止进行SQL注入,彻底防治了存储型 XSS 的利用和危害。
- 可以看到,这次impossible在high级别的基础上对name参数也进行了更严格的过滤,导致name参数也无法进行XSS攻击。而且使用了Anti-CSRF token防止CSRF攻击,完全杜绝了XSS漏洞和CSRF漏洞。
五、参考链接:
https://www.runoob.com/sql/sql-insert.html
https://www.runoob.com/php/func-mysqli-query.html
https://www.w3school.com.cn/php/func_string_strip_tags.asp
了XSS漏洞和CSRF漏洞。
五、参考链接:
https://www.runoob.com/sql/sql-insert.html
https://www.runoob.com/php/func-mysqli-query.html
https://www.w3school.com.cn/php/func_string_strip_tags.asp
以上是关于三详解 DVWA_Stored存储型XSS的主要内容,如果未能解决你的问题,请参考以下文章