天天看點

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

DVWA學習之CSRF

  • CSRF(Cross-site request forgery,跨站請求僞造)
    • 0x01 何為CSRF?
    • 0x02 CSRF原理
    • 0x03 low級别
    • 0x04 medium級别
    • 0x05 high級别
    • 0x06 impossible級别
    • 0x07 CSRF防禦
      • 服務端的防禦
        • 驗證HTTP Referer字段
        • 在請求位址中添加token并驗證
        • 在HTTP頭中自定義屬性并驗證
      • 使用者端的防禦
      • 安全裝置的防禦

CSRF(Cross-site request forgery,跨站請求僞造)

0x01 何為CSRF?

CSRF:全稱Cross-site request forgery,翻譯過來就是跨站請求僞造, 是指利用受害者尚未失效的身份認證資訊(cookie、會話等),誘騙其 點選惡意連結或者通路包含攻擊代碼的頁面,在受害人不知情的情況下 以受害者的身份向(身份認證資訊所對應的)伺服器發送請求,進而完 成非法操作(如轉賬、改密等)。CSRF與XSS最大的差別就在于,CSRF并 沒有盜取cookie而是直接利用。

相信看到下面這幅圖,你就對CSRF這一簡寫印象深刻

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

0x02 CSRF原理

csrf攻擊的原理如下:

1.正常的使用者通過輸入密碼登入了網站A(被攻擊站點);

2.網站A(被攻擊站點)判斷該使用者密碼合法性,産生cookie儲存在浏覽器中,此時使用者登入網站A成功;

3.使用者在沒有退出網站A(被攻擊站點)的情況下,通路了網站B(攻擊者的站點);

4.網站B(攻擊者的站點)接收到使用者請求後,傳回一些攻擊性代碼,并發出一個請求要求通路網站A;

5.浏覽器在收到攻擊性代碼後,根據網站B的請求,在使用者不知情的情況下攜帶Cookie資訊,向網站A送出請求。網站A并不知道該請求其實是由B發起的,是以會根據受害者的Cookie資訊以受害者的權限處理該請求,導緻來自網站B的惡意代碼被執行。

crsf原理圖如下:

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

0x03 low級别

low級别CSRF:隻是對輸入的兩次密碼是否相同進行了簡單的判斷,沒有進行其他的防禦,是以,隻要使用者在cookie還有小的時間内在相同的浏覽器通路我們給定的url(該操作是伺服器對請求的發送者進行了身份驗證,檢查cookie),就可以實作CSRF 攻擊,最終修改密碼。

方式一:直接指定URL,讓使用者進行點選(該方式,構造URL攻擊小郭太過于明顯,使用者隻要一看靠該URL即可判斷是惡意連結)

構造惡意URL: http://192.168.15.164/dvwa/vulnerabilities/csrf/?password_new=my&password_conf=my&Change=Change#
           
DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

此外、CSRF最關鍵的是利用受害者的cookie向伺服器發送僞造請求,是以受害者之前用的是IE浏覽器登入的系統,而後通過谷歌浏覽器浏覽該惡意連結,攻擊是不會觸發的,因為請求谷歌浏覽器沒有存儲受害者登入cookie,而會直接跳入登入界面.

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

方式二:使用一些技巧,将url做一下改變,例如:縮短網址,将較長較明顯的惡意URL變為短連接配接:

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

誘導使用者點選短連接配接,當點選網短連接配接後,直接跳轉到原來的連結,更改使用者密碼:

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

通過縮短連結的方式:也存在缺點,當使用者點選短連接配接後,仍然會跳轉到原有連結,出現更改密碼的界面,一旦使用者看到修改密碼的界面,就全露餡了

方式三:通過構造一個惡意頁面,讓使用者通路頁面時,出現諸如:404錯誤之類的僞裝頁面(這裡就直接惡作劇了),悄悄的更改使用者的密碼。

首先,構造頁面demo.html:通過img标簽中的src屬性來加載CSRF攻擊利用的URL,并進行布局隐藏,實作了受害者點選連結則會将密碼修改。

<img src="http://192.168.15.164/dvwa/vulnerabilities/csrf/?password_new=my&password_conf=my&Change=Change#" border="0" style="display:none;"/> <h1>hello gay<h1> <h2>Your password has been changed!!!<h2>
           

其次:将頁面放在公網上或者自己的伺服器上(這裡就直接上傳到本地的另一台伺服器),誘導受害者通路上傳的頁面。

受害者通路上傳的惡意頁面(< img>display設為none,直接執行不回顯),當受害者看到該頁面,密碼已經被偷偷修改:

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

0x04 medium級别

首先,将級别調為medium,bp抓個包

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

這裡先介紹幾個源碼中用到的函數

stripos(string,find,start):函數查找字元串在另一字元串中第一次出現的位置,不區分大小寫。
 eregi(string pattern, string string):檢查string中是否含有pattern(不區分大小寫),如果有傳回True,反之False。
 
 PHP超全局變量$_SERVER中的兩個值:
 
 $_SERVER['HTTP_REFERER']:PHP中擷取連結到目前頁面的前一頁面的url連結位址,即HTTP資料包中的Referer參數的值。
 $_SERVER['SERVER_NAME']:PHP中擷取伺服器主機的名稱,即HTTP資料包中的Host參數的值。
           

該級别檢查了保留變量HTTP_REFERER(http-header的Referer參數的值,表示源位址)中是否包含SERVER_NAME(http標頭的Host參數,及要通路的主機名,這裡是192.168.15.164),希望通過這種機制抵禦CSRF攻擊。一開始就調用eregi()函數來判斷HTTP頭的referer字段裡是不是包含“192.168.15.164”字元串,即發送請求的是不是本機,如果是則繼續後面代碼的執行。

簡而言之,若想通過驗證就必須確定在http請求中國年Referer字段中必須包含host,是以隻需要在連接配接中添加目标的host即可通過驗證。

在攻擊者的伺服器中将html檔案命名為:192.168.15.164.html

誘導受害者通路:http://192.168.15.241/192.168.15.164.html

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

然後,我們驗證是否更改成功,由于伺服器沒有安裝bp,就直接用主機清空曆史記錄,重新登入:登入失敗

DVWA學習之CSRF(跨站請求僞造)CSRF(Cross-site request forgery,跨站請求僞造)

0x05 high級别

high級别中:設定了token限制,它是在每次通路此頁面時,會随機生成一個token,當發起伺服器請求時伺服器會檢查它的值。思路:先擷取token的值,再構造連結并誘騙受害者通路。

問題也就出來了:如何擷取token呢??

這裡提供一個思路:利用XSS将攻擊代碼直接注入到目标伺服器。或者(XSS+CSRF)利用js的ajax跨域請求去得到token,然後帶着token通路改密頁面。(就是構造一個連結誘騙點選,這個連結執行一段放在自己伺服器上js,js執行先得到token,

然後改密。)

我們的想法,想起來很簡單,但實際并沒有這麼容易,為什麼呢?我們回想一下,CSRF(Cross-site request forgery,跨站請求僞造)是屬于跨站攻擊,我們攻擊代碼放在自己的伺服器上,想讓受害者通過我們的腳本,而後偷偷連接配接受害者并修改密碼,這屬于跨域攻擊,然而現在的浏覽器 禁止跨域請求,是以我們通過在自己伺服器上的腳本,無法擷取受害者user_token。是以,這種通過在自己的伺服器上上傳腳本檔案,引誘受害點選,然後腳本請求受害者主機的方法行不通。

那我們就沒辦法了麼???程式員不能說不:

那麼我們就可以:另辟蹊徑:

新思路一:那就想辦法,直接把腳本檔案偷偷上傳到受害者的伺服器呗,然後引誘其通路自己伺服器的腳本,至于怎麼上傳,你可以…哈哈,自己思考吧,誰讓我們是未來的滲透工程師呢。

新思路二:利用dvwa的xss漏洞,直接擷取受害者的cookie資訊,然後通過bp修改cookie,進行一次重播攻擊,簡單粗暴,直接達到目的。但這種方法,并不是十分實用,因為我們是在實驗,我們知道dvwa存在的xss漏洞,如果是實戰,又怎麼能曉得受害着是否存在xss漏洞呢?至于xss漏洞,在後面的章節将繼續分享

0x06 impossible級别

當我們點選到impossible級别的源碼,後可以清楚的發現,imposing級别不僅使用了Anti-CSRF token檢驗來杜絕一定上的CSRF漏洞的利用,還加入了PDO(PHP Data Objects )技術用來防禦SQL注入,還要求輸入目前密碼來确定執行此操作的是否為使用者本人用來防護CSRF。基本杜絕了惡意使用者的攻擊。

0x07 CSRF防禦

CSRF的防禦一般分為三個層面:服務端的防禦、使用者端的防禦和安全裝置的防禦

服務端的防禦

服務端的防禦主要有三種政策:驗證HTTP Referer 字段、在請求位址中添加token驗證、在HTTP頭中自定義屬性并驗證。

驗證HTTP Referer字段

根據 HTTP 協定,在 HTTP 頭中有一個字段叫 Referer,它記錄了該 HTTP 請求的來源位址。在通常情況下,通路一個安全受限頁面的請求來自于同一個網站,比如需要通路 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,使用者必須先登陸 bank.example,然後通過點選頁面上的按鈕來觸發轉賬事件。這時,該轉帳請求的 Referer 值就會是轉賬按鈕所在的頁面的 URL,通常是以 bank.example 域名開頭的位址。而如果黑客要對銀行網站實施 CSRF 攻擊,他隻能在他自己的網站構造請求,當使用者通過黑客的網站發送請求到銀行時,該請求的 Referer 是指向黑客自己的網站。是以,要防禦 CSRF 攻擊,銀行網站隻需要對于每一個轉賬請求驗證其 Referer 值,如果是以 bank.example 開頭的域名,則說明該請求是來自銀行網站自己的請求,是合法的。如果 Referer 是其他網站的話,則有可能是黑客的 CSRF 攻擊,拒絕該請求。

這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不需要操心 CSRF 的漏洞,隻需要在最後給所有安全敏感的請求統一增加一個攔截器來檢查 Referer 的值就可以。特别是對于目前現有的系統,不需要改變目前系統的任何已有代碼和邏輯,沒有風險,非常便捷。

然而,這種方法并非萬無一失。Referer 的值是由浏覽器提供的,雖然 HTTP 協定上有明确的要求,但是每個浏覽器對于 Referer 的具體實作可能有差别,并不能保證浏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴于第三方(即浏覽器)來保障,從理論上來講,這樣并不安全。事實上,對于某些浏覽器,比如 IE6 或 FF2,目前已經有一些方法可以篡改 Referer 值。如果 bank.example 網站支援 IE6 浏覽器,黑客完全可以把使用者浏覽器的 Referer 值設為以 bank.example 域名開頭的位址,這樣就可以通過驗證,進而進行 CSRF 攻擊。

即便是使用最新的浏覽器,黑客無法篡改 Referer 值,這種方法仍然有問題。因為 Referer 值會記錄下使用者的通路來源,有些使用者認為這樣會侵犯到他們自己的隐私權,特别是有些組織擔心 Referer 值會把組織内網中的某些資訊洩露到外網中。是以,使用者自己可以設定浏覽器使其在發送請求時不再提供 Referer。當他們正常通路銀行網站時,網站會因為請求沒有 Referer 值而認為是 CSRF 攻擊,拒絕合法使用者的通路。

在請求位址中添加token并驗證

CSRF 攻擊之是以能夠成功,是因為黑客可以完全僞造使用者的請求,該請求中所有的使用者驗證資訊都是存在于 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 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。

使用者端的防禦

對于普通使用者來說,都學習并具備網絡安全知識以防禦網絡攻擊是不現實的。但若使用者養成良好的上網習慣,則能夠很大程度上減少CSRF攻擊的危害。例如,使用者上網時,不要輕易點選網絡論壇、聊天室、即時通訊工具或電子郵件中出現的連結或者圖檔;及時退出長時間不使用的已登入賬戶,尤其是系統管理者,應盡量在登出系統的情況下點選未知連結和圖檔。除此之外,使用者還需要在連接配接網際網路的計算機上安裝合适的安全防護軟體,并及時更新軟體廠商釋出的特征庫,以保持安全軟體對最新攻擊的實時跟蹤。

安全裝置的防禦

至于安全裝置的防禦,普通使用者就通過安裝防火牆等軟體設定好過濾規則進行防禦;企業等機構就使用實體裝置進行防禦,直接架設專門的防火牆進行防禦。

注:防禦階段實作方法引用自:https://blog.csdn.net/stpeace/article/details/53512283

繼續閱讀