zoukankan      html  css  js  c++  java
  • DVWA XSS部分

    DVWA XSS练习

    反射型(Reflected)

    Low

    输入框里随便输入,比如aaa点击submit

    访问:http://localhost/DVWA/vulnerabilities/xss_r/?name=aaa#

    查看源代码发现只有一处有回显:

    <pre>Hello aaa</pre>
    

    可控的变量是name

    直接插script标签进行尝试:

    payload:<script>alert(1)</script>

    成功弹窗

    代码分析:

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

    没有做任何的过滤。

    Medium

    插script标签进行尝试:

    查看源代码:
    <pre>Hello alert(1)</pre>

    应该是过滤了<script>一类的

    构造payload:<scr<script>ipt>alert(1)</script>

    成功弹窗

    代码分析

    
    <?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>标签置换成了空

    High

    尝试了 low , medium 等级的payload都是过滤掉了,试试img标签。

    payload:<img src=x onerror=alert(1)>

    成功弹窗

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

    通过正则表达式进行了过滤,无论script中间夹了什么都能置空。

    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函数实体化了。就基本没有可能xss了。

    htmlspecialchars:

    语法:

    htmlspecialchars(string,flags,character-set,double_encode)
    

    定义和用法
    htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。

    预定义的字符是:

    & (和号)成为 &
    " (双引号)成为 "
    ' (单引号)成为 '
    < (小于)成为 <
    > (大于)成为 >

    提示:如需把特殊的 HTML 实体转换回字符,请使用 htmlspecialchars_decode() 函数。

    存储型(Stored)

    Low

    随便输入一个数据,查看源代码:

    <div id="guestbook_comments">
        Name: admin<br />
        Message: test<br />
    </div>
    

    构造payload:

    <script>alert(1)</script>

    发现Name处有长度限制。不过Message部分也可以触发xss进行弹窗。

    看看能不能通过审查元素更改Name输入框的长度限制:

    查看源代码:

    <input name="txtName" type="text" size="30" maxlength="10">
    

    maxlength="10"删掉,提交后发现弹了两下窗口。

    测试完成以后可以点击那个Clear Guestbook来清除之前提交的记录,不然每次刷新都弹窗很烦。

    代码分析

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

    代码的大概意思就是收到name跟message之后直接存到数据库里。基本上没有什么过滤,message是用stripslashes函数去除了一下斜杠。

    Medium

    提交了 Low 等级的payload后返回页面的源代码:

    <div id="guestbook_comments">
        Name: aaa<br>
        Message: alert(1)<br>
    </div>
    

    也是<script>标签被过滤了。

    构造一下:<scr<script>ipt>alert(1)</script>

    还是被过滤了,代码可能是跟反射型漏洞的high一样叭,试试别的标签。

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

    em~ 也过滤了。

    看了一眼代码,发现是把message实体化了,只能通过Name来传payload了。

    也是利用代码审计把长度限制去掉,也可以利用抓包工具在改一下数据内容。

    payload:<scr<script>ipt>alert(1)</script>

    就可以弹窗了。

    代码分析

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

    代码的意思就是说,传入message跟name,然后两个变量都是把<script>置空,然后把message实体化之后才保存至数据库。

    High

    既然medium难度就把message实体化了,所以high应该也是实体化了,所以把name的长度限制去掉,传入一个img标签的payload试试:

    payload:<img src=x onerror=alert(1)>

    弹窗了。

    代码分析

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

    处理方法跟反射型的high难度有异曲同工之妙。也是利用了正则表达式。

    Impossiable

    impossiable难度是安全的。

    代码分析

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

    两个变量都实体化了。

    Dom型 (DOM)

    Dom的一开始做了只做会了Low等级的,就暂时放一边了。

    Low

    点击select时访问:http://localhost/DVWA/vulnerabilities/xss_d/?default=English

    查看源代码发现default之后的值就是<option>标签里的值,查看源代码:

    <option value="English">English</option>
    

    payload:
    <script>alert(1)</script>

    成功弹窗:

    代码里什么也没写。

    弹窗以后想要逃出value="English"这个地方触发xss。但是">传入这个之后没有什么反应。查看前端代码时发现一段js代码:

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

    这里lang就是我们传入的值。

    在浏览器的console里查看了一下lang的值,发现都是经过了url编码的。

    Medium

    尝试了一下Low等级的payload,直接返回到了

    http://localhost/DVWA/vulnerabilities/xss_d/?default=English

    这个地址。

    尝试别的标签:http://localhost/DVWA/vulnerabilities/xss_d/?default=<img src=x onerror=alert(1)>

    还是没有什么反应。

    尝试关闭了option标签也是逃不过去,看了一下html嵌套规则:https://www.cnblogs.com/xiyangbaixue/p/4090511.html

    发现得把select标签页一并关闭才可以,构造一下payload:

    </option></select><img src=x onerror=alert(1)>

    成功

    代码分析:

    
    <?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标签就会执行跳转。

    High

    首先尝试了一下medium难度的payload,执行了跳转操作。

    没什么思路,看了一下代码:

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

    网上搜了一下:https://www.cnblogs.com/huangming-zzz/p/9901770.html

    利用了#号,URL中#号之后的内容,不会被提交到服务器,可以直接与浏览器进行交互

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

    Impossiable

    安全,后端也没有代码。前端跟之前的不一样:

    document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
    

    改成了:

    document.write("<option value='" + lang + "'>" + (lang) + "</option>");
    

    去掉了url解码的部分

  • 相关阅读:
    第一个SWT程序
    稀疏数组
    算法与数据结构
    《Java核心技术》学习笔记 第1-3章
    算术运算符
    5.11 rw zip file
    5.10 gob序列化
    5.9 piping between writer and reader
    5.7 io.MultiWriter(buf, f)
    5.7 读写 二进制数据
  • 原文地址:https://www.cnblogs.com/F4lc0n/p/12897202.html
Copyright © 2011-2022 走看看