Brute Force 就是暴力破解的意思,尝试常用的用户名和必然然后使用工具一个一个的去尝试
通过解析源码我们可以发现代码没有任何的安全防范措施,可以用万能密码试一下
试了一下admin’# 直接过 =。=
if( isset( $_GET[ 'Login' ] ) ) {
// 获取用户名
$user = $_GET[ 'username' ];
// 获取密码,然后进行md5加密
$pass = $_GET[ 'password' ];
$pass = md5( $pass );
// 查看数据库是否有相关的信息
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
// 返回结果
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ''
. ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// 获取用户细节
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// 如果登陆成功
echo "Welcome to the password protected area {$user}
"; echo ""; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
Username and/or password incorrect.
可以发现这里的代码就是简单的获取用户名和密码去数据库中进行查询而已
用户进行用户名和密码验证时,网站需要查询数据库。查询数据库就是执行SQL语句。
用户登录时,后台执行的数据库查询操作(SQL语句)是:
Select user_id,user_type,email From users Where user_id=’用户名’ And password=’密码';
admin
和万能密码2’or’1
时,执行的SQL语句为:Select user_id,user_type,email From users Where user_id=’admin’ And password=’2’or’1’
。=
优先于and
,and
优先于or
,且适用传递性。因此,此SQL语句在后台解析时,分成两句:Select user_id,user_type,email From users Where user_id='admin'And password='2'
和'1'
,两句bool值进行逻辑or运算,恒为TRUE。admin'#
,密码都不用输,即可登录成功。
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)) ? "" : ""));
// 密码进行Md5加密
$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( ''
. ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// Get users details
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// Login successful
echo "Welcome to the password protected area {$user}
"; echo ""; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
Username and/or password incorrect.
源码解析(原文地址):
1、mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符;如果不进行转义,意味着任何用户无需输入合法的密码即可登陆。使用该函数来预防数据库攻击,基本防止了SQL注入;
2、同时,$pass做了MD5校验,杜绝了通过参数password进行sql注入的可能性;
3、但依然没有加入有效的防爆破机制,只是不能采用SQL注入的方式登录;
如果进行暴力破解的话,web工具当然首选Burp Intruder了。kali就有自带这个工具直接使用即可。具体的使用教程我也找了挺久的,一开始可能比较懵逼,我这里就放几个图,不细说了
现在进行用户名的添加,你可以选择直接从文件中导入也可以直接输入,我这里就随便输入几个
哎嘿,就可以发现一个小家伙的Length不对劲了,这个就是密码。之后就可以用这个密码尝试登陆了。
这里直接说结果吧,High以上的版本都无法进行暴力破解,下面我们来看看源码到底是什么样的。
if( isset( $_GET[ 'Login' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Sanitise username input
$user = $_GET[ 'username' ];
// 删除由 addslashes() 函数添加的反斜杠,可用于清理从数据库中或者从 HTML 表单中取回的数据。
$user = stripslashes( $user );
// 转义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' ];
// 删除由 addslashes() 函数添加的反斜杠,可用于清理从数据库中或者从 HTML 表单中取回的数据。
$pass = stripslashes( $pass );
// 转义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)) ? "" : ""));
// 进行md5加密
$pass = md5( $pass );
// Check database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ''
. ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// Get users details
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// Login successful
echo "Welcome to the password protected area {$user}
"; echo ""; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } // Generate Anti-CSRF token generateSessionToken(); ?>
Username and/or password incorrect.
我们抓包看一下包的内容:可以看到添加了随机生成的user_token, 这种东西一般和时间有关,当然了通过解析js文件我们也可以获取user_token的加密方式,然后通过python去进行暴力破解也不算不可以。
这个级别增加了登陆次数的验证,从根本上防御了暴力破解
1、限制尝试次数
2、验证码(验证码存在技术被破解的风险,仅用于增加每次尝试的成不)
3、PDO技术
PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。
PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。
PDO随PHP5.1发行,在PHP5.0的PECL扩展中也可以使用,无法运行于之前的PHP版本。