Cache Poisoning and Cache Deception
Last updated
Last updated
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Usa Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
¿Cuál es la diferencia entre el envenenamiento de caché web y la decepción de caché web?
En el envenenamiento de caché web, el atacante hace que la aplicación almacene contenido malicioso en la caché, y este contenido se sirve desde la caché a otros usuarios de la aplicación.
En la decepción de caché web, el atacante hace que la aplicación almacene contenido sensible perteneciente a otro usuario en la caché, y luego el atacante recupera este contenido de la caché.
El envenenamiento de caché tiene como objetivo manipular la caché del lado del cliente para obligar a los clientes a cargar recursos que son inesperados, parciales o controlados por un atacante. La magnitud del impacto depende de la popularidad de la página afectada, ya que la respuesta contaminada se sirve exclusivamente a los usuarios que visitan la página durante el período de contaminación de la caché.
La ejecución de un ataque de envenenamiento de caché implica varios pasos:
Identificación de Entradas Sin Clave: Estos son parámetros que, aunque no son necesarios para que una solicitud sea almacenada en caché, pueden alterar la respuesta devuelta por el servidor. Identificar estas entradas es crucial, ya que pueden ser explotadas para manipular la caché.
Explotación de las Entradas Sin Clave: Después de identificar las entradas sin clave, el siguiente paso implica averiguar cómo abusar de estos parámetros para modificar la respuesta del servidor de una manera que beneficie al atacante.
Asegurar que la Respuesta Envenenada esté Almacenada en Caché: El paso final es asegurarse de que la respuesta manipulada esté almacenada en la caché. De esta manera, cualquier usuario que acceda a la página afectada mientras la caché esté envenenada recibirá la respuesta contaminada.
Por lo general, cuando una respuesta fue almacenada en la caché, habrá un encabezado que lo indique, puedes verificar qué encabezados debes tener en cuenta en esta publicación: Encabezados de caché HTTP.
Si estás pensando que la respuesta se está almacenando en una caché, podrías intentar enviar solicitudes con un encabezado incorrecto, que debería ser respondido con un código de estado 400. Luego intenta acceder a la solicitud normalmente y si la respuesta es un código de estado 400, sabes que es vulnerable (y podrías incluso realizar un DoS).
Puedes encontrar más opciones en:
Sin embargo, ten en cuenta que a veces estos tipos de códigos de estado no se almacenan en caché, por lo que esta prueba podría no ser confiable.
Podrías usar Param Miner para fuerza bruta de parámetros y encabezados que pueden estar cambiando la respuesta de la página. Por ejemplo, una página puede estar usando el encabezado X-Forwarded-For
para indicar al cliente que cargue el script desde allí:
Con el parámetro/cabecera identificado, verifica cómo está siendo sanitizado y dónde se está reflejando o afectando la respuesta de la cabecera. ¿Puedes abusar de ello de alguna manera (realizar un XSS o cargar un código JS controlado por ti? ¿realizar un DoS?...)
Una vez que hayas identificado la página que puede ser abusada, qué parámetro/cabecera usar y cómo abusar de ello, necesitas hacer que la página se almacene en caché. Dependiendo del recurso que estés tratando de almacenar en caché, esto podría tomar algún tiempo, podrías necesitar intentarlo durante varios segundos.
La cabecera X-Cache
en la respuesta podría ser muy útil ya que puede tener el valor miss
cuando la solicitud no fue almacenada en caché y el valor hit
cuando está en caché.
La cabecera Cache-Control
también es interesante para saber si un recurso está siendo almacenado en caché y cuándo será la próxima vez que el recurso será almacenado en caché nuevamente: Cache-Control: public, max-age=1800
Otra cabecera interesante es Vary
. Esta cabecera se utiliza a menudo para indicar cabeceras adicionales que se tratan como parte de la clave de caché incluso si normalmente no están indexadas. Por lo tanto, si el usuario conoce el User-Agent
de la víctima que está atacando, puede envenenar la caché para los usuarios que utilizan ese User-Agent
específico.
Una cabecera más relacionada con la caché es Age
. Define el tiempo en segundos que el objeto ha estado en la caché del proxy.
Al almacenar en caché una solicitud, ten cuidado con las cabeceras que usas porque algunas de ellas podrían ser usadas inesperadamente como indexadas y la víctima necesitará usar esa misma cabecera. Siempre prueba un Cache Poisoning con diferentes navegadores para verificar si está funcionando.
Una cabecera como X-Forwarded-For
se está reflejando en la respuesta sin sanitizar.
Puedes enviar una carga útil básica de XSS y envenenar la caché para que todos los que accedan a la página sean XSSed:
Note que esto envenenará una solicitud a /en?region=uk
no a /en
Las cookies también podrían reflejarse en la respuesta de una página. Si puedes abusar de esto para causar un XSS, por ejemplo, podrías ser capaz de explotar XSS en varios clientes que cargan la respuesta de caché maliciosa.
Note que si la cookie vulnerable es muy utilizada por los usuarios, las solicitudes regulares estarán limpiando la caché.
Verifique:
Este informe explica cómo fue posible robar una clave de API de OpenAI con una URL como https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
porque cualquier cosa que coincida con /share/*
será almacenada en caché sin que Cloudflare normalice la URL, lo cual se hizo cuando la solicitud llegó al servidor web.
Esto también se explica mejor en:
A veces necesitarás explotar varias entradas sin clave para poder abusar de una caché. Por ejemplo, puedes encontrar un redireccionamiento abierto si configuras X-Forwarded-Host
a un dominio controlado por ti y X-Forwarded-Scheme
a http
. Si el servidor está reenviando todas las solicitudes HTTP a HTTPS y usando el encabezado X-Forwarded-Scheme
como el nombre de dominio para el redireccionamiento. Puedes controlar hacia dónde apunta la página por el redireccionamiento.
Vary
limitadoSi descubres que el X-Host
se está utilizando como nombre de dominio para cargar un recurso JS pero el encabezado Vary
en la respuesta indica User-Agent
. Entonces, necesitas encontrar una manera de exfiltrar el User-Agent de la víctima y envenenar la caché utilizando ese user agent:
Envía una solicitud GET con la solicitud en la URL y en el cuerpo. Si el servidor web utiliza la del cuerpo pero el servidor de caché almacena en caché la de la URL, cualquier persona que acceda a esa URL utilizará en realidad el parámetro del cuerpo. Como la vulnerabilidad que James Kettle encontró en el sitio web de Github:
There it a portswigger lab about this: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
Por ejemplo, es posible separar parámetros en servidores ruby usando el carácter ;
en lugar de &
. Esto podría usarse para poner valores de parámetros no clave dentro de los clave y abusar de ellos.
Portswigger lab: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking
Aprende aquí cómo realizar ataques de Cache Poisoning abusando de HTTP Request Smuggling.
El Escáner de Vulnerabilidades de Cache Web se puede usar para probar automáticamente la intoxicación de caché web. Soporta muchas técnicas diferentes y es altamente personalizable.
Ejemplo de uso: wcvs -u example.com
ATS reenvió el fragmento dentro de la URL sin eliminarlo y generó la clave de caché solo usando el host, la ruta y la consulta (ignorando el fragmento). Así que la solicitud /#/../?r=javascript:alert(1)
se envió al backend como /#/../?r=javascript:alert(1)
y la clave de caché no tenía la carga útil dentro de ella, solo host, ruta y consulta.
Enviar un valor incorrecto en el encabezado content-type activó una respuesta 405 en caché. La clave de caché contenía la cookie, por lo que solo era posible atacar a usuarios no autenticados.
GitLab utiliza buckets de GCP para almacenar contenido estático. Los Buckets de GCP soportan el encabezado x-http-method-override
. Por lo tanto, era posible enviar el encabezado x-http-method-override: HEAD
y envenenar la caché para que devolviera un cuerpo de respuesta vacío. También podría soportar el método PURGE
.
En aplicaciones Ruby on Rails, a menudo se utiliza middleware Rack. El propósito del código Rack es tomar el valor del encabezado x-forwarded-scheme
y establecerlo como el esquema de la solicitud. Cuando se envía el encabezado x-forwarded-scheme: http
, ocurre una redirección 301 a la misma ubicación, lo que puede causar una Denegación de Servicio (DoS) a ese recurso. Además, la aplicación podría reconocer el encabezado X-forwarded-host
y redirigir a los usuarios al host especificado. Este comportamiento puede llevar a la carga de archivos JavaScript desde el servidor de un atacante, lo que representa un riesgo de seguridad.
Cloudflare anteriormente almacenaba en caché respuestas 403. Intentar acceder a S3 o Azure Storage Blobs con encabezados de autorización incorrectos resultaría en una respuesta 403 que se almacenó en caché. Aunque Cloudflare ha dejado de almacenar en caché respuestas 403, este comportamiento podría seguir presente en otros servicios de proxy.
Las cachés a menudo incluyen parámetros GET específicos en la clave de caché. Por ejemplo, el Varnish de Fastly almacenaba en caché el parámetro size
en las solicitudes. Sin embargo, si se enviaba una versión codificada en URL del parámetro (por ejemplo, siz%65
) con un valor erróneo, la clave de caché se construiría usando el parámetro size
correcto. Sin embargo, el backend procesaría el valor en el parámetro codificado en URL. Codificar en URL el segundo parámetro size
llevó a su omisión por parte de la caché, pero su utilización por parte del backend. Asignar un valor de 0 a este parámetro resultó en un error 400 Bad Request que se podía almacenar en caché.
Algunos desarrolladores bloquean solicitudes con user-agents que coinciden con los de herramientas de alto tráfico como FFUF o Nuclei para gestionar la carga del servidor. Irónicamente, este enfoque puede introducir vulnerabilidades como la intoxicación de caché y DoS.
El RFC7230 especifica los caracteres aceptables en los nombres de encabezados. Los encabezados que contienen caracteres fuera del rango tchar especificado deberían idealmente activar una respuesta 400 Bad Request. En la práctica, los servidores no siempre se adhieren a este estándar. Un ejemplo notable es Akamai, que reenvía encabezados con caracteres no válidos y almacena en caché cualquier error 400, siempre que el encabezado cache-control
no esté presente. Se identificó un patrón explotable donde enviar un encabezado con un carácter ilegal, como \
, resultaría en un error 400 Bad Request que se podía almacenar en caché.
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
El objetivo de la Decepción de Caché es hacer que los clientes carguen recursos que van a ser guardados por la caché con su información sensible.
Primero, ten en cuenta que extensiones como .css
, .js
, .png
, etc., suelen estar configuradas para ser guardadas en la caché. Por lo tanto, si accedes a www.example.com/profile.php/nonexistent.js
, la caché probablemente almacenará la respuesta porque ve la extensión .js
. Pero, si la aplicación está reproduciendo con los contenidos sensibles del usuario almacenados en www.example.com/profile.php, puedes robar esos contenidos de otros usuarios.
Otras cosas para probar:
www.example.com/profile.php/.js
www.example.com/profile.php/.css
www.example.com/profile.php/test.js
www.example.com/profile.php/../test.js
www.example.com/profile.php/%2e%2e/test.js
Usa extensiones menos conocidas como .avif
Otro ejemplo muy claro se puede encontrar en este informe: https://hackerone.com/reports/593712. En el ejemplo, se explica que si cargas una página inexistente como http://www.example.com/home.php/non-existent.css, el contenido de http://www.example.com/home.php (con la información sensible del usuario) se devolverá y el servidor de caché guardará el resultado. Luego, el atacante puede acceder a http://www.example.com/home.php/non-existent.css en su propio navegador y observar la información confidencial de los usuarios que accedieron antes.
Ten en cuenta que el proxy de caché debe estar configurado para almacenar en caché archivos basados en la extensión del archivo (.css) y no basarse en el tipo de contenido. En el ejemplo http://www.example.com/home.php/non-existent.css tendrá un tipo de contenido text/html
en lugar de un tipo MIME text/css
(que es el esperado para un archivo .css).
Aprende aquí cómo realizar ataques de Decepción de Caché abusando de HTTP Request Smuggling.
toxicache: Escáner de Golang para encontrar vulnerabilidades de intoxicación de caché web en una lista de URLs y probar múltiples técnicas de inyección.
Usa Trickest para construir y automatizar flujos de trabajo fácilmente impulsados por las herramientas más avanzadas de la comunidad. Obtén acceso hoy:
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)