【工具-DVWA】DVWA渗透系列一:Brute Force

前言

DVWA安装使用介绍,见:【工具-DVWA】DVWA的安装和使用

本渗透系列包含最新DVWA的14个渗透测试样例:

1.Brute Force(暴力破解)                    
2.Command Injection(命令注入)
3.CSRF(跨站请求伪造)                        
4.File Inclusion(文件包含)
5.File Upload(文件上传)                    
6.Insecure CAPTCHA(不安全的验证码)
7.SQL Injection(SQL注入)                    
8.SQL Injection(Blind)(SQL盲注)
9.Weak Session IDs(有问题的会话ID)                
10.XSS(DOM)(DOM型xss)
11.XSS(ref)(反射型xss)                    
12.XSS(Stored)(存储型xss)
13.CSP Bypass(Content Security Policy内容安全策略,旁路/绕过)    
14.JavaScript​​​​​​​

安全级别分低、中、高、安全四个级别来分析Brute Force的渗透测试过程。

【工具-DVWA】DVWA渗透系列一:Brute Force_第1张图片

1 Low

1.1 渗透测试

  • 使用Burpsuite来测试,详细过程见:【工具-BurpSuite】BurpSuite专业版 安装和使用

  • 使用SQL注入方式

使用账号【admin' OR '1'='1】+正确密码【password】,发现登陆失败

【工具-DVWA】DVWA渗透系列一:Brute Force_第2张图片

使用账号【admin' OR '1'='1】+空密码【】或者错误密码 ,发现登陆成功

使用账号【admin' OR '1'='2】+任何密码,都能登陆成功

【工具-DVWA】DVWA渗透系列一:Brute Force_第3张图片

咦?这是为何呢?找源码看看。

1.2 源码分析

网站路径:DVWA-master\vulnerabilities\brute下面有源码

index.php:根据安全级别,来选择使用的php代码。

switch( $_COOKIE[ 'security' ] ) {
	case 'low':
		$vulnerabilityFile = 'low.php';
		break;
	case 'medium':
		$vulnerabilityFile = 'medium.php';
		break;
	case 'high':
		$vulnerabilityFile = 'high.php';
		break;
	default:
		$vulnerabilityFile = 'impossible.php';
		$method = 'POST';
		break;
}

low.php:发现SQL执行使用的拼接,且对参数username、password没有做任何过滤,存在SQL注入漏洞和Brute Force漏洞。

//用来检测变量是否设置
if( isset( $_GET[ 'Login' ] ) ) {
	// Get username
	$user = $_GET[ 'username' ];

	// Get password
	$pass = $_GET[ 'password' ];
	$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)) . '
' ); //当查询结果为1个,则认为登陆成功 if( $result && mysqli_num_rows( $result ) == 1 ) { // Login successful $html .= "

Welcome to the password protected area {$user}

"; $html .= ""; } else { // Login failed ...... } ...... }

回到之前的问题,为何使用账号【admin' OR '1'='1】+正确密码【password】,会登陆失败。

执行SQL,发现使用password的密码的用户有2个,当查询结果不为1个时都认为登陆失败:

【工具-DVWA】DVWA渗透系列一:Brute Force_第4张图片

PS:所以,一般SQL注入时,会使用空密码,来避免因密码重复而导致认证失败。

当用户名为【admin' OR '1'='2】时,由于AND优先级高于OR,所以,OR之后的条件相当于不存在,所以只能查询出admin一个用户出来,这个和password不正确的情况是一样的。

2 Medium

2.1 渗透测试

  • 使用Burpsuite来测试

发现:依然可以成功,但是,慢了很多。

  • 使用SQL注入

发现:无效!!

2.2 源码分析

medium.php:与low相比,添加了mysql_real_escape_string函数,来对特殊字符进行转义;同时登陆失败会休眠2秒

if( isset( $_GET[ 'Login' ] ) ) {
	// Sanitise username input
	$user = $_GET[ 'username' ];
	//对字符串中的特殊符号(x00,n,r,,’,”,x1a)进行转义
	$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' ];
	//对字符串中的特殊符号(x00,n,r,,’,”,x1a)进行转义
	$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( '
' . ((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 $html .= "

Welcome to the password protected area {$user}

"; $html .= ""; } else { // Login failed 登陆失败休眠2秒 sleep( 2 ); $html .= "

Username and/or password incorrect.
"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); }

PS:mysql_real_escape_string函数可以绕过哟,sleep(2)休眠时间真是短,贴心......

3 High

3.1 渗透测试

  • burpsuite测试

发现:请求中多了一个参数user_token,按原来的暴力请求,会返回CSRF token不正确的异常。

【工具-DVWA】DVWA渗透系列一:Brute Force_第5张图片

【工具-DVWA】DVWA渗透系列一:Brute Force_第6张图片

  • 查看页面代码

发现:页面中多了一个隐藏字段user_token,它会随着请求提交,且每次登陆后,该值会变化

  • 再次尝试

1、抓取请求,发送到Intruder,选择Password和user_token,使用Pitchfork(一一映射方式),即每次登陆密码都对应新的user_token

【工具-DVWA】DVWA渗透系列一:Brute Force_第7张图片

2、线程数修改为1,因为一个user_token只能支持一次登陆测试,只要测试过一次,那么token就会失效。

【工具-DVWA】DVWA渗透系列一:Brute Force_第8张图片

3、从页面中抓取user_token

【工具-DVWA】DVWA渗透系列一:Brute Force_第9张图片

 

点击Refetch response,然后双击你需要抓取的内容,burp会自动帮你填充start和end的内容:

【工具-DVWA】DVWA渗透系列一:Brute Force_第10张图片

4、Payload1设置照旧,payload2,选择Recursive grep,payload内容会自动加载刚刚配置的截取规则,first request需要填写最新的user_token,去页面里看代码或者使用刚刚response里的value(在这之后没有使用过这个token)。

【工具-DVWA】DVWA渗透系列一:Brute Force_第11张图片

5、测试成功,user_token会自动截取页面的值,进行请求:

【工具-DVWA】DVWA渗透系列一:Brute Force_第12张图片

3.2 源码分析

high.php:与medium相比主要就多了一个CSRF-token的效验和生成,还有就是stripslashes去掉反斜线,避免转义绕过

if( isset( $_GET[ 'Login' ] ) ) {
	// Check Anti-CSRF token,验证CSRF-token是否正确 
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

	// Sanitise username input
	$user = $_GET[ '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 = $_GET[ '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 );

	// 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 ) { // Login successful $html .= "

Welcome to the password protected area {$user}

"; $html .= ""; } else { // Login failed,登陆失败休眠0-3秒 sleep( rand( 0, 3 ) ); $html .= "

Username and/or password incorrect.
"; } } // Generate Anti-CSRF token,产生CSRF-token generateSessionToken();

4 impossible

4.1 渗透测试

发现没效果......

4.2 源码分析

核心代码:限制登陆失败次数,以及账号锁定机制,同时使用了更安全的PDO机制,来限制传参执行数据库操作。

// Default values
$total_failed_login = 3;
$lockout_time       = 15;
$account_locked     = false;

// Check the database (Check user information),不能使用PDO扩展本身执行任何数据库操作
$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.当登陆失败次数超过3次,将锁定账号15分钟
if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) )  {
	// User locked out.  Note, using this method would allow for user enumeration!
	//$html .= "

This account has been locked due to too many incorrect logins.
"; // 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) . "
"; print "The timenow is: " . date ("h:i:s", $timenow) . "
"; print "The timeout is: " . date ("h:i:s", $timeout) . "
"; */ // 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
"; } }

5 总结

暴力破解可应用场景:

  • 没有验证码
  • 没有账号登陆失败+锁定机制

登陆渗透过程:

  1. 尝试SQL注入
  2. 尝试常规暴力破解
  3. 通过分析页面源代码和请求参数来解决CSRF类验证

 

 


爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!

你可能感兴趣的:(安全,工具)