Web安全学习之——基于dvwa的XSS (Stored)学习教程

1.什么是XSS(stored)?

存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie等

例子:

  1. 发一篇文章,里面包含了恶意脚本
今天和女朋友出去约会了,心情不错<script>alert('handsome boy')</script>
  1. 后端没有对文章进行过滤,直接保存文章内容到数据库。

  2. 当其他人看这篇文章的时候,包含的恶意脚本就会执行。

注:因为大部分文章是保存整个HTML内容的,前端显示时候也不做过滤,就极可能出现这种情况。

结论:
后端尽可能对提交数据做过滤,在场景需求而不过滤的情况下,前端就需要做些处理了。

Low level

先看看代码:

<?php 

if( isset( $_POST[ 'btnSign' ] ) ) { 
    // 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)) ? "" : "")); 

    // 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(); 
} 

?> 

分析代码

trim(string,charlist)

trim函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括**\0、\t、\n、\x0B、\r以及空格**,可选参数charlist支持添加额外需要删除的字符。

mysqli_real_escape_string(string,connection)

mysqli_real_escape_string函数会对字符串中的特殊符号(\x00,\n,\r,\,’,",\x1a)进行转义

stripslashes(string)

函数删除字符串中的反斜杠。

分析代码可知:程序对输入并没有做XSS方面的过滤与检查,且存储在数据库中,因此这里存在明显的存储型XSS漏洞

输入
name:123
message:this is a test 

在这里插入图片描述

输入
name:123
message:123<script>alert('xss')</script>

在这里插入图片描述
点击刷新
在这里插入图片描述
成功弹框,且注意到message只显示了123,后面的<script>被隐藏
接下来我们试试在name中输入payload

输入
name:123<script>alert('xss')</script>
message:123

在这里插入图片描述
发现输入不了,查看源代码
在这里插入图片描述
显然name属性值最大值为10,长度明显受到限制。

Medium level

先看代码:

<?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();
}

?>

分析代码:
(1)strip_tags()函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用<b>标签。

例:
<?php
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";

// 允许 <p> 和 <a>
echo strip_tags($text, '<p><a>');
?>

以上代码将输出:

Test paragraph. Other text
<p>Test paragraph.</p> <a href="#fragment">Other text</a>

(2)addslashes()函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。

例:
<!DOCTYPE html>
<html>
<body>

<?php 
$str = addslashes('Shanghai is the "biggest" city in China.');
echo($str); 
?>  

</body>
</html>

以上代码将会输出:

Shanghai is the \"biggest\" city in China.

(3)htmlspecialchars()函数把预定义的字符转换为 HTML 实体。
预定义的字符是:

& (和号)      
" (双引号)         
' (单引号)       
< (小于)        
 > (大于)

由于对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS。
因此我们可以通过burpsuite来抓包,更改name的信息(因为name限制长度为10)
如图:
在这里插入图片描述
把name的内容换成:<sCript>alert('xss')</sCript>这里记得把<script>里的大小写换一下,不然会被函数str_replace替换掉
在这里插入图片描述
弹框成功

High level

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值