DVWA靶機-暴力破解(Brute Force)

DVWA靶機-暴力破解

1.DVWA靶機的4個安全等級

DVWA Security分爲四個等級,low,medium,high,impossible,不同的安全等級對應了不同的漏洞等級。
1.low-最低安全等級,無任何安全措施,通過簡單毫無安全性的編碼展示了安全漏洞。
2.medium-中等安全等級,有安全措施的保護,但是安全性並不強。
3.high-高等安全等級,有安全措施保護,是中等安全等級的加深,這個等級下的安全漏洞可能不允許相同程度的攻擊。
4.impossible-最高(不可能)安全等級,存在相當強的安全保護措施,這個級別應能防止所有的漏洞,主要用於比較不同等級下的源代碼。
在這裏插入圖片描述

2.暴力破解(Brute Force)

暴力破解也稱爲窮舉法,是指未知用戶名和密碼的情況下,通過某些破解軟件+破解詞典(用戶可能設置的用戶名及密碼文件),來爆破出正確的用戶名及密碼,此過程技術成分低,其耗費時間多,成功機率小
適用場景:適用於無驗證碼或者二次驗證登錄的WEB頁面
在這裏插入圖片描述

(1).DVWA-LOW等級下的暴力破解

首先我們在此處用的暴力破解工具爲Burp suite,此工具可以在截取WEB頁面POST提交的信息後,可以通過修改用戶名密碼方式來測試WEB頁面是否正確回顯,也就是修改之後的用戶名密碼是否正確

由於暴力破解及其耗費時間,此時爲了方便,我們在自定義詞典,在詞典中加入已知的用戶名,密碼,爲了更快速的查到結果。
username:admin
password:123

Low Brute Force Source
<?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 = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    if( $result && mysql_num_rows( $result ) == 1 ) {
        // Get users details
        $avatar = mysql_result( $result, 0, "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();
}

?> 
1.截取HTTP報文

在這裏插入圖片描述

2.轉入Intruder-positions

Intruder默認針對於所有的變量,我們先將其原策略清除(clear),重新添加(Add)單選項針對於password,
攻擊類型(Attack type)選爲sniper
在這裏插入圖片描述

3.轉入Intruder-Payloads

Payload Sets
Payload set:設置破解頁,當前只針對於密碼,爲1
Payload type 設置爲Simple list,單表模式
在這裏插入圖片描述
Payload Options[Simple list]
load:通過load可以載入常用用戶名及密碼詞典,文件形式
Add:添加單獨可能存在的密碼
常用的用戶名密碼詞典在網上都能下載,此處爲了方便,快速的達成效果,我們Add中添加已知的密碼
在這裏插入圖片描述

4.Start Attack

定義好詞典後,開始攻擊,我們可以發現當出現正確的密碼時回覆中,Length有不同的結果,此時正確的長度爲5317,這就是判斷密碼是否正確的方法,同時可以在Response Render中查看web頁面的回顯效果
在這裏插入圖片描述

(2).DVWA-Medium等級下的暴力破解

同low等級下的暴力破解類似,爲了方便,我們在自定義詞典,在詞典中加入已知的用戶名,密碼,爲了更快速的查到結果。
username:admin
password:123

由於low等級下,不存在安全策略,無安全行可言,但是Medium等級下存在安全策略,爲了方便快速,我們此時可以先查看源碼再進行破解。

mysql_real_escape_string():此函數轉義了SQL語句中使用的字符串的特殊字符
也就是過濾了一些特殊字符,包括(\x00、\n、\r 、\、 '、 "、 \x1a),也意味着用戶名和密碼中不能存在這些特殊字符

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

    // Check the database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    if( $result && mysql_num_rows( $result ) == 1 ) {
        // Get users details
        $avatar = mysql_result( $result, 0, "avatar" );

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        sleep( 2 );
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }

    mysql_close();
}

?> 
1.截取HTTP報文

在這裏插入圖片描述

2.轉入Intruder-positions

Intruder默認針對於所有的變量,我們先將其原策略清除(clear),重新添加(Add)單選項針對於username&password,
攻擊類型(Attack type)選爲Cluster bomb
在這裏插入圖片描述

3.轉入Intruder-Payloads

Payload Sets
Payload set:設置破解頁,當前於用戶名和密碼,爲2
Payload type 設置爲Simple list,單表模式
在這裏插入圖片描述
Payload Options[Simple list]
load:通過load可以載入常用用戶名及密碼詞典,文件形式
Add:添加單獨可能存在的用戶名及密碼
常用的用戶名密碼詞典在網上都能下載,此處爲了方便,快速的達成效果,我們Add中添加已知的用戶名及密碼
用戶名:
在這裏插入圖片描述
密碼:
在這裏插入圖片描述

4.Start Attack

定義好詞典後,開始攻擊,我們可以發現當出現正確的用戶名和密碼時回覆中,Length有不同的結果,此時正確的長度爲5326,這就是判斷密碼是否正確的方法,同時可以在Response Render中查看web頁面的回顯效果

此時我定義了6個用戶名,7個密碼,其共有42中結果,這個過程花費大概1min,可想而知,如果用成千上萬個用戶名和密碼來測試,那需要的時間就相當的長,此時暴力破解的缺點也就顯露出來。
在這裏插入圖片描述

(3).DVWA-high等級下的暴力破解

在high等級中,存在更加強的安全策略
1.token機制(基於token的身份驗證)
2.stripslashes()函數,過濾字符串中的反斜槓’’,也就是說用戶名中和密碼不能存在
3.mysql_real_escape_string(),同medium等級一樣,過濾了一些特殊字符,包括(\x00、\n、\r 、\、 '、 "、 \x1a),也意味着用戶名和密碼中不能存在這些特殊字符

由於token值,每次都是隨機的,客戶端和服務端都爲隨機值,無法使用burp suite進行暴力破解,但是可以通過python腳本,自動獲取token,後期會發布python相關腳本文件的暴力破解過程。

High Brute Force Source
<?php

if( isset( $_GET[ 'Login' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

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

    // Check database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    if( $result && mysql_num_rows( $result ) == 1 ) {
        // Get users details
        $avatar = mysql_result( $result, 0, "avatar" );

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        sleep( rand( 0, 3 ) );
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }

    mysql_close();
}

// Generate Anti-CSRF token
generateSessionToken();

?> 

(4).impossiable

Impossible Brute Force Source

impossible等級的安全策略相當強大,應能防止所有的漏洞,用於比較不同等級下的源代碼。
相比於high等級,impossible等級,加上了登錄失敗策略,定義了3個變量
total_failed_login:總的登錄失敗次數,當前定義爲3次。
lockout_time:賬戶鎖定時間,當前定義爲15s
account_locked:創建用戶的時候鎖定用戶
bindparam:爲用戶名和密碼綁定參數PDOStatement::bindParam
時間函數:
last_login、timeout、timenow等組成了相當大的防禦體系

<?php

if( isset( $_POST[ 'Login' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Sanitise username input
    $user = $_POST[ 'username' ];
    $user = stripslashes( $user );
    $user = mysql_real_escape_string( $user );

    // Sanitise password input
    $pass = $_POST[ 'password' ];
    $pass = stripslashes( $pass );
    $pass = mysql_real_escape_string( $pass );
    $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 = $row[ 'last_login' ];
        $last_login = strtotime( $last_login );
        $timeout    = strtotime( "{$last_login} +{$lockout_time} minutes" );
        $timenow    = strtotime( "now" );

        // Check to see if enough time has passed, if it hasn't locked the account
        if( $timenow > $timeout )
            $account_locked = true;
    }

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

?> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章