暴力破解:
暴力破解的原理就是是用攻击者自己的用户名和密码字典,一个一个去枚举,尝试是否能够登录。因为理论上来说,只要字典足够庞大,不考虑时间来说,枚举总能够成功的。
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); } ?>
-
重点就在这两句代码:
$query = "SELECT * FROM users WHERE user = '$user' AND password = '$pass';"
if( $result && mysqli_num_rows( $result ) == 1 )
什么意思呢,就是说这个登录系统,只要将账号和密码输入,在数据库中找到的结果不为空,则登录成功。
-
-
欸,惊奇的发现好像可以用SQL注入
- 我们将账号设置为
admin' or '1'='1
,那么第一句代码带入就变成了 $query = "SELECT * FROM users WHERE user = 'admin' or '1'='1' AND password = '$pass';"
- 这样,我们根本不需要输入密码,因为or的存在,只要数据库搜索到user为admin的账号,返回值就不为空,那么登录就成功了。
- 其实or后面的部分 我们改为'1'='2,也是不影响登录的。
- 我们将账号设置为
Midium难度
- 查看源码,发现与low级别相比,只在处理我们输入的值时多了一个
mysqli_real_escape_string
函数处理。经过百度得知函数会将我们输入的值进行转义处理,那么我们low级别用sql注入的单引号就失效了,本来嘛这一章就是暴力破解模块,不多说开始破解。
-
打开浏览器代理。
-
打开Burp Suite。
-
随意输入密码,拦截后,送入Intruder准备爆破。
- 在Payloads里加载我们准备的弱口令文件,Positions选择密码,
Start attack
-
最后选择长度排序,正确的密码与其他的不一样,可以看出来密码就是
password
。 -
当然low难度我们用同样方法也是行得通的。
High难度
- 切换难度,二话不说直接暴力破解,结果发现和之前相比多了一个条件,
user_token
。
-
而且用弱口令爆破,显示全部失败,打开源码一探究竟。
-
看来失败原因和新加的token有关,百度查询token有关信息:
-
-
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
-
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌。
-
-
-
就是说,每当我们打开网页时,这个token就发送给了我们,当我们登录时,再用token去匹配,如果用之前的方法爆破的话,第一个爆破的数据失败了,第二个尝试时,系统的token已经改变了,然而我们还一直是第一个token的数据,导致后面全部枚举的失败。
法一 python脚本破解
-
因为还不会python,也还没下编辑器,就暂时跳过了。。
法二
-
burp suite,不过要麻烦一些。
-
随便输入密码,拦截后送往Intruder。
-
设置两个参数 password和user_token为变量,攻击模式改为Pitch fork.
草叉模式(Pitchfork )——它可以使用多组Payload集合,在每一个不同的Payload标志位置上(最多20个),遍历所有的Payload。举例来说,如果有两个Payload标志位置,第一个Payload值为A和B,第二个Payload值为C和D,则发起攻击时,将共发起两次攻击,第一次使用的Payload分别为A和C,第二次使用的Payload分别为B和D。
-
在Options中勾选 Extract the following items from responses; 点击
Add
,选中图中value并复制作为第一次token的初始值,确定。 -
回到Payloads,设置如图,payload1设置好我们准备的弱口令密码,payload2的初始值为之前复制的token,开始爆破。
-
成功找到密码。
-
一点疑惑
在爆破的时候发现,每次尝试的token值是上一次攻击获取的value,在上面倒数第二张图也可以看出。这就很奇怪为什么上一次攻击会得到下一次攻击的token值,token不应该是每次重新一次的攻击才刷新的吗?