DVWA(medium) XSS部分

DVWA(medium) - XSS

中安全级别

XSS(DOM)

查看后台源码(View Source)


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

?>

分析

首先进行了一个判断。如果GET到的default的值不为空,就将接收到的值赋值给$default变量。再对$default变量的内容进行分析,如果这个变量的值包含<script,就跳转到默认的页面。

构造payload

?default=<a onclick=alert(2333)>2333</a>

XSS(Reflected)

查看源码(View Source)

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

?>

分析

  • X-XSS-Protection

HTTP X-XSS-Protection 响应头是Internet Explorer,Chrome和Safari的一个功能,当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。虽然这些保护在现代浏览器中基本上是不必要的,当网站实施一个强大的Content-Security-Policy来禁用内联的JavaScript ('unsafe-inline')时, 他们仍然可以为尚不支持 CSP 的旧版浏览器的用户提供保护。

0

禁止XSS过滤。

1

启用XSS过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。

1;mode=block

启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。

1; report=<reporting-URI> (Chromium only)

启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri指令的功能发送违规报告。

在这个页面里,禁用了XSS过滤。

  • 后端程序对GET接收到的内容进行了过滤,将<script>替换为空。再将过滤后的内容赋值给$name变量,在网页上进行输出。

构造payload

?name=<a href="javascript:alert(2333);">2333</a>

?name=<button onclick=alert(2333)>2333</button>

XSS(Stored)

查看源码(View Source)

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

?>

分析

  • trim()

trim() 函数移除字符串两侧的空白字符或其他预定义字符。

  • addslashes()

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

  • strip_tags()

strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。

  • htmlspecialchars()

htmlspecialchars()函数把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体。

可以看到,后端程序对message进行了大量的过滤。相比之下,对name的过滤较少。name应该是切入点。后端程序移除name两侧的空白字符,将name中可能含有的<script>替换为空,然后就没有其他操作了。

发现,后端程序对name的长度没有限制,可以采用类似上一题的方法构造payload。由于前端将name的长度设置为10,可以通过修改maxlength来进行下一步操作。

构造payload

name: <a onclick="alert(2333)">2333</a>
message: 2333

添加新评论

评论列表