CSRF
跨站請求偽造
漏洞介紹
跨站點請求偽造(Cross Site Request Forgery)是一種經典的網路攻擊方式,它一直是OWASP TOP 10之一,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用,盡管聽起來和跨站腳本攻擊很相似,但它與跨站腳本攻擊非常不同,并且攻擊方式幾乎完全不一樣,CSRF與XSS最大的區別就在于,CSRF并沒有盜取cookie而是直接利用,跨站腳本攻擊利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站,與跨站腳本攻擊相比,CSRF攻擊往往不大流行,因此對其進行防范的措施也相當稀少,另外對于CSRF的防范難度更大,所以被認為比跨站腳本攻擊更具危險性,
CSRF危害
你這可以這么理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義發送惡意請求,CSRF能夠做的事情包括:以你名義發送郵件,發訊息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉賬…造成的問題包括:個人隱私泄露以及財產安全,
Session的作業原理
想要深入理解CSRF的攻擊特性我們有必要了解一下網站Session的作業原理,
Session大家都不陌生,無論是用.net還是PHP開發過網站的程式員都肯定用過Session物件,然而Session它是如何作業的呢?如果我們把瀏覽器的Cookie禁用了,大家認為Session還能正常作業嗎? 答案是否定的,
在這里舉個簡單的例子幫助大家理解Session,比如我買了一張高爾夫俱樂部的會員卡,俱樂部給了我一張帶有卡號的會員卡,我能享受哪些權利呢?如果我是高級會員卡可以打19洞和后付費喝飲料,而初級會員卡只能在練習場揮桿,我的個人資料都是保存在高爾夫俱樂部的資料庫里,我每次去高爾夫俱樂部只需要出示這張高級會員卡,俱樂部就知道我是誰了,并且為我服務了, 因此我們的高級會員卡卡號相當于保存在Cookie的Sessionid;而我的高級會員卡權利和個人資訊就相當于服務端的Session物件,
我們知道Http是無狀態的協議,它不要求瀏覽器在每次請求中標明客戶端自己的身份,并且瀏覽器以及服務器之間并沒有保持一個持久性的連接用于多個頁面之間的訪問,為了維持web應用程式狀態的問題,每次Http請求都會將本域下的所有Cookie作為Http請求頭的一部分發送給服務端,服務器端就可以根據請求中的Cookie所存放的Sessionid去Session物件中找到該會員資料了,
我們理解了Session的作業機制后,CSRF也就很容易理解了,CSRF攻擊就相當于攻擊用戶復制了我的高級會員卡,然后攻擊用戶就可以拿著這張假冒的高級會員卡去高爾夫俱樂部打19洞,享受美味的飲料,而我這個受害者在月底就會收到高爾夫俱樂部的賬單,
CSRF的攻擊程序
CSRF攻擊程序有以下兩個重點:
目標用戶已經登錄了網站,能夠執行網站的功能
目標用戶訪問了攻擊者構造的URL

CSRF攻擊舉例
受害者Bob 在銀行有一筆存款,通過對銀行的網站發送請求 “http://bank.example/withdraw?account=bob&amount=1000000&for=bob2”可以使 Bob把1000000塊的存款轉到Bob2的賬號下,通常情況下,該請求發送到網站后,服務器會先驗證該請求是否來自一個合法的Session,并且該Session的用戶Bob已經成功登陸,黑客Hacker自己在該銀行也有賬戶,他知道上文中的URL可以把錢進行轉帳操作,Hacker可以自己發送一個請求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Hacker,但是這個請求來自Hacker而非 Bob,他不能通過安全認證,因此該請求不會起作用,
這時,Hacker想到使用CSRF的攻擊方式,他先自己做一個網站,在網站中放入如下代碼: src=“http://bank.example/withdraw?account=bob&amount=1000000&for=Hacker”,并且通過廣告等誘使 Bob 來訪問他的網站,當Bob訪問該網站時,上述URL就會從Bob的瀏覽器發向銀行,而這個請求會附帶Bob瀏覽器中的 Cookie 一起發向銀行服務器,大多數情況下,該請求會失敗,因為他要求Bob的認證資訊,但是,如果Bob當時恰巧剛訪問他的銀行后不久,他的瀏覽器與銀行網站之間的Session尚未過期,瀏覽器的Cookie之中含有Bob的認證資訊,這時,悲劇發生了,這個URL請求就會得到回應,錢將從Bob的賬號轉移到Hacker的賬號,而Bob當時毫不知情,等以后Bob發現賬戶錢少了,即使他去銀行查詢日志,他也只能發現確實有一個來自于他本人的合法請求轉移了資金,沒有任何被攻擊的痕跡,而Hacker則可以拿到錢后逍遙法外,
CSRF漏洞檢測
檢測CSRF漏洞是一項比較繁瑣的作業,最簡單的方法就是抓取一個正常請求的資料包,去掉Referer欄位后再重新提交,如果該提交還有效,那么基本上可以確定存在CSRF漏洞,
隨著對CSRF漏洞研究的不斷深入,不斷涌現出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等,以CSRFTester工具為例,CSRF漏洞檢測工具的測驗原理如下:使用CSRFTester進行測驗時,首先需要抓取我們在瀏覽器中訪問過的所有鏈接以及所有的表單等資訊,然后通過在CSRFTester中修改相應的表單等資訊,重新提交,這相當于一次偽造客戶端請求,如果修改后的測驗請求成功被網站服務器接受,則說明存在CSRF漏洞,當然此款工具也可以被用來進行CSRF攻擊,
CSRF漏洞修復建議
目前防御 CSRF 攻擊主要有三種策略:驗證 HTTP Referer 欄位;在請求地址中添加token并驗證;在HTTP頭中自定義屬性并驗證,
驗證HTTP Referer欄位
根據 HTTP 協議,在HTTP頭中有一個欄位叫Referer,它記錄了該 HTTP 請求的來源地址,在通常情況下,訪問一個安全受限頁面的請求來自于同一個網站,比如需要訪問 http://bank.example/withdraw?account=bob&amount=1000000&for= Hacker,用戶必須先登陸bank.example,然后通過點擊頁面上的按鈕來觸發轉賬事件,這時,該轉帳請求的Referer值就會是轉賬按鈕所在的頁面的URL,通常是以bank.example域名開頭的地址,而如果黑客要對銀行網站實施 CSRF 攻擊,他只能在他自己的網站構造請求,當用戶通過黑客的網站發送請求到銀行時,該請求的 Referer 是指向黑客自己的網站,因此,要防御CSRF攻擊,銀行網站只需要對于每一個轉賬請求驗證其Referer值,如果是以bank.example開頭的域名,則說明該請求是來自銀行網站自己的請求,是合法的,如果Referer是其他網站的話,則有可能是黑客的CSRF攻擊,拒絕該請求,
這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不需要操心CSRF的漏洞,只需要在最后給所有安全敏感的請求統一增加一個攔截器來檢查Referer的值就可以,特別是對于當前現有的系統,不需要改變當前系統的任何已有代碼和邏輯,沒有風險,非常便捷,
然而,這種方法并非萬無一失,Referer的值是由瀏覽器提供的,雖然 HTTP協議上有明確的要求,但是每個瀏覽器對于Referer的具體實作可能有差別,并不能保證瀏覽器自身沒有安全漏洞,使用驗證 Referer 值的方法,就是把安全性都依賴于第三方(即瀏覽器)來保障,從理論上來講,這樣并不安全,事實上,對于某些瀏覽器已經有一些方法可以篡改 Referer值,如果bank.example網站支持 IE6 瀏覽器,黑客完全可以把用戶瀏覽器的Referer值設為以bank.example域名開頭的地址,這樣就可以通過驗證,從而進行 CSRF 攻擊,
即便是使用最新的瀏覽器,黑客無法篡改Referer值,這種方法仍然有問題,因為Referer值會記錄下用戶的訪問來源,有些用戶認為這樣會侵犯到他們自己的隱私權,特別是有些組織擔心Referer值會把組織內網中的某些資訊泄露到外網中,因此,用戶自己可以設定瀏覽器使其在發送請求時不再提供 Referer,當他們正常訪問銀行網站時,網站會因為請求沒有Referer值而認為是CSRF攻擊,拒絕合法用戶的訪問,
在請求地址中添加token并驗證
攻擊之所以能夠成功,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證資訊都是存在于Cookie中,因此黑客可以在不知道這些驗證資訊的情況下直接利用用戶自己的Cookie來通過安全驗證,要抵御CSRF,關鍵在于在請求中放入黑客所不能偽造的資訊,并且該資訊不存在于Cookie之中,可以在HTTP請求中以引數的形式加入一個隨機產生的token,并在服務器端建立一個攔截器來驗證這個token,如果請求中沒有token或者token內容不正確,則認為可能是CSRF攻擊而拒絕該請求,
這種方法要比檢查Referer要安全一些,token可以在用戶登陸后產生并放于session之中,然后在每次請求時把token從session中拿出,與請求中的token進行比對,但這種方法的難點在于如何把token以引數的形式加入請求,對于 GET 請求,token將附在請求地址之后,這樣 URL 就變成 http://url?csrftoken=tokenvalue, 而對于 POST 請求來說,要在 form 的最后加上 ,這樣就把 token 以引數的形式加入請求了,
但是,在一個網站中,可以接受請求的地方非常多,要對于每一個請求都加上token 是很麻煩的,并且很容易漏掉,通常使用的方法就是在每次頁面加載時,使用JavaScript遍歷整個dom樹,對于dom中所有的a和form標簽后加入token,這樣可以解決大部分的請求,但是對于在頁面加載之后動態生成的html代碼,這種方法就沒有作用,還需要程式員在編碼時手動添加token,
該方法還有一個缺點是難以保證token本身的安全,特別是在一些論壇之類支持用戶自己發表內容的網站,黑客可以在上面發布自己個人網站的地址,由于系統也會在這個地址后面加上token,黑客可以在自己的網站上得到這個 token,并馬上就可以發動 CSRF 攻擊,為了避免這一點,系統可以在添加 token的時候增加一個判斷,如果這個鏈接是鏈接到自己本站的,就在后面添加 token,如果是通向外網則不加,不過,即使這個csrftoken不以引數的形式附加在請求之中,黑客的網站也同樣可以通過Referer來得到這個token值以發動CSRF攻擊,這也是一些用戶喜歡手動關閉瀏覽器Referer功能的原因,
在HTTP頭中自定義屬性并驗證
這種方法也是使用token并進行驗證,和上一種方法不同的是,這里并不是把token以引數的形式置于HTTP請求之中,而是把它放到HTTP頭中自定義的屬性里,通過 XMLHttpRequest這個類,可以一次性給所有該類請求加上 csrftoken這個HTTP頭屬性,并把token值放入其中,這樣解決了上種方法在請求中加入token的不便,同時,通過XMLHttpRequest請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心token會透過Referer泄露到其他網站中去,
然而這種方法的局限性非常大,XMLHttpRequest 請求通常用于Ajax方法中對于頁面區域的異步重繪,并非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,從而進行前進,后退,重繪,收藏等操作,給用戶帶來不便,另外,對于沒有進行CSRF防護的遺留系統來說,要采用這種方法來進行防護,要把所有請求都改為 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的,
————————————————
SSRF
服務端請求偽造
SSRF漏洞介紹
SSRF(Sever-Side Request Forgery,服務器端請求偽造)是一種由攻擊者構造請求,由服務端發起請求的安全漏洞,一般情況下,SSRF攻擊的目標是外網無法訪問的內部系統(正因為請求是由服務端發起的,所以服務端能請求到與自身相連而與外網隔離的內部系統),
SSRF漏洞原理
SSRF形成的原因大都是由于服務端提供了從其他服務器應用獲取資料的功能,且沒有對目標地址做過濾與限制,例如,黑客操作服務端從指定URL地址獲取網頁文本內容,加載指定地址的圖片等,利用的是服務點的請求偽造,SSRF利用存在缺陷的Web應用作為代理攻擊遠程和本地的服務器,

首先,我們要對目標網站的架構了解,腦子要有一個架構圖,比如 : A網站,是一個所有人都可以訪問的外網網站,B網站是一個他們內部的OA網站,
所以,我們普通用戶只可以訪問a網站,不能訪問b網站,但是我們可以同過a網站做中間人,訪問b網站,從而達到攻擊b網站需求,
正常用戶訪問網站的流程是:
輸入A網站URL --> 發送請求 --> A服務器接受請求(沒有過濾),并處理 -->回傳用戶回應
【那網站有個請求是www.baidu,com/xxx.php?image=URL】
那么產生SSRF漏洞的環節在哪里呢?安全的網站應接收請求后,檢測請求的合法性
產生的原因:服務器端的驗證并沒有對其請求獲取圖片的引數(image=)做出嚴格的過濾以及限制,導致A網站可以從其他服務器的獲取資料
例如:www.baidu.com/xxx.php?image=www.abc.com/1.jpg
如果我們將www.abc.com/1.jpg換為與該服務器相連的內網服務器地址會產生什么效果呢?
如果存在該內網地址就會回傳1xx 2xx 之類的狀態碼,不存在就會其他的狀態碼
終極簡析: SSRF漏洞就是通過篡改獲取資源的請求發送給服務器,但是服務器并沒有檢測這個請求是否合法的,然后服務器以他的身份來訪問其他服務器的資源,
SSRF危害
掃內網
向內部任意主機的任意埠發送精心構造的Payload
DOS攻擊(請求大檔案,始終保持連接Keep-Alive Always)
攻擊內網的web應用,主要是使用GET引數就可以實作的攻擊(比如struts2,sqli等)
利用file協議讀取本地檔案等
SSRF漏洞利用
SSRF漏洞利用測驗地址:http://127.0.0.1/web/ssrf.php?url=127.0.0.1/l.php
頁面ssrf.php實作的功能是獲取GET引數URL,然后將URL的內容回傳網頁上,如果將請求的網址篡改為http://www.baidu.com,則頁面會顯示http://www.baidu.com的網頁內容,如下所示:

但是,當設定引數URL為內網地址時,則會泄露內網資訊,例如,當url=192.168.0.2:3306時,頁面回傳如下:

說明存在mysql服務,
訪問ssrf.php?url=file:///C:/windows/win.ini即可讀取本地檔案,如下所示:

SSRF漏洞代碼分析
在頁面SSRF.PHP中,程式獲取GET引數URL,通過curl_init()初始化curl組件后,將引數URL帶入curl_setopt($ch, CURLOPT_URL, $url),然后呼叫curl_exec請求該URL.由于服務端會將banner資訊回傳客戶端,所以可以根據banner

SSRF漏洞修復建議
過濾回傳資訊,驗證遠程服務器對請求的回應是比較容易的方法,如果web應用是去獲取某一種型別的檔案,那么在把回傳結果展示給用戶之前先驗證回傳的資訊是否符合標準,
統一錯誤資訊,避免用戶可以根據錯誤資訊來判斷遠端服務器的埠狀態,
限制請求的埠為http常用的埠,比如,80,443,8080,8090,
黑名單內網ip,避免應用被用來獲取獲取內網資料,攻擊內網,
禁用不需要的協議,僅僅允許http和https請求,可以防止類似于file:///、gopher://、ftp:// 等引起的問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/327874.html
標籤:其他
