DVWA靶機-跨站請求僞造(CSRF)

DVWA靶機-跨站請求僞造(CSRF)

引入SQL注入是一種後端的攻擊行爲,通過瀏覽器發出請求,基於http/https協議將數據送給對方服務器,服務器通過WEB容器,將數據進行解析,實現與數據庫的交互,而CSRF則是一種前端的注入

DVWA靶機-暴力破解(Brute Force) && DVWA靶機的四個安全等級

DVWA靶機-命令注入漏洞(Command Injection)

DVWA靶機-文件包含漏洞(File Inclusion)

DVWA靶機-文件上傳漏洞(File uploads)

CSRF攻擊

CSRF(Cross-Site Request Forgery)是一種前端的注入,譯爲跨站請求僞造

瀏覽器的同源策略:(Same origin policy)是一種約定,是瀏覽器最核心也是最基本的安全功能,所謂同源是指域名、協議、端口相同

CSRF攻擊: 是利用受被攻擊者的身份認證信息(cookie),誘騙其點擊惡意鏈接或者訪問包含攻擊代碼的界面,在被攻擊者不知情的情況下以被攻擊者的身份向服務器發出請求,從而進行一些非法操作(改密碼)

通常情況下由於同源策略的原因,我們不能直接進行跨站操作,但是HTML中存在可跨站的腳本語言

在html中,同源策略對下列腳本語言無效:

<script></script>
img圖片
iframe
line
等.....

CSRF攻擊原理概述

在這裏插入圖片描述
1.用戶USER打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼登錄網站A
2.在用戶通過驗證之後,網站A產生cookie信息並返回給瀏覽器,此時用戶登錄網站A成功
3.用戶未退出網站A的情況下,在同一瀏覽器訪問B
4.網站B接收到用戶請求之後,返回攻擊代碼,併發出一個請求要求訪問第三方站點A
5.瀏覽器接收攻擊性代碼後,根據B的請求,在用戶不知情的情況下以用戶USER的身份(攜帶USER的cookie)信息,向網站A發出請求

此時網站A不知道請求由B發起,根據用戶USER的cookie信息以USER的身份權限處理該請求,從而導致網站B的惡意代碼被執行

1.DVWA-LOW等級下的CSRF攻擊

在low等級下,無任何安全策略以及過濾,web頁面回顯如下,Change your admin password,修改當前用戶admin的密碼
在這裏插入圖片描述
此時我們輸入新的密碼,確認一次,在Web頁面回顯已經修改成功(Password Changed)

瀏覽器URL中回顯爲,http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#,此時漏洞點就暴露出來

在這裏插入圖片描述
在這裏插入圖片描述
此時所在頁面設爲WEB A
我們以攻擊者的身份創建一個新的鏈接爲WEB B,鏈接爲:

http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

以此鏈接發送個admin用戶,誘導用戶點擊該鏈接

admin在同一個瀏覽器中打開該鏈接,此時會以WEB A頁面用戶admin的身份信息打開該鏈接,由於該鏈接與WEB A頁面同源,此時會通過直接修改admin的密碼爲123456,且頁面回顯與WEB A頁面一致
在這裏插入圖片描述
admin用戶再次登錄發現密碼已經被修改,Login failed(登錄失敗)
在這裏插入圖片描述

完善環境,趨於真實

上述過程中,完整的展示出了CSRF攻擊的整個流程,但是其中存在很大的問題

question1:Web B鏈接接的格式問題

我們在以攻擊者的身份來誘導用戶admin,來點擊B鏈接,但是B鏈接太過於簡單(弱智)

http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

只要是一個稍微懂點計算機知識的都能看出,該鏈接中有密碼信息且該鏈接與鏈接A基本上相同,所以這種連接作爲用戶能直觀看出來的作用的,你覺得用戶回去點擊嗎?

用戶不會點擊該鏈接(B)的原因就是該鏈接,過於簡單且無誘惑力站在被攻擊者的角度來想想,我爲什麼要去點擊這個鏈接? 點擊這個鏈接對自己有什麼好處?

question1解決問題

1.長短連接變換:長短鏈接變換,可以使該鏈接變的真實,且具有迷惑性,在DVWA中由於是本地環境,且基於本地IP地址,無法進行長鏈接變短鏈接的操作

舉例
這是我之前的DVWA-文件上傳漏洞(File Upload)博文,從長鏈接我們能看出該URL爲CSDN博客,短鏈接無法看出

長鏈接: https://blog.csdn.net/weixin_43726831/article/details/102512070
短鏈接: http://mrw.so/5aMSRJ

2.轉換成二維碼:將鏈接轉換成二維碼,相比於短鏈接,二維碼更具真實性,更具迷惑性

舉例
長鏈接: https://blog.csdn.net/weixin_43726831/article/details/102512070
二維碼:
在這裏插入圖片描述
3.轉換成圖片格式的鏈接
在三種鏈接轉換方式中,最具有迷惑性,誘惑力的就爲圖片鏈接形式

question2:Web B頁面的回顯問題

上述過程中WEB B頁面回顯同WEB A頁面的回顯一致,admin用戶打開連接B能直觀的發現自己的密碼已經被修改(Password Change)

question2問題解決

在現實的攻擊中,需要定義一個攻擊回顯頁面,該攻擊頁面能既能達到攻擊的效果,又能不讓用戶發覺
在DVWA環境中,由於是本地環境,我們可以定義一個本地WEB頁面(html文件)

touch change.html
vim change.html

寫入代碼

<img src="http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/
?password_new=123456&password_conf=123456&Change=Change#" border="0" style="display:none"/>
<h1>404<h1>
<h2>file not found.<h2>

admin用戶打開鏈接http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/change.html
當然可對該攻擊頁面進行進行優化,使之更加趨於真實,當然該鏈接也需進行迷惑型的轉化
在這裏插入圖片描述

此時change.html中的代碼已經執行(也就是修改密碼已經完成),被攻擊者此時無法察覺自己的密碼已經被修改了,當被攻擊者下次登錄該網站時發現密碼已經被修改。
在這裏插入圖片描述

LOW等級下的CSRF源碼

CSRF Source:
無安全策略,當pass_new=pass_conf時直接修改密碼。

<?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 = mysql_real_escape_string( $pass_new );
        $pass_new = md5( $pass_new );

        // Update the database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );

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

    mysql_close();
}

?> 

2.DVWA-Medium等級下的CSRF攻擊

DVWA-Medium等價下CSRF攻擊,會有一些安全策略

CSRF Source:
eregi()函數: 在一個字符串搜索指定的模式的字符串,在medium等級中,檢查HTTP_REFERER字段中是否有包含SERVER_NAME(HOST)字段,當匹配成功時返回true,否則返回false

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Checks to see where the request came from
    if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) {
        // 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 = mysql_real_escape_string( $pass_new );
            $pass_new = md5( $pass_new );

            // Update the database
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
            $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );

            // Feedback for the user
            echo "<pre>Password Changed.</pre>";
        }
        else {
            // Issue with passwords matching
            echo "<pre>Passwords did not match.</pre>";
        }
    }
    else {
        // Didn't come from a trusted source
        echo "<pre>That request didn't look correct.</pre>";
    }

    mysql_close();
}

?> 

也就是說referer字段裏必須存在HOST:192.168.203.149 eregi()函數是用字符串進行比較

繞過方法: 我們此時可以創建一個帶有192.168.203.149的html文件,192.168.203.149.html文件
寫入具有迷惑性的代碼

<img src="http://192.168.203.149/DVWA-1.9/vulnerabilities/csrf/
?password_new=123456&password_conf=123456&Change=Change#" border="0" style="display:none"/>
<h1>404<h1>
<h2>file not found.<h2>

HOST字段通常與本地主機IP相同,爲了防止干擾,我們在本地192.168.203.150主機上面做
在這裏插入圖片描述
此時被攻擊者admin打開連接http://192.168.203.150/DVWA-1.9/vulnerabilities/csrf/192.168.203.149.html
在這裏插入圖片描述
192.168.203.149.html中的腳本被執行,此時密碼已經修改
當被攻擊者下次再次登錄該網站時,才發覺自己的密碼已經被修改。
在這裏插入圖片描述

3.DVWA-High等級下的CSRF攻擊

在High等級下,安全策略啓用了token機制,安全性更強
CSRF Source:
基於token的驗證,隨機數,由於現在瀏覽器不支持跨域,後期我們在XSS漏洞中,我們可以藉助XSS漏洞協助獲取token

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // 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 = mysql_real_escape_string( $pass_new );
        $pass_new = md5( $pass_new );

        // Update the database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );

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

    mysql_close();
}

// Generate Anti-CSRF token
generateSessionToken();

?> 

4.DVWA-impossible等級下的CSRF

impossible等級之下,有相當強的安全策略,幾乎不可能攻破

CSRF Source:
Token機制: 定義隨機數token
stripslashes() 函數: 過濾了反斜槓,刪除反斜槓
mysql_real_escape_string() 函數: 轉義 SQL 語句中使用的字符串中的特殊字符,\x00 \n \r \ ’ " \x1a字符受影響。
bindParam()函數: 該函數綁定了 SQL 的參數,且告訴數據庫參數的值

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $pass_curr = $_GET[ 'password_current' ];
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];

    // Sanitise current password input
    $pass_curr = stripslashes( $pass_curr );
    $pass_curr = mysql_real_escape_string( $pass_curr );
    $pass_curr = md5( $pass_curr );

    // Check that the current password is correct
    $data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
    $data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
    $data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
    $data->execute();

    // Do both new passwords match and does the current password match the user?
    if( ( $pass_new == $pass_conf ) && ( $data->rowCount() == 1 ) ) {
        // It does!
        $pass_new = stripslashes( $pass_new );
        $pass_new = mysql_real_escape_string( $pass_new );
        $pass_new = md5( $pass_new );

        // Update database with new password
        $data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' );
        $data->bindParam( ':password', $pass_new, PDO::PARAM_STR );
        $data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
        $data->execute();

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

// Generate Anti-CSRF token
generateSessionToken();

?> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章