注意,这里需要使用字典,点我 下载字典top100
这里的防护等级是逐级加高的,最明显的出现防护等级提升的是对于SQL语句防护的提升。
Low 源码分析 <?php if ( isset ( $_GET [ 'Login' ] ) ) { $user = $_GET [ 'username' ]; $pass = $_GET [ 'password' ]; $pass = md5 ( $pass ); $query = "SELECT * FROM `users` WHERE user = '$user ' AND password = '$pass ';" ; $result = mysql_query ( $query ) or die ( '<pre>' . mysql_error () . '</pre>' ); if ( $result && mysql_num_rows ( $result ) == 1 ) { $avatar = mysql_result ( $result , 0 , "avatar" ); echo "<p>Welcome to the password protected area {$user} </p>" ; echo "<img src=\"{$avatar} \" />" ; } else { echo "<pre><br />Username and/or password incorrect.</pre>" ; } mysql_close (); } ?>
破解 破解的思路:
1.暴力破解,直接调用字典进行破解
http: username=name&password=123456 能更迭的是俩个变量:username和password
Medium 源码 <?php if ( isset ( $_GET [ 'Login' ] ) ) { $user = $_GET [ 'username' ]; $pass = $_GET [ 'password' ]; $user = mysql_real_escape_string ( $user ); $pass = mysql_real_escape_string ( $pass ); $pass = md5 ( $pass ); $query = "SELECT * FROM `users` WHERE user = '$user ' AND password = '$pass ';" ; $result = mysql_query ( $query ) or die ( '<pre>' . mysql_error () . '</pre>' ); if ( $result && mysql_num_rows ( $result ) == 1 ) { $avatar = mysql_result ( $result , 0 , "avatar" ); echo "<p>Welcome to the password protected area {$user} </p>" ; echo "<img src=\"{$avatar} \" />" ; } else { sleep ( 2 ); echo "<pre><br />Username and/or password incorrect.</pre>" ; } mysql_close (); } ?>
解题 思路: 和上面相比,多了一个转义语句,这道题目相当与加了一个屏障 防止特殊语句的注入,单仍然无法防止暴力破解 解题思路和LOW相同,使用字典破解即可 具体步骤不赘述
height 源码 <?php if ( isset ( $_GET [ 'Login' ] ) ) { checkToken ( $_REQUEST [ 'user_token' ], $_SESSION [ 'session_token' ], 'index.php' ); $user = $_GET [ 'username' ]; $pass = $_GET [ 'password' ]; $user = stripslashes ( $user ); $pass = stripslashes ( $pass ); $user = mysql_real_escape_string ( $user ); $pass = mysql_real_escape_string ( $pass ); $pass = md5 ( $pass ); $query = "SELECT * FROM `users` WHERE user = '$user ' AND password = '$pass ';" ; $result = mysql_query ( $query ) or die ( '<pre>' . mysql_error () . '</pre>' ); if ( $result && mysql_num_rows ( $result ) == 1 ) { $avatar = mysql_result ( $result , 0 , "avatar" ); echo "<p>Welcome to the password protected area {$user} </p>" ; echo "<img src=\"{$avatar} \" />" ; } else { sleep ( rand ( 0 , 3 ) ); echo "<pre><br />Username and/or password incorrect.</pre>" ; } mysql_close (); } generateSessionToken ();?>
解题 针对Token的解决思路:实时捕获Token并且加入信息提交 Token本身是随机生成的,用于防止直接的暴力破解 =>使用BP解决Token的动态捕获和返还问题 新版BP貌似没有带单线程攻击,使用旧版BP即可
Impossible 源码 <?php if ( isset ( $_POST [ 'Login' ] ) ) { checkToken ( $_REQUEST [ 'user_token' ], $_SESSION [ 'session_token' ], 'index.php' ); $user = $_POST [ 'username' ]; $pass = $_POST [ 'password' ]; $user = stripslashes ( $user ); $pass = stripslashes ( $pass ); $user = mysql_real_escape_string ( $user ); $pass = mysql_real_escape_string ( $pass ); $pass = md5 ( $pass ); $total_failed_login = 3 ; $lockout_time = 15 ; $account_locked = false ; $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 (); if ( ( $data ->rowCount () == 1 ) && ( $row [ 'failed_login' ] >= $total_failed_login ) ) { $last_login = $row [ 'last_login' ]; $last_login = strtotime ( $last_login ); $timeout = strtotime ( "{$last_login} +{$lockout_time} minutes" ); $timenow = strtotime ( "now" ); if ( $timenow > $timeout ) $account_locked = true ; } $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 ( ( $data ->rowCount () == 1 ) && ( $account_locked == false ) ) { $avatar = $row [ 'avatar' ]; $failed_login = $row [ 'failed_login' ]; $last_login = $row [ 'last_login' ]; echo "<p>Welcome to the password protected area <em>{$user} </em></p>" ; echo "<img src=\"{$avatar} \" />" ; 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>" ; } $data = $db ->prepare ( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' ); $data ->bindParam ( ':user' , $user , PDO::PARAM_STR ); $data ->execute (); } else { sleep ( rand ( 2 , 4 ) ); 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>" ; $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 (); } $data = $db ->prepare ( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' ); $data ->bindParam ( ':user' , $user , PDO::PARAM_STR ); $data ->execute (); } generateSessionToken ();?>
解题 难度有点大,暂时不做。