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

    Insecure CAPTCHA

    Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称。但个人觉得,这一模块的内容叫做不安全的验证流程更妥当些,因为这块主要是验证流程出现了逻辑漏洞,谷歌的验证码表示不背这个锅。

    reCAPTCHA验证流程

    这一模块的验证码使用的是Google提供reCAPTCHA服务,下图是验证的具体流程。

    服务器通过调用recaptcha_check_answer函数检查用户输入的正确性。

    recaptcha_check_answer($privkey,$remoteip, $challenge,$response)

    参数$privkey是服务器申请的private key ,$remoteip是用户的ip,$challenge 是recaptcha_challenge_field 字段的值,来自前端页面 ,$response是 recaptcha_response_field 字段的值。函数返回ReCaptchaResponse class的实例,ReCaptchaResponse 类有2个属性 :

    • $is_valid是布尔型的,表示校验是否有效,
    • $error是返回的错误代码。

    ps:有人也许会问,那这个模块的实验是不是需要访问谷歌呢?答案是不用,因为我们可以绕过验证码。

    Low Level

    查看源码

    <?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
                $html .= "
                    <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
            $html .= "<pre>Password Changed.</pre>";
        }
        else {
            // Issue with the passwords matching
            $html .= "<pre>Passwords did not match.</pre>";
            $hide_form = false;
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    ?>

    可以看到,服务器将改密操作分成了两步,第一步检查用户输入的验证码,验证通过后,服务器返回表单,第二步客户端提交post请求,服务器完成更改密码的操作。但是,这其中存在明显的逻辑漏洞,服务器仅仅通过检查Changestep 参数来判断用户是否已经输入了正确的验证码。

    漏洞利用

    1.通过构造参数绕过验证过程的第一步

    首先输入密码,点击Change按钮,抓包:

    (ps:因为没有翻墙,所以没能成功显示验证码,发送的请求包中也就没有recaptcha_challenge_field、recaptcha_response_field两个参数)

    更改step参数绕过验证码

    修改密码成功

    2.由于没有任何的防CSRF机制,我们可以轻易地构造攻击页面

    当受害者访问这个页面时,攻击脚本会伪造改密请求发送给服务器。

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

     

     参考:https://www.freebuf.com/articles/web/119692.html 

  • 相关阅读:
    我的物联网项目(七)前期线上事故
    我的物联网项目(六)推广策略
    我的物联网项目(五)下单渠道
    我的物联网项目(四)订单系统
    我的物联网项目(三)平台架构
    我的物联网项目(二)初建团队
    我的物联网项目(一)开端
    從需求分析開始
    提升GDI画图的效率
    C#写COM组件,JS调用控件
  • 原文地址:https://www.cnblogs.com/zhengna/p/12764745.html
Copyright © 2011-2022 走看看