Brute Force,即暴力破解,是指黑客利用密码字典,使用穷举法猜解出用户口令,是现在最为广泛使用的攻击手法之一。
暴力破解前的准备:
- 字典:username.txt,passwd.txt;
- 公认的神器:Burp Suite;
Low:
源码分析一波:
<?php
//检查变量是否设置(先看有没有Login参数)
if( isset( $_GET[ 'Login' ] ) ) {
//获取密码,存入pass变量中
$user = $_GET[ 'username' ];
//获取密码
$pass = $_GET[ 'password' ];
//将密码使用md5加密
$pass = md5( $pass );
//构建SQL语句,查询结果保存在query变量中
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
//数据库查询,将查询结果保存在result变量中,查到了,保存用户具体信息;未查到,就在页面上输入错误结果,result为空
$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 ) {
//查询结果关联数据row,row已经变成键值对
$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);
}
?>
可以看到,服务器只是验证了参数Login是否被设置(isset函数在php中用来检测变量是否设置,该函数返回的是布尔类型的值,即true/false),没有任何的防爆破机制,且对参数username、password没有做任何过滤,存在明显的sql注入漏洞;
在没有做任何身份校验,那就先抓包重放几次看看,抓点击Login后的包;
仔细观察抓包结果,参数在URL传递,并且密码明文,没有验证码机制,点击了N次Go,依旧返回200,没有锁定,所以存在爆破;
爆破模块中攻击类型介绍
第一种:
Sniper标签 这个是我们最常用的,Sniper是狙击手的意思。这个模式会使用单一的payload【就是导入字典的payload】组。它会针对每个position中$$位置设置payload。这种攻击类型适合对常见漏洞中的请求参数单独地进行测试。攻击中的请求总数应该是position数量和payload数量的乘积。
第二种:
Battering ram – 这一模式是使用单一的payload组。它会重复payload并且一次把所有相同的payload放入指定的位置中。这种攻击适合那种需要在请求中把相同的输入放到多个位置的情况。请求的总数是payload组中payload的总数。简单说就是一个playload字典同时应用到多个position中
第三种:
Pitchfork – 这一模式是使用多个payload组。对于定义的位置可以使用不同的payload组。攻击会同步迭代所有的payload组,把payload放入每个定义的位置中。比如:position中A处有a字典,B处有b字典,则a【1】将会对应b【1】进行attack处理,这种攻击类型非常适合那种不同位置中需要插入不同但相关的输入的情况。请求的数量应该是最小的payload组中的payload数量
第四种:
Cluster bomb – 这种模式会使用多个payload组。每个定义的位置中有不同的payload组。攻击会迭代每个payload组,每种payload组合都会被测试一遍。比如:position中A处有a字典,B处有b字典,则两个字典将会循环搭配组合进行attack处理这种攻击适用于那种位置中需要不同且不相关或者未知的输入的攻击。攻击请求的总数是各payload组中payload数量的乘积。
爆破:
因为是两个变量用不同字典跑所以攻击类型选择Cluster bomb;
然后清除变量然后将username和password添加add$;
添加username.txt,passwd.txt的字典:
然后点击右上方的Start attack,
如上,开始暴力破解,可以看到admin,admin的响应包长度(length)“与众不同”,可推测admin,admin为正确账密,手工验证登陆成功。
当然在参数username、password没有做任何过滤的时候可以用方法二:
手工sql注入
Username:admin’ or ’1′=’1 或者 admin’ #
Password:(空)
Medium:
源码分析一下:
<?php
//是否存在Login变量(标签里面的name),检查是否存在Login按钮
if( isset( $_GET[ 'Login' ] ) ) {
// Sanitise username input
//获取用户名,存入user变量里
$user = $_GET[ 'username' ];
//user中x00,n,r,,’,”,x1a转义,防SQL注入
$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中x00,n,r,,’,”,x1a转义,防SQL注入
$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级别的代码,Medium级别的代码主要增加了mysql_real_escape_string函数,这个函数会对字符串中的特殊符号(x00,n,r,,’,",x1a)进行转义,基本上能够抵御sql注入攻击,那低等级时候用到的注入就失效了,所以我们直接用爆破方法即可,和low级的一样,需要注意的是中级的暴力破解相对来说较慢是因为有个sleep函数,在破解失败后会使程序停止运行两秒。
所以Medium级别使用Burpsuite进行爆破,与Low级别的爆破方法一样。
High:
源码分析一下:
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Sanitise username input
$user = $_GET[ 'username' ];
$user = stripslashes( $user );
$user = mysql_real_escape_string( $user );
// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = stripslashes( $pass );
$pass = mysql_real_escape_string( $pass );
$pass = md5( $pass );
$qry = "SELECT * FROM `users` WHERE user='$user' AND password='$pass';";
$result = mysql_query($qry) or die('<pre>' . mysql_error() . '</pre>' );
if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$i=0; // Bug fix.
$avatar = mysql_result( $result, $i, "avatar" );
// Login Successful
echo "<p>Welcome to the password protected area " . $user . "</p>";
echo '<img src="' . $avatar . '" />';
} else {
// Login failed
sleep(3);
echo "<pre><br>Username and/or password incorrect.</pre>";
}
mysql_close();
}
?>
High级别的代码加入了user_token,可以抵御CSRF攻击,同时也增加了爆破的难度,通过抓包,可以看到,登录验证时提交了四个参数:username、password、Login以及user_token。
将抓到的包发送到intrude,选择攻击模式为pitchfock,并且给user_token添加add$;
在options选项中,找到grep-extact;
找到Redirections模块设置允许重定向,选择always
设置密码本,点击payload,选择Recursive grep 并且把之前得到的token值粘贴到下方的方框中。
然后即可破解成功。