滲透測(cè)試 | Webgoat8 CSRF 超詳細(xì)通關(guān)題解

CSRF

基本原理

CSRF即Cross Site Request Forgery跨站請(qǐng)求偽造,即通過偽造用戶身份來向網(wǎng)站發(fā)出請(qǐng)求的一種攻擊方式。主要原理為:

  • 用戶訪問了正常的網(wǎng)站A,生成Cookie
  • 攻擊者引誘用戶訪問惡意網(wǎng)站B
  • 網(wǎng)站B攜帶用戶的cookie向A網(wǎng)站發(fā)出請(qǐng)求
  • A將B當(dāng)作是用戶執(zhí)行請(qǐng)求

攻擊者在用戶不知情的情況下冒充用戶在A網(wǎng)站執(zhí)行了操作

攻擊類型

GET類型

POST類型

鏈接類型

防御方法

  • 阻止不明外域的訪問

    • 同源檢測(cè):校驗(yàn) Referer 頭
    • Samesite Cookie
  • 提交時(shí)要求附加本域才能獲取的信息

    • 驗(yàn)證Token
    • 雙重Cookie驗(yàn)證

Webgoat題解

3 Basic Get CSRF Exercise

題目的意思是在登錄Webgoat的情況下通過一個(gè)外部的源觸發(fā)請(qǐng)求,在響應(yīng)中便能拿到flag。
先點(diǎn)擊Submit Query,得到響應(yīng):

這里提示我們當(dāng)前這個(gè)請(qǐng)求是從同一個(gè)源發(fā)出的,查看headers

這里有三個(gè)屬性:

  • Host表示請(qǐng)求的目的地,包括域名和端口號(hào)
  • Origin表示請(qǐng)求是從哪發(fā)起的,包括協(xié)議、域名、端口號(hào)
  • Referer表示當(dāng)前頁(yè)面的來源完整地址,包括協(xié)議、域名、查詢參數(shù)

這里我們用burpsuite抓包后嘗試修改Origin為一個(gè)外部網(wǎng)站:

沒有成功,那么試試修改Referer

進(jìn)一步,我們直接把Referer頭去掉:

竟然也可以,看來這里的機(jī)制還是通過檢測(cè)Referer來判斷發(fā)出的請(qǐng)求是否同源。
這里有一個(gè)問題,為什么修改Origin不起作用,而修改Referer起作用了。

4 Post a review on someone else’s behalf

第4題的要求以當(dāng)前登錄WebGoat身份的用戶提交評(píng)論,這里的要求也是從外部站點(diǎn)提交:

因此我們像上一題一樣,修改Referer為外部站點(diǎn),實(shí)際上,我們這樣的直接抓包修改header是在走捷徑,正常的方式是構(gòu)造一個(gè)釣魚網(wǎng)站將執(zhí)行請(qǐng)求的鏈接寫入,并誘導(dǎo)用戶點(diǎn)擊,點(diǎn)擊時(shí)瀏覽器會(huì)自動(dòng)把cookie添加在headers中,從而達(dá)到偽造用戶身份進(jìn)行請(qǐng)求。

刷新一下則會(huì)發(fā)現(xiàn)我們的評(píng)論出現(xiàn)了,本題通過。

7 CSRF and content-type

這道題目要求從以json形式從外部提交表單,以實(shí)現(xiàn)CSRF攻擊:

因此關(guān)鍵點(diǎn)如下:

  • 以json形式提交表單數(shù)據(jù)
  • 跨域提交

這里涉及幾個(gè)知識(shí)點(diǎn)需要提前說明一下:

JSON數(shù)據(jù)

全稱為JavaScript Object Notation,是一種記錄數(shù)據(jù)的格式標(biāo)準(zhǔn),形式為key:value。比如:

{
 "name": "Ares",
 "email":"Ares@BS.com",
 "Company":"Black Swan"
}

在網(wǎng)頁(yè)中常用json格式提交表單數(shù)據(jù)。

XHR

全稱 XMLHttpRequest是一種用于與服務(wù)器進(jìn)行交互的瀏覽器API,通過XHR可以在不刷新頁(yè)面的情況下請(qǐng)求特定URL,獲取數(shù)據(jù)。在載入json數(shù)據(jù)時(shí),就需要用到 XHR對(duì)象。

CORS

全稱Cross Resource Share 跨域資源共享,是一種基于HTTP頭的機(jī)制,用于標(biāo)識(shí)出瀏覽器可以訪問哪些不同源的域、協(xié)議和端口。

CORS允許瀏覽器向跨源服務(wù)器發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。

CORS包含了一種預(yù)檢請(qǐng)求的機(jī)制,預(yù)檢的作用就是把將要發(fā)送的HTTP請(qǐng)求去掉body,只保留請(qǐng)求頭發(fā)送,以此來檢測(cè)服務(wù)器是否允許該請(qǐng)求。預(yù)檢請(qǐng)求的方法就是OPTIONS

參考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

瀏覽器將CORS請(qǐng)求分為兩類:簡(jiǎn)單請(qǐng)求與非簡(jiǎn)單請(qǐng)求

簡(jiǎn)單請(qǐng)求
滿足以下條件:

  1. 請(qǐng)求方法為以下三種:

    • HEAD
    • GET
    • POST
  2. HTTP頭信息不超出以下字段:

    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:必須為這三個(gè)值其一 application/x-www-form-urlencoded、multipart/form-datatext/plain

對(duì)于簡(jiǎn)單請(qǐng)求,瀏覽器會(huì)在請(qǐng)求頭中包含一個(gè)Origin字段,標(biāo)明此請(qǐng)求的來源,如果服務(wù)器認(rèn)為該來源不在許可的范圍內(nèi),則會(huì)返回一個(gè)不包含Access-Control-Alllow-Origin的字段,瀏覽器就會(huì)發(fā)現(xiàn)請(qǐng)求出錯(cuò)。如果請(qǐng)求來源在許可范圍內(nèi),服務(wù)器將返回包含以下字段的響應(yīng):

Access-Control-Allow-Origin: http://api.bob.com /*值為*或者Origin字段的值/
Access-Control-Allow-Credentials: true /*表示是否允許發(fā)送Cookie)
Access-Control-Expose-Headers: FooBar /*表示getResponseHeader()方法可以拿到其他字段的值
Content-Type: text/html; charset=utf-8

非簡(jiǎn)單請(qǐng)求就是不滿足上述兩個(gè)條件的其他請(qǐng)求,例如使用POST、DELETE方法,content-Typeapplication/json。

非簡(jiǎn)單請(qǐng)求在執(zhí)行正式請(qǐng)求之前會(huì)以OPTIONS方法發(fā)送一個(gè)預(yù)檢請(qǐng)求,這個(gè)預(yù)檢請(qǐng)求就是把真實(shí)的請(qǐng)求頭單獨(dú)拉出來,先進(jìn)行一次查詢,探測(cè)服務(wù)器是否允許來自當(dāng)前域名的請(qǐng)求以及可以使用哪些HTTP動(dòng)詞和頭信息字段。只有獲得服務(wù)器的允許答復(fù),瀏覽器才會(huì)發(fā)出正式的請(qǐng)求。

詳情參考:https://blog.csdn.net/yexudengzhidao/article/details/100104134

再回到這個(gè)題

我們?nèi)绻苯犹峤话?code>json數(shù)據(jù)的請(qǐng)求,是非簡(jiǎn)單請(qǐng)求,就需要經(jīng)過CORS預(yù)檢,然而CSRF是一個(gè)跨域提交的漏洞。因此這道題目有兩種場(chǎng)景:

  • 未驗(yàn)證Content-Type:在form中拼接json數(shù)據(jù)提交
  • 驗(yàn)證Content-Type

參考:https://www.secpulse.com/archives/61297.html

我們嘗試第一種方式:

構(gòu)造 POC如下:

<html>
<title>JSON CSRF PIC </title>


<form action="http://172.17.0.1:8080/WebGoat/start.mvc#lesson/CSRF.lesson/6" method="POST" enctype="text/plain" >
    <input name='{"name":"WebGoat","email":"webgoat@webgoat.org","subject":"suggestions","message":"' value='WebGoat is the best!!"}' type='hidden'>
</form>
                                                                                                                                                                   
<script>
      document.forms[0].submit();
</script>

</html>

這里的關(guān)鍵也就是上文所說的將 json拼接在input屬性中,也就是下面這行:

<input name='{"name":"WebGoat","email":"webgoat@webgoat.org","subject":"suggestions","message":"' value='WebGoat is the best!!"}' type='hidden'>

通過構(gòu)造將需要提交的json數(shù)據(jù)分為兩段,分別拼接在namevalue后的值中,交由瀏覽器解析即可。解析結(jié)果如下:

瀏覽器解析結(jié)果

可以看到message中的值多了一個(gè)=,這是因?yàn)闉g覽器在解析input中的值時(shí),會(huì)自動(dòng)以name=value形式補(bǔ)全:

name=value

就算不寫value的值,瀏覽器依然會(huì)自動(dòng)不全=

name=

這就是為什么如果只將json放在name里,不寫value值的話,json數(shù)據(jù)末尾會(huì)多一個(gè)=,自然也就無法解析成功了。

按道理來說將構(gòu)造的html文件從瀏覽器打開就應(yīng)該已經(jīng)成功了,但我卻收到了如下響應(yīng):

405

對(duì)比一下從網(wǎng)頁(yè)正常提交的請(qǐng)求頭

請(qǐng)求頭錯(cuò)誤

修改為:

修改請(qǐng)求頭

就可以拿到flag啦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • CSRF & CORS 下面轉(zhuǎn)的兩篇文章分別說明了以下兩個(gè)概念和一些解決方法: 1. CSRF - Cross-S...
    Elvis_zhou閱讀 844評(píng)論 0 4
  • 一、HTTP協(xié)議的主要特點(diǎn) 簡(jiǎn)單快速:每個(gè)資源URI都是固定的 靈活:頭部有數(shù)據(jù)類型,可以完成不同類型傳輸 無連接...
    番茄沙司a閱讀 951評(píng)論 0 5
  • 6.2.2 其他邏輯實(shí)現(xiàn) 1. 實(shí)現(xiàn)ajax接口和渲染數(shù)據(jù) 2. 使用multer處理文件上傳 npm insta...
    小五同學(xué)H閱讀 347評(píng)論 0 0
  • 背景 跨域這個(gè)問題前端開發(fā)者都接觸過,網(wǎng)上的文章也非常多,但是昨天的騰訊二面給我留了非常深刻的印象,原來跨域能問出...
    流動(dòng)碼文閱讀 880評(píng)論 1 1
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,856評(píng)論 28 54

友情鏈接更多精彩內(nèi)容