wmm的学习日记(XSS跨站脚本漏洞)

本文详细介绍了XSS跨站脚本攻击的三种类型:反射型、存储型和DOM型,并通过DVWA平台展示了不同安全级别下的攻击实例,包括注入点分析、绕过策略和防护措施。同时,强调了XSS攻击的危害,如钓鱼、窃取cookie等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  由于政策放开我们学校已经采取线上上课的教学方式,虽然现在已经在家了,但是学习还是要继续,休息了几天之后这两天学习了XSS跨站脚本攻击。

目录

XSS简介

反射型XSS

简介

常见注入点

DVWA(XSS Reflected)

Low

Medium

High

存储型XSS

简介

常见注入点

DVWA(XSS Stored)

Low

Medium

High

DOM型XSS

简介

DVWA(XSS DOM)

Low

Medium

High


 

XSS简介

跨站脚本攻击是指通过在Web页面里插入恶意javascript代码,当用户浏览该页之时,恶意代码会被执行,从而达到攻击的目的。

反射型XSS

简介

非持久型XSS,这种攻击方式往往具有一次性,主要存在于攻击者将恶意脚本附加到url参数中,发送给用户,服务端未经过严格的过滤处理,而输出在用户的浏览器中,当用户点击链接时会会发送请求触发恶意代码执行,跨站代码经过服务端反射回来,这类跨站的代码通常不存储服务端所以没有持久性

常见注入点

搜索框,登录入口等。主打钓鱼和窃取客户端cookie

DVWA(XSS Reflected)

Low

 尝试注入

<script>alert('wmm')</script>

 出现了弹框表示注入成功查看网页源码我们可以发现我们输入内容出现在了网页源码内,并且script标签被解析了,说明存在xss漏洞

 我们可以借此获得cookie

<script>alert(document.cookie)</script>

Medium

 尝试用<script>标签注入发现没有弹窗出现,观察页面回显猜测<script>标签英爱是被过滤了,尝试采用大小写绕过试试,发现成功绕过

<Script>alert('wmm')</Script>

查看php源码发现是将<script>替换成空,因此我们还可以采用双写绕过

<?php

header ("X-XSS-Protection: 0");

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Get input
    $name = str_replace( '<script>', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}

?> 
<s<script>cript>alert('wmm')</script>

High

根据上一题是将script标签替换成空进行简单的过滤,猜测这题是将script用正则表达式过滤,所以我们只能采用别的标签进行注入比如<img>标签(img标签中,当src的值不存在时会执行onerror的内容)

<img src=1 onerror=alert('wmm') />

查看php源码发现就是采用正则表达式过滤了script标签

<?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
    echo "<pre>Hello ${name}</pre>";
}

?> 

存储型XSS

简介

持久型XSS漏洞主要存在于攻击者将恶意代码脚本存储到服务器中,当用户访问包含恶意数据相关的页面时,服务端未经过严格过滤处理而输出在用户浏览器中,导致浏览器执行代码数据。

常见注入点

留言板,评论等

DVWA(XSS Stored)

Low

如图所示,将script标签放在Massage中被网页解析了,出现弹窗,而且内容被存储在服务器中

Medium

在Massage中尝试了用img标签发现都没有用,应该不能在Massage中注入了,或者很难在Massage中注入,不如改变方向,尝试从Name中注入

 在Name中注入时发现有长度限制,先将其maxLength改为1000,再尝试注入

 第一次用script标签注入发现被过滤了,尝试用大小写绕过成功

 源码:

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

?> 

审计源码发现massage使用htmlspecialchars()函数,将massage中含有的预定义字符'<'和'>'转化为实体,即转化为字符,导致页面不解析标签

High

结合之前的题目,猜测实在Name中将script用正则表达过滤了,于是先修改Name的长度,再用img标签注入,成功

 源码:

<?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用正则表达式过滤了 

DOM型XSS

简介

基于文档对象模型Document Objeet Model,DOM)的一种漏洞。DOM是访问和操作HTML文档的 标准方法,可以通过利用js来访问操作HTML,由于其是基于js,不需要与服务器进行交互。简单是说就是通过改变DOM树来修改HTML文档。

DVWA(XSS DOM)

Low

选择一个选项后发现页面出现一个注入点,将<script>alert('wmm')</script>作为参数传入

Medium

尝试了大小写绕过,和双写都不行。于是尝试了img标签也不行,检查发现img标签没有被写入

发现传入的参数要包裹在 option标签下,而option在select标签下,说明要先闭合option标签和select标签

?default=</option></select><img src=1 onerror=alert('wmm') />

 ​​​

 检查源码发现成功插入img标签

 

 源码:

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

?> 

如源码所示,过滤了<script

stripos()函数:查找字符串在另一字符串中第一次出现的位置(不区分大小写)

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;
    }
}

?> 

直接上源码,源码显示如果输入的default参数不在 French","English","German","Spanish"中时直接返回default=English

我们可以用#(%23)来截断,#这个字符后面的数据不会发送到服务器端,就是说php中default的值是English,相当于绕过了后端的过滤,而且在HTML中#不表示注释

?default=English#<script>alert('wmm')</script>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值