brute force指暴力破解,列举出所有可能,并一一进行尝试
爆破用户名和密码,利用了burpsuit的抓包和爆破
burpsuite里intruder的四种攻击模式:https://howiezhao.github.io/2018/05/01/burpsuite-intruder-attack-type/
具体分析:
1、LOW
查看源码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php if( isset( $_GET['Login'] ) ) { $user = $_GET['username']; $pass = $_GET['password']; $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 echo "<pre><br>Username and/or password incorrect.</pre>"; } mysql_close(); }
直接用burpsuite的intruder即可
2、medium
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Brute Force Source <?php if( isset( $_GET[ 'Login' ] ) ) { // Sanitise username input $user = $_GET[ 'username' ]; $user = mysql_real_escape_string( $user ); // Sanitise password input $pass = $_GET[ 'password' ]; $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 echo "<pre><br>Username and/or password incorrect.</pre>"; } mysql_close(); } ?>
相比low级别,添加了mysqli_real_escape_string函数,对一些特殊字符,例如\,'等,可以防止sql注入和xss注入,关于mysqli_real_escape_string函数:https://www.yuque.com/docs/share/eaca5dfb-cf45-481c-8ff0-6dbbff465125
3、high
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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(); } ?>
相比medium级别添加了stripslashes
函数,删除字符串中的反斜杠,可以防止sql注入,而且若失败会等待3秒才可继续下一次,爆破处理时间会更长
4、impossible
其实我的没有,是一篇博客里的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php if( isset( $_POST[ 'Login' ] ) && isset ($_POST['username']) && isset ($_POST['password']) ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Sanitise username input $user = $_POST[ '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 = $_POST[ '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 ); // Default values $total_failed_login = 3; $lockout_time = 15; $account_locked = false; // Check the database (Check user information) $data = $db->prepare( 'SELECT failed_login, last_login FROM users WHERE user = (:user) LIMIT 1;' ); $data->bindParam( ':user', $user, PDO::PARAM_STR ); $data->execute(); $row = $data->fetch(); // Check to see if the user has been locked out. if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) ) { // User locked out. Note, using this method would allow for user enumeration! //echo "<pre><br />This account has been locked due to too many incorrect logins.</pre>"; // Calculate when the user would be allowed to login again $last_login = strtotime( $row[ 'last_login' ] ); $timeout = $last_login + ($lockout_time * 60); $timenow = time(); /* print "The last login was: " . date ("h:i:s", $last_login) . "<br />"; print "The timenow is: " . date ("h:i:s", $timenow) . "<br />"; print "The timeout is: " . date ("h:i:s", $timeout) . "<br />"; */ // Check to see if enough time has passed, if it hasn't locked the account if( $timenow < $timeout ) { $account_locked = true; // print "The account is locked<br />"; } } // Check the database (if username matches the password) $data = $db->prepare( 'SELECT * FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' ); $data->bindParam( ':user', $user, PDO::PARAM_STR); $data->bindParam( ':password', $pass, PDO::PARAM_STR ); $data->execute(); $row = $data->fetch(); // If its a valid login... if( ( $data->rowCount() == 1 ) && ( $account_locked == false ) ) { // Get users details $avatar = $row[ 'avatar' ]; $failed_login = $row[ 'failed_login' ]; $last_login = $row[ 'last_login' ]; // Login successful echo "<p>Welcome to the password protected area <em>{$user}</em></p>"; echo "<img src="{$avatar}" />"; // Had the account been locked out since last login? if( $failed_login >= $total_failed_login ) { echo "<p><em>Warning</em>: Someone might of been brute forcing your account.</p>"; echo "<p>Number of login attempts: <em>{$failed_login}</em>.<br />Last login attempt was at: <em>${last_login}</em>.</p>"; } // Reset bad login count $data = $db->prepare( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' ); $data->bindParam( ':user', $user, PDO::PARAM_STR ); $data->execute(); } else { // Login failed sleep( rand( 2, 4 ) ); // Give the user some feedback echo "<pre><br />Username and/or password incorrect.<br /><br/>Alternative, the account has been locked because of too many failed logins.<br />If this is the case, <em>please try again in {$lockout_time} minutes</em>.</pre>"; // Update bad login count $data = $db->prepare( 'UPDATE users SET failed_login = (failed_login + 1) WHERE user = (:user) LIMIT 1;' ); $data->bindParam( ':user', $user, PDO::PARAM_STR ); $data->execute(); } // Set the last login time $data = $db->prepare( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' ); $data->bindParam( ':user', $user, PDO::PARAM_STR ); $data->execute(); } // Generate Anti-CSRF token generateSessionToken(); ?>
1、generateSessionToken();
每次服务器返回的登陆页面都会包含一个随机生成的session,当服务器收到请求,会优先检测token,所以此处不应该使用burpsuite(没有对session进行相应的改变),可使用python写个脚本进行爆破
该函数最主要的作用是Anti-CSRF token来抵御CSRF的攻击
2、对登录次数进行了限制
3、查询采用PDO(PHP Data Object)防御sql注入
参考链接:
https://blog.csdn.net/qq_36119192/article/details/82938424