CSRF(跨站請求偽造)學習總結

前言

參考大佬的文章,附上地址 //www.freebuf.com/articles/web/118352.html

什麼是CSRF?

       CSRF,中文名字,跨站請求偽造,聽起來是不是和XSS差不多?區別就在於,CSRF並沒有盜取cookie而是直接利用。通俗的來說,就是攻擊者盜用了你的身份,在你不知情的情況下執行一些違法操作,比如密碼修改,增加管理員,轉賬等敏感操作,危害很大。

漏洞利用

      這裡已DVWA為例,通過實例演示自己的學習過程。對DVWA陌生,並且想了解搭建一下的,可以參考這篇文章 //www.cnblogs.com/lxfweb/p/12678463.html  

打開DVWA,選擇CSRF,先從最低級別的low開始,查看源程式碼

 

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Get input
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];

    // Do the passwords match?
    if( $pass_new == $pass_conf ) {
        // They do!
        $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)) ? "" : ""));
        $pass_new = md5( $pass_new );

        // Update the database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $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>' );

        // Feedback for the user
        echo "<pre>Password Changed.</pre>";
    }
    else {
        // Issue with passwords matching
        echo "<pre>Passwords did not match.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?> 

 

通過查看發現,程式碼中,password_new,password_conf,兩個參數沒有做任何防護,這樣是相當危險的,如果攻擊者對受害者的這套程式很熟悉,可以很輕易的構造鏈接,只要攻擊者一點擊這個鏈接,就會觸發CSRF攻擊。這是DVWA修改密碼的鏈接 //www.test.com/DVWA-master/vulnerabilities/csrf/?password_new=12345678&password_conf=12345678&Change=Change#  受害者只要帶登陸情況下點擊這個鏈接(同一瀏覽器),密碼就會被修改為12345678,不過這鏈接一看就是改密碼的,基本不會有人點,所以需要咱們精心構造一下,這裡以burpsuite演示。進去修改密碼頁面,抓包。

點擊Generate CSRF PoC burp會構造簡單的一個頁面,如圖

接下來,將構造的網址複製到瀏覽器,就會有一個按鈕,用戶點擊就會觸發CSRF攻擊,密碼被修改。

不過這個做法也有些粗糙,點擊完,會自動跳轉到,密碼修改的頁面,受害者就知道密碼被修改,

參考上面提到的文章裡面的思路,那就是隱藏img src 標籤,再可以精心構造一個錯誤頁面,讓受害者認為這是一個無效的URL,但已經進行了CSRF攻擊。構造的程式碼如下

<img src="//www.test.com/DVWA-master/vulnerabilities/csrf/?password_new=12345678&password_conf=12345678&Change=Change#" border="0" style="display:none;"/>

<h1>404<h1>

<h2>file not found.<h2>

 

 

下面看一下中級的DVWA部分源程式碼截圖,看做了什麼防禦。

可以看到,中級別的程式碼檢查了保留變數 HTTP_REFERERhttp包頭的Referer參數的值,表示來源地址)中是否包含SERVER_NAMEhttp包頭的Host參數,及要訪問的主機名)抓包看一下,通俗的講,不在本域的請求,就會拒絕訪問。

那該如何繞過呢,這個,只需要將咱們構造的頁面名字改為受害者的主機名即可,如上圖,至於要將名字改為 www.test.com.html,就可以繞過啦。

防禦措施

1)檢查Referer欄位

HTTP頭中有一個Referer欄位,這個欄位用以標明請求來源於哪個地址。在處理敏感數據請求時,通常來說,Referer欄位應和請求的地址位於同一域名下。但是這樣的方式,也是不安全的,上文中已經講解了,如何繞過Referer欄位的檢查。

2)添加校驗token(來源百度百科)

由於CSRF的本質在於攻擊者欺騙用戶去訪問自己設置的地址,所以如果要求在訪問敏感數據請求時,要求用戶瀏覽器提供不保存在cookie中,並且攻擊者無法偽造的數據作為校驗,那麼攻擊者就無法再運行CSRF攻擊。這種數據通常是窗體中的一個數據項。伺服器將其生成並附加在窗體中,其內容是一個偽隨機數。當客戶端通過窗體提交請求時,這個偽隨機數也一併提交上去以供校驗。正常的訪問時,客戶端瀏覽器能夠正確得到並傳回這個偽隨機數,而通過CSRF傳來的欺騙性攻擊中,攻擊者無從事先得知這個偽隨機數的值,服務端就會因為校驗token的值為空或者錯誤,拒絕這個可疑請求。

 3)源程式碼中增加輸入原密碼機制

在這種情況下,攻擊者在不知道原密碼的情況下是無法進行CSRF攻擊的。

 

Tags: