• dvwa-Brute Force


    brute force指暴力破解,列举出所有可能,并一一进行尝试

    爆破用户名和密码,利用了burpsuit的抓包和爆破

    burpsuite里intruder的四种攻击模式:https://howiezhao.github.io/2018/05/01/burpsuite-intruder-attack-type/

    具体分析:

    1、LOW

    查看源码如下:

    <?php
    
    if( isset( $_GET['Login'] ) ) {
    
        $user = $_GET['username'];
        
        $pass = $_GET['password'];
        $pass = md5($pass);
    
        $qry = "SELECT * FROM `users` WHERE user='$user' AND password='$pass';";
        $result = mysql_query( $qry ) or die( '<pre>' . mysql_error() . '</pre>' );
    
        if( $result && mysql_num_rows( $result ) == 1 ) {
            // Get users details
            $i=0; // Bug fix.
            $avatar = mysql_result( $result, $i, "avatar" );
    
            // Login Successful
            echo "<p>Welcome to the password protected area " . $user . "</p>";
            echo '<img src="' . $avatar . '" />';
        } else {
            //Login failed
            echo "<pre><br>Username and/or password incorrect.</pre>";
        }
    
        mysql_close();
    } 
    View Code

    直接用burpsuite的intruder即可

    2、medium

    Brute Force Source
    <?php
    
    if( isset( $_GET[ 'Login' ] ) ) {
    
        // Sanitise username input
        $user = $_GET[ 'username' ];
        $user = mysql_real_escape_string( $user );
    
        // Sanitise password input
        $pass = $_GET[ 'password' ];
        $pass = mysql_real_escape_string( $pass );
        $pass = md5( $pass );
    
        $qry = "SELECT * FROM `users` WHERE user='$user' AND password='$pass';";
        $result = mysql_query( $qry ) or die( '<pre>' . mysql_error() . '</pre>' );
    
        if( $result && mysql_num_rows($result) == 1 ) {
            // Get users details
            $i=0; // Bug fix.
            $avatar = mysql_result( $result, $i, "avatar" );
    
            // Login Successful
            echo "<p>Welcome to the password protected area " . $user . "</p>";
            echo '<img src="' . $avatar . '" />';
        } else {
            //Login failed
            echo "<pre><br>Username and/or password incorrect.</pre>";
        }
    
        mysql_close();
    }
    
    ?>
    View Code

    相比low级别,添加了mysqli_real_escape_string函数,对一些特殊字符,例如\,'等,可以防止sql注入和xss注入,关于mysqli_real_escape_string函数:https://www.yuque.com/docs/share/eaca5dfb-cf45-481c-8ff0-6dbbff465125

    3、high

     <?php
    
    if( isset( $_GET[ 'Login' ] ) ) {
    
        // Sanitise username input
        $user = $_GET[ 'username' ];
        $user = stripslashes( $user );
        $user = mysql_real_escape_string( $user );
    
        // Sanitise password input
        $pass = $_GET[ 'password' ];
        $pass = stripslashes( $pass );
        $pass = mysql_real_escape_string( $pass );
        $pass = md5( $pass );
    
        $qry = "SELECT * FROM `users` WHERE user='$user' AND password='$pass';";
        $result = mysql_query($qry) or die('<pre>' . mysql_error() . '</pre>' );
    
        if( $result && mysql_num_rows( $result ) == 1 ) {
            // Get users details
            $i=0; // Bug fix.
            $avatar = mysql_result( $result, $i, "avatar" );
    
            // Login Successful
            echo "<p>Welcome to the password protected area " . $user . "</p>";
            echo '<img src="' . $avatar . '" />';
        } else {
            // Login failed
            sleep(3);
            echo "<pre><br>Username and/or password incorrect.</pre>";
            }
    
        mysql_close();
    }
    
    ?> 
    View Code

    相比medium级别添加了stripslashes函数,删除字符串中的反斜杠,可以防止sql注入,而且若失败会等待3秒才可继续下一次,爆破处理时间会更长

    4、impossible

    其实我的没有,是一篇博客里的

    <?php
    if( isset( $_POST[ 'Login' ] ) && isset ($_POST['username']) && isset ($_POST['password']) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
        // Sanitise username input
        $user = $_POST[ 'username' ];
        $user = stripslashes( $user );
        $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        // Sanitise password input
        $pass = $_POST[ 'password' ];
        $pass = stripslashes( $pass );
        $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass = md5( $pass );
        // Default values
        $total_failed_login = 3;
        $lockout_time       = 15;
        $account_locked     = false;
     
        // Check the database (Check user information)
        $data = $db->prepare( 'SELECT failed_login, last_login FROM users WHERE user = (:user) LIMIT 1;' );
        $data->bindParam( ':user', $user, PDO::PARAM_STR );
        $data->execute();
        $row = $data->fetch();
        // Check to see if the user has been locked out.
        if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) )  {
            // User locked out.  Note, using this method would allow for user enumeration!
            //echo "<pre><br />This account has been locked due to too many incorrect logins.</pre>";
            // Calculate when the user would be allowed to login again
            $last_login = strtotime( $row[ 'last_login' ] );
            $timeout    = $last_login + ($lockout_time * 60);
            $timenow    = time();
            /*
            print "The last login was: " . date ("h:i:s", $last_login) . "<br />";
            print "The timenow is: " . date ("h:i:s", $timenow) . "<br />";
            print "The timeout is: " . date ("h:i:s", $timeout) . "<br />";
            */
            // Check to see if enough time has passed, if it hasn't locked the account
            if( $timenow < $timeout ) {
                $account_locked = true;
                // print "The account is locked<br />";
            }
        }
        // Check the database (if username matches the password)
        $data = $db->prepare( 'SELECT * FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
        $data->bindParam( ':user', $user, PDO::PARAM_STR);
        $data->bindParam( ':password', $pass, PDO::PARAM_STR );
        $data->execute();
        $row = $data->fetch();
        // If its a valid login...
        if( ( $data->rowCount() == 1 ) && ( $account_locked == false ) ) {
            // Get users details
            $avatar       = $row[ 'avatar' ];
            $failed_login = $row[ 'failed_login' ];
            $last_login   = $row[ 'last_login' ];
            // Login successful
            echo "<p>Welcome to the password protected area <em>{$user}</em></p>";
            echo "<img src="{$avatar}" />";
            // Had the account been locked out since last login?
            if( $failed_login >= $total_failed_login ) {
                echo "<p><em>Warning</em>: Someone might of been brute forcing your account.</p>";
                echo "<p>Number of login attempts: <em>{$failed_login}</em>.<br />Last login attempt was at: <em>${last_login}</em>.</p>";
            }
            // Reset bad login count
            $data = $db->prepare( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' );
            $data->bindParam( ':user', $user, PDO::PARAM_STR );
            $data->execute();
        } else {
            // Login failed
            sleep( rand( 2, 4 ) );
            // Give the user some feedback
            echo "<pre><br />Username and/or password incorrect.<br /><br/>Alternative, the account has been locked because of too many failed logins.<br />If this is the case, <em>please try again in {$lockout_time} minutes</em>.</pre>";
            // Update bad login count
            $data = $db->prepare( 'UPDATE users SET failed_login = (failed_login + 1) WHERE user = (:user) LIMIT 1;' );
            $data->bindParam( ':user', $user, PDO::PARAM_STR );
            $data->execute();
        }
        // Set the last login time
        $data = $db->prepare( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' );
        $data->bindParam( ':user', $user, PDO::PARAM_STR );
        $data->execute();
    }
    // Generate Anti-CSRF token
    generateSessionToken();
    ?> 
    View Code

    1、generateSessionToken();

    每次服务器返回的登陆页面都会包含一个随机生成的session,当服务器收到请求,会优先检测token,所以此处不应该使用burpsuite(没有对session进行相应的改变),可使用python写个脚本进行爆破

    该函数最主要的作用是Anti-CSRF token来抵御CSRF的攻击

    2、对登录次数进行了限制

    3、查询采用PDO(PHP Data Object)防御sql注入

    参考链接:

    https://blog.csdn.net/qq_36119192/article/details/82938424

  • 相关阅读:
    斜率优化dp学习
    拓扑排序
    P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)
    网络流24题!!!!
    费用流板子
    网络流dinic板子
    小花梨的数组
    C. 小花梨判连通
    splay树
    hdu4467 graph
  • 原文地址:https://www.cnblogs.com/dx-yll/p/11963479.html
Copyright © 2020-2023  润新知