关于DVWA的学习-Brute Force
low
随便试了一下,账号密码和登录dvwa的一样,登陆成功会显示avatar
 
 看了一下PHP源码
 
 没有对SQL注入进行防范,本来直接输入 ’ or 1=1#,但应该是由于返回的行数超过1,也不能显示avatar,加一个LIMIT 1即可。
medium
和low一样,试了一下就登进去了,确实没太懂想考察啥。
 打开源码看了一下:
 
 首先应该是对sql注入进行了一些防范,给引号啥的加了转义字符。
 比较重要的是,fail的情况多了个sleep函数,应该是防止爆破的一种手段(不过感觉也没啥用。。)
high
多了一个user_token,每轮爆破之前要先得到这个令牌,就在网页的html代码里:
 
用python的requests先获得token,在加入username和password进行爆破即可,不赘述了,没啥意思-.-
impossible
直接代码审计:
<?php
if( isset( $_POST[ 'Login' ] ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
	// Sanitise username input
	$user = $_POST[ 'username' ];
	$user = stripslashes( $user );
	$user = mysql_real_escape_string( $user );
	// Sanitise password input
	$pass = $_POST[ 'password' ];
	$pass = stripslashes( $pass );
	$pass = mysql_real_escape_string( $pass );
	$pass = md5( $pass );
	// Default values
	$total_failed_login = 3;  //登录尝试次数超过这个值会提示和:存在attacker
	$lockout_time       = 15;   //lock out时间为15min
	$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!
		//$html .= "<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 = $row[ 'last_login' ];
		$last_login = strtotime( $last_login );
		$timeout    = strtotime( "{$last_login} +{$lockout_time} minutes" );
		$timenow    = strtotime( "now" );
		// Check to see if enough time has passed, if it hasn't locked the account
		if( $timenow > $timeout )		//看当前时间是否达到封锁15min
			$account_locked = true;
	}
	// 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
		$html .= "<p>Welcome to the password protected area <em>{$user}</em></p>";
		$html .= "<img src=\"{$avatar}\" />";
		// Had the account been locked out since last login?
		if( $failed_login >= $total_failed_login ) {  //判断是否超过最大登录次数3次
			$html .= "<p><em>Warning</em>: Someone might of been brute forcing your account.</p>";
			$html .= "<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
		$html .= "<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();
?>
 
登录失败提示的那个15min,在尝试三次以内时候并不是真的需要等十五分钟,写的不清不楚的啊。。。建议好好看看源码。
总结一下:
- PDO和mysql_real_escape_string,stripslashes共同防范了sql注入问题
 - 尝试次数+lock out机制使得爆破攻击成功的概率几乎为0。
 









