针对DVWA里的暴力破解漏洞进行实验测试。主要内容包括BurpSuite的一些Intruder模块的基本使用和简单的python脚本编写。
简介
搞Web安全和渗透的,估计都玩过Dvwa这个靶机。所以关于Dvwa就不说了。直接进入主题吧
Brute Force,即暴力(破解),是指黑客利用密码字典,使用穷举法猜解出用户口令,是现在最为广泛使用的攻击手法之一,如2014年轰动全国的12306“撞库”事件,实质就是暴力破解攻击
话不多说,下面就针对Dvwa中暴力破解模块的不同级别进行分析测试吧。
Low级别
先来看源码
1 |
|
可以看到,对于登录的处理,服务器只是验证参数Login是否被设置,并没有任何的防爆破机制。因此可以通过BurpSuite进行爆破。if( isset( $_GET[ 'Login' ] ) )
此外对参数username、password等也没做任何过滤处理。因此此处还存在SQL注入漏洞,可以使用万能密码绕过,在用户名处输入admin'#
或者admin' or '1'='1
即可登录。
使用Burp进行爆破
- 打开Burp,记得设置浏览器代理。
- 进行抓包
浏览器设置好代理后,点击Login按钮,可以看到Burp成功抓包 - 抓到包后,按ctrl+l键,或者右键选择send to Intruder
- 因为是要对password参数进行爆破,所以只在password参数内容两边加$
- 设置好要爆破的参数后,选择Payloads模块设置字典。
可以使用Burp自带的简单字典,或者自己去网上下载构造。
因为此处Burp自带的字典里没有password(正确密码),故我们手动加入进去 - 设置攻击字典后,设置爆破线程
暴力破解是一个穷举的过程,速度很慢,故可以通过多线程加快速度。
但Burp社区版不提供增加线程功能,我用的是Burp pro破解版
将线程设为50个,然后点击start attack开始爆破 - 上一步点击开始爆破后,会切换到一个爆破任务详情新窗口
在分析爆破结果前,先讲一下原理(感觉太啰嗦了,麻烦且累以后还是不写这么详细好了)
我们分别通过万能密码和错误的密码成功登陆和失败登陆,如下两图
可以看到,返回的信息是不同的,所以响应包的长度Length也不一样 - 因此,在爆破任务详情窗口可以通过Length进行筛选
选出Length “与众不同”的payload即为密码
Medium级别
贴上源码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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);
}
可以看到,相比low级别的代码,这里主要增加了mysql_real_escape_string函数,这个函数会对字符串中的特殊符号进行转义,基本上能抵御SQL注入攻击。但对登录并没做什么防护,因此跟Low级别一样,使用Burp进行爆破即可。
High级别
贴上源码
1 |
|
###分析
High级别的代码加入了随机token,可以抵御CSRF攻击,但同时增加了爆破的难度。虽然不能用Burp爆破,但可以用python jio脚本呀
先抓一下包分析一下请求
可以看到,每次服务器返回的登录页面都会生成一个随机的user_token,用户每次登陆时都要将user_token一起提交,服务器每次收到请求后,也都会先做token的检查,再进行sql查询
脚本编写
思路
每次用python登录之前,先用python访问登录页面通过BeautifulSoup将user_token抓取出来。抓出来之后拼接url进行登录。我写了两个脚本,原理都差不多,不过是第二个用了requests库中的Session方法。
实现
好了,不多bb,开始写吧
先贴代码
1 | #Version:python3 |
1 | #Version:python3 |
编写中注意的点
先用浏览器F12一下,找出user_token所在标签
理清结构后使用BeautifulSoup进行提取(可以用一些爬虫插件、或者直接用python解释器测试)
得到BeautifulSoup提取语句:user_token = soup.form.find_all(name='input')[-1]['value']
设置header要注意,不然脚本无效
因为这个实验测试是之前做的,写文章的时候复现时发现,header不对的话脚本无效
说一下设置header的方法吧。
用Burp抓一下包,然后照着结果设置header。此处应有个笑哭的emoji
效果
Impossible级别
这个不怎么好写,就不写了
总结
想起之前看别人博客学习的时候,别人写的太简洁了而自己知识面不够广,导致自己学习的时候一脸懵。那种自闭的感觉很容易消磨学习的兴趣。所以自己刚开始写Blog,就总想着写得详细。但写得详细的话,太费时间了。所以之后看情况写吧,一些太啰嗦的东西就懒得贴上来了。