DVWA实战测试之XSS

0x01 XSS(Reflected)

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值是否为空,然后再将name打印出来,参数没有做任何的过滤,存在明显的XSS漏洞。

测试过程

输入<script>alert('0xdawn')</script>成功弹框!

可以弹窗的函数:alert()、confirm()、prompt()

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

?> 

$name = str_replace( '<script>', '', $_GET[ 'name' ] );这句代码将<script>替换成了空字符,从而进行简单的过滤。

测试过程
  • 双写绕过:<scr<script>ipt>alert('0xdawn')</script>
  • 大写绕过:<SCRIPT>alert('0xdawn')</SCRIPT>

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

?> 
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );	
//这段正则表达式直接将*s*c*r*i*p*t给过滤了,并且不区分大小写,使得双写绕过和大小写混淆绕过不可行,但同样是使用黑名单策略,仍存在安全隐患。
测试过程

尝试其他标签:

  • img:<img src=1 onerror=alert('0xdawn')>当图片显示错误时,执行alert(‘0xdawn’)
  • 超链接:<a href='#' onclick=alert('0xdawn')>0xdawn</a>

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

?> 

Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、"、’、<、>转换为 HTML 实体,防止浏览器将其作为HTML元素。 当输入<script>alert('hack')</script>时,因为 htmlspecialchars 函数会将 < 和 > 转换成html实体,并且${name}取的是$name的值,然后包围在<pre></pre>标签中被打印出来,所以我们插入的语句并不会被执行。

0x02 XSS(Stored)

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

?> 

low级别的代码对我们输入的message和name并没有进行XSS过滤,而且数据存储在数据库中,存在比较明显的存储型XSS漏洞。

测试过程

name中填入0xdawn,message中填入<script>alert('0xdawn')</script>代码立即执行

在这里插入图片描述

查看元素,发现js代码已经被写入进去。在这里插入图片描述

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

?> 

代码中name值的处理增加了一个str_replace() 函数,用来将字符串中含有<script>的字符串替换为空字符,从而有过滤作用;message值的处理中,在其第二次调用trim()函数时还内嵌了两个函数,先是使用addslashes() 函数、返回在预定义字符之前添加反斜杠的字符串,然后调用strip_tags()函数来剥去字符串中的HTML、XML 以及 PHP 的标签,在最后再调用htmlspecialchars() 函数、把预定义的字符转换为 HTML 实体,对输入的内容先进行HTML的编码然后再存储进服务器中,从而使message的SQL和XSS漏洞几乎不存在。

测试过程
  • 从name入手,查看元素,修改name值的最大长度为100。

  • 大小写混淆绕过,在name中填入<SCRIPT>alert('0xdawn')</SCRIPT>,成功写入。

在这里插入图片描述

  • 双写绕过,在name中填入<scr<script>ipt>alert('0xdawn')</script>,成功写入。

在这里插入图片描述

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

?>

在medium级别上,name参数使用了正则表达式进行过滤,仍然可以突破。

测试过程
  • 查看元素,修改name值最大限制为100.

  • name中填入<img src=1 onerror=alert('0xdawn')>,成功写入
    在这里插入图片描述

  • 超链接:name中填入<a href='#' onclick=alert('0xdawn')>0xdawn</a>,成功写入
    在这里插入图片描述

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

?> 

Impossible在high级别的基础上对name参数也进行了更严格的过滤,导致name参数也无法进行XSS攻击。而且使用了Anti-CSRF token防止CSRF攻击,彻底防御XSS漏洞和CSRF漏洞。

0x03 XSS(DOM)

Low

源码分析
<?php

# No protections, anything goes

?> 

代码没有任何的保护措施,对default参数没有任何过滤。

测试过程

直接构造xss代码,访问连接:

192.168.8.151/dvwa/vulnerabilities/xss_d/?default=English<script>alert('0xdawn')</script>		//脚本成功执行

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参数是否为空,如果不为空则接受参数的值,同时使用了stripos将<script>进行过滤,并且不区分大小写。

测试过程
  • 尝试用img标签进行写入:

    http://192.168.8.151/dvwa/vulnerabilities/xss_d/?default=English<img src=1 onerror=alert('0xdawn')>
    
  • 并没有弹窗,查看元素发现语句被写入了value值中,却没有插入到option标签里。在这里插入图片描述

  • 尝试闭合option标签注入:

    http://192.168.8.151/dvwa/vulnerabilities/xss_d/?default=English</option><img src=1 onerror=alert('0xdawn')>
    
  • 还是没有弹窗,img依然在value值中。在这里插入图片描述

  • 继续闭合select标签,使img成为独立标签:

    192.168.8.151/dvwa/vulnerabilities/xss_d/?default=English</option></select><img src=1 onerror=alert('0xdawn')>
    
  • 成功弹窗!写入alert事件。在这里插入图片描述

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

?> 

high级别的代码先判断defalut值是否为空,如果不为空的话,再用switch语句进行匹配,如果匹配成功,则插入case字段的相应值,如果不匹配,则插入的是默认的值。

测试过程

’#‘字符之后的数据不会发送的服务器端,从而绕过服务器端过滤。

构造http://192.168.8.151/dvwa/vulnerabilities/xss_d/?default=English#<script>alert('0xdawn')</script>即可成功弹窗。

Impossible

源码分析
<?php

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

?> 

防御机制写在了客户端里,无XSS漏洞。

发布了22 篇原创文章 · 获赞 24 · 访问量 1980

猜你喜欢

转载自blog.csdn.net/weixin_43872099/article/details/98876568