DVWA之Brute Force(暴力破解)
暴力破解是指使用窮舉法,舉出所有的可能的結果,然後逐一驗證是否正確!
Low
原始碼:
<?php 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( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); if( $result && mysqli_num_rows( $result ) == 1 ) { // Get users details $row = mysqli_fetch_assoc( $result ); $avatar = $row["avatar"]; // Login successful echo "<p>Welcome to the password protected area {$user}</p>"; echo "<img src=\"{$avatar}\" />"; } else { // Login failed echo "<pre><br />Username and/or password incorrect.</pre>"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
low級別的程式碼直接獲取使用者輸入的使用者名稱和密碼,密碼再經過MD5進行加密。然後查詢資料庫中,查詢出結果來了說明使用者名稱和密碼正確。這裡對輸入的使用者名稱和密碼沒經過任何的過濾和檢查。
我們輸入 admin 和任意的密碼,然後用burpsuite進行抓包
傳送到 Intruder 模組 ,這裡會對所有可能的爆破點標記
我們點選 clear,然後add增加我們的密碼,使其成為爆破點
我們點選 payloads,然後選擇 load 來載入我們的密碼字典,也可以使用paste貼上密碼,還可以使用add手動輸入密碼
然後點選 start attack 開始攻擊
Medium
原始碼:
<?php if( isset( $_GET[ 'Login' ] ) ) { // Sanitise username input $user = $_GET[ 'username' ]; $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 = ((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( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); if( $result && mysqli_num_rows( $result ) == 1 ) { // Get users details $row = mysqli_fetch_assoc( $result ); $avatar = $row["avatar"]; // Login successful echo "<p>Welcome to the password protected area {$user}</p>"; echo "<img src=\"{$avatar}\" />"; } else { // Login failed sleep( 2 ); echo "<pre><br />Username and/or password incorrect.</pre>"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
mysqli_real_escape_string(string,connection) :函式會對字串string中的特殊符號(\x00,\n,\r,\,‘,“,\x1a)進行轉義。
$GLOBALS :引用全域性作用域中可用的全部變數。$GLOBALS 這種全域性變數用於在 PHP 指令碼中的任意位置訪問全域性變數(從函式或方法中均可)。PHP 在名為 $GLOBALS[index] 的陣列中儲存了所有全域性變數。變數的名字就是陣列的鍵。
可以看到,medium級別的程式碼對使用者輸入的引數進行了簡單的過濾,對一些預定義字元進行了轉義,基本上防止了SQL注入。還有一個措施就是如果密碼輸錯了,則延時兩秒之後才能再次提交。
這依然可以和 low 級別的爆破一樣,只不過時間長了點而已。因為試一次密碼要過濾2秒才能試下一個。
High
原始碼:
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Check Anti-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( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// Get users details
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( rand( 0, 3 ) );
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>
stripslashes(string): 去除掉string字元的反斜槓\
mysqli_real_escape_string(string,connection) :函式會對字串string中的特殊符號(\x00,\n,\r,\,‘,“,\x1a)進行轉義。
$GLOBALS :引用全域性作用域中可用的全部變數。$GLOBALS 這種全域性變數用於在 PHP 指令碼中的任意位置訪問全域性變數(從函式或方法中均可)。PHP 在名為 $GLOBALS[index] 的陣列中儲存了所有全域性變數。變數的名字就是陣列的鍵。
High級別的程式碼使用了Anti-CSRF token來抵禦CSRF的攻擊,使用了stripslashes函式和mysqli_real_esacpe_string來抵禦SQL注入和XSS的攻擊。
由於使用了Anti-CSRF token,每次伺服器返回的登陸頁面中都會包含一個隨機的user_token的值,使用者每次登入時都要將user_token一起提交。伺服器收到請求後,會優先做token的檢查,再進行sql查詢。所以,我們不能再利用burpsuite進行無腦式的爆破了。