XSS 跨站脚本攻击

XSS(DOM)

XSS 又称CSS(Cross Site Scripting)或跨站脚本攻击,攻击者在网页中插入由JavaScript编写的恶意代码,当用户浏览被嵌入恶意代码的网页时,恶意代码将会在用户的浏览器上执行。

XSS攻击可分为三种:分别为反射型(Reflected),存储型(Stored)和DOM型。

反射型xss:只是简单地把用户输入的数据反射给浏览器,简单来说,黑客往往需要引诱用户点击一个恶意链接,才能攻击成功。(经后端,不经数据库)

存储型XSS:将用户输入的数据存储在服务器端。用户访问了带有xss得页面代码后,产生安全问题。(经后端和数据库)

DOM XSS:通过修改页面的DOM节点形成的XSS。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。一般是浏览器前端代码进行处理。(不经过后端,是基于文档对象模型的一种漏洞,是通过url传入参数去控制触发的)

XSS危害

1.挂马
2.盗取用户Cookie。
3.DOS(拒绝服务)客户端浏览器。
4.钓鱼攻击,高级的钓鱼技巧。
5.删除目标文章、恶意篡改数据、嫁祸。
6.劫持用户Web行为,甚至进一步渗透内网。
7.爆发Web2.0蠕虫。
8.蠕虫式的DDoS攻击。
9.蠕虫式挂马攻击、刷广告、刷浏量、破坏网上数据
10.其它安全问题

LOW级别

php 复制代码
<?php

# No protections, anything goes

?>

发现并没有做任何过滤

点击了select按钮后,地址栏链接发生变化

构造xss语句,看到出现弹窗,代码执行成功,说明存在xss漏洞。

js 复制代码
<script>alert(/xss/)</script>

Medium级别

php 复制代码
<?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

尝试使用img标签

js 复制代码
<img src=1 οnerrοr=alert("xss")>

发现页面没有变化

查看页面代码,发现我们构造的语句已经被插入到了value当中,不能成功执行的原因是select标签中只允许内嵌option标签,而option标签是不能嵌套我们构造的img标签的,因此我们需要先将前面的select标签和option标签都闭合后才能使用img标签.

js 复制代码
</select></option><img src=1 onerror=alert('xss');>

High级别

php 复制代码
<?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 其中一个

只能找方法绕过服务器端的处理,直接在本地运行我们构造的语句,可以过"#"来注释掉后面的内容,因为URL栏中的"#"之后的内容不会被发送到服务器当中去,不会经过JS的过滤,只在客户端显示,可以直接与浏览器进行交互。

js 复制代码
#<script>alert('xss');</script>

XSS(Reflect)反射型

php 复制代码
 <?php

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

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Feedback for end user
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}

?>

LOW级别

发现没有什么防御,直接<script>alert('xss');</script>

Medium级别

php 复制代码
<?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>";
}
?> 

发现源码过滤了<script>,可以通过大写字母,双写,输入其他可执行弹窗的标签等方法来实现攻击.

如果用<script>alert('xss')</script>会直接显示alert('xss')

js 复制代码
//大写
<Script>alert('xss')</script>

//双写
<sc<script>ript>alert('xss')</script>

<img src=1 οnerrοr=alert('xss');>

High级别

php 复制代码
<?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>";
}

发现preg_replace 函数,是执行一个正则表达式的搜索和替换,直接将所有的<script>无论大小写都进行了过滤,但并未对其他标签进行限制,所以我们继续使用img等标签来进xss利用。

js 复制代码
<img src=1 onerror=alert('XSS')>

XSS(Stored)存储型

LOW级别

php 复制代码
<?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();
}

?> 

查看源代码,发现使用mysqli_real_escape_string函数来对string中的特殊符号进行转义处理,但并未对我们输入的Name和Message进行xss的过滤。

因此我们只需要直接输入JS代码进行攻击即可得到弹窗,攻击成功。

在name输入框中输入<script>alert('xss')</script>

Medium级别

php 复制代码
 <?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();
}

?>

查看源代码,发现将Message所有可能xss攻击的标签都进行了转义或过滤,但对Name仅仅限制了<script>的标签,因此我们依旧可以在Name中使用大写、双写、使用其他标签等方法来进行注入。

js 复制代码
<Script>alert(1)</script>

修改最大长度

Hign级别

php 复制代码
 <?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();
}
 
?>
  • 查看代码,发现在Medium的基础上对Name的输入进行了
php 复制代码
<img src=1 onerror=alert('2');>
相关推荐
前端郭德纲7 分钟前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
王解12 分钟前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
欲游山河十万里13 分钟前
(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数
前端·ecmascript·es6
明辉光焱13 分钟前
【ES6】ES6中,如何实现桥接模式?
前端·javascript·es6·桥接模式
PyAIGCMaster32 分钟前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
baozhengw34 分钟前
UniAPP快速入门教程(一)
前端·uni-app
nameofworld43 分钟前
前端面试笔试(二)
前端·javascript·面试·学习方法·数组去重
帅比九日1 小时前
【HarmonyOS NEXT】实战——登录页面
前端·学习·华为·harmonyos
摇光931 小时前
promise
前端·面试·promise
麻花20132 小时前
WPF学习之路,控件的只读、是否可以、是否可见属性控制
服务器·前端·学习