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();
?>