Contribución de Francisco Losada, asistente de la última edición del SEC-560 que impartí el pasado año y buen amigo, en la que nos va a contar con detalle en que consisten las vulnerabilidades de Cross-Site Request Forgery:
Los ataques CSRF o XSRF son uno de los principales vectores de ataque a los que se enfrentan las empresas en sus aplicaciones web según OWASP. Tanto aquellas aplicaciones que son públicamente accesibles a través de Internet como las que se encuentran en una intranet restringida a un número reservado de usuarios pueden ser vulnerables.
Los ataques CSRF o XSRF son uno de los principales vectores de ataque a los que se enfrentan las empresas en sus aplicaciones web según OWASP. Tanto aquellas aplicaciones que son públicamente accesibles a través de Internet como las que se encuentran en una intranet restringida a un número reservado de usuarios pueden ser vulnerables.
El objetivo de este tipo de ataques consiste en conseguir que el navegador de una víctima lleve a cabo una acción en una aplicación web en la que la víctima se encuentra autenticada. Para conseguir que el navegador realice la acción deseada se suele hacer uso de código HTML que puede ser inyectado en alguna página web a la que la víctima accede libremente o redirigida a través de algún tipo de enlace. El esquema básico de este tipo de ataques podría ser similar al siguiente.
0- En un primer momento, el atacante logra introducir el código HTML en una aplicación del servidor A.
1- La víctima establece una conexión legítima con una aplicación web del servidor B.
2- La víctima accede a la aplicación web en la que se encuentra el código introducido por el atacante.
3- El navegador de la víctima realiza una petición contra la aplicación del servidor B sin que el usuario se percate.
En este caso, A y B están representados como dos aplicaciones diferentes; en el caso que explicaremos más adelante A y B serán la misma aplicación, sin embargo, este escenario podría representar a la aplicación A como una aplicación publicada en Internet y a la aplicación B como una aplicación dentro de la intranet de una empresa. Los límites los pone la imaginación.
1- La víctima establece una conexión legítima con una aplicación web del servidor B.
2- La víctima accede a la aplicación web en la que se encuentra el código introducido por el atacante.
3- El navegador de la víctima realiza una petición contra la aplicación del servidor B sin que el usuario se percate.
En este caso, A y B están representados como dos aplicaciones diferentes; en el caso que explicaremos más adelante A y B serán la misma aplicación, sin embargo, este escenario podría representar a la aplicación A como una aplicación publicada en Internet y a la aplicación B como una aplicación dentro de la intranet de una empresa. Los límites los pone la imaginación.
Las acciones que se pueden llevar a cabo a través de estos ataques dependen de la aplicación vulnerable. OWASP ofrece en su página el OWASP Broken Web Applications Project que proporciona un entorno vulnerable a la mayoría de los ataques contra aplicaciones web. En este caso mostraremos un ejemplo con una antigua versión de Yazd Discussion Forum que nos servirá para mostrar cómo llevar a cabo un ataque CSRF.
Un usuario accede de forma anónima al foro en el que se muestra la lista de hilos publicados junto con el autor del mismo. En este caso, vemos que existe un usuario "Admin".
Navegando a través de los mensajes, se puede ver cómo algunos usuarios pueden tener visible la cuenta de correo asociada a su usuario. Este dato no será de utilidad para este caso pero podría ser empleado en un caso real para llevar a cabo el ataque de una forma más elegante.
Lo primero que se necesita para llevar a cabo un ataque de tipo CSRF es conocer de qué forma se realizan las peticiones en las páginas que envían información sensible. Para conocer el entorno más en profundidad crearemos un usuario en la aplicación.
En muchas ocasiones es posible conseguir crear un usuario mediante CSRF, en este caso carece de interés ya que cualquier usuario puede registrarse libremente. Si nos vamos a la parte que nos permite gestionar nuestra cuenta, podemos probar a realizar un cambio y ver de qué forma se realiza la petición contra el servidor. En este caso actualizaremos la contraseña de nuestro usuario.
Si analizamos la petición con un proxy podemos ver los campos que se envían y comprobar que ninguno de ellos tiene pinta de generarse de forma aleatoria para cada petición. Aquí tenemos nuestra vulnerabilidad. ¿Qué ocurriría si consiguiésemos qué el usuario "Admin" enviase esa petición desde su navegador pero con los datos que nosotros quisiéramos?
Cuando existen páginas que permiten enviar contenidos al servidor como es el caso de los foros o los blogs, se suele hacer uso de etiquetas HTML ligeramente modificadas para que realicen la petición cuando un usuario las visualiza. Así, si se publica un mensaje el el foro con una etiqueta de imagen cuyo campo apunte a la URL que visualizamos en nuestro proxy lograremos que cuando el usuario la visualice, ejecute involuntariamente la petición.
A simple vista, el nuevo mensaje enviado por nuestro usuario anónimo parece una imagen cuyo enlace está roto y no puede mostrar el contenido.
Sin embargo, cuando nuestro usuario "Admin" acceda al nuevo hilo del foro y su navegador trate de cargar la imagen, lanzará una petición a http://owaspbwa/yazd/bay/account.jsp?
mode=2&doCreate=true&username=Admin&password=admin123&password2=admin123&
email=usuario%40pollo.com&name=user&URL=&signature=&nameVisible=on&emailVisible=on
mode=2&doCreate=true&username=Admin&password=admin123&password2=admin123&
email=usuario%40pollo.com&name=user&URL=&signature=&nameVisible=on&emailVisible=on
Puesto que el usuario no recibe ningún tipo de mensaje de confirmación ni debe realizar ningún tipo de validación, no sabrá que sus datos han sido modificados. En este ejemplo podría ver lo sucedido accediendo a la página de configuración de su cuenta y vería que su dirección de correo ha cambiado, pero si hubiéramos puesto la dirección real -que obtuvimos situando el ratón sobre su nombre- no sería consciente de lo sucedido hasta tratase de volver a identificarse tras cerrar la sesión.
Además del cambio de contraseña, y en función del tipo de aplicación, podría llevarse a cabo la creación de usuarios, la compra de artículos e, incluso, se podrían llegar a realizar transferencias bancarias -como ocurrió en el pasado- si no se dispone de los mecanismos adecuados que validen operaciones del tipo:
https://www.banco-xx.com/transferencia.php?cuenta=692&importe=1000
Como se puede ver en este último supuesto, este tipo de ataque también funcionaría a través de conexiones HTTPS. Dado que el usuario debe estar autenticado con anterioridad en la aplicación vulnerable, el navegador hará uso de la cookie creada previamente, cuando se estableció la conexión.
Existen varios métodos para evitar este tipo de problemática. Los captchas y la doble autenticación del usuario son dos opciones válidas pero que repercuten en la usabilidad de la aplicación y obligan a que el usuario tenga que introducir los caracteres para validar el captcha o introducir sus credenciales. El método preferido es usar un token aleatorio y único para cada petición. Este token se crea y se valida automáticamente sin la intervención del usuario. Si nos fijamos en el formulario para la creación de una cuenta en Facebook podemos ver que existe un campo oculto que envía este token en la petición:
En el caso de Linkedin podemos ver que también se utiliza un token único para cada petición y, en este caso, el campo tiene incluso un nombre mucho más descriptivo:
Al analizar una petición de cambio de contraseña en Gmail, vemos que también utiliza también los token para evitar los cambios de contraseña a través de CSRF:
Otras posibles recomendaciones a nivel de usuario para evitar estos ataques son:
- Cerrar la sesión cuando ya no se vaya a hacer uso de la aplicación.
- No permitir al navegador que recuerde usuarios y contraseñas.
- No utilizar la funcionalidad de las aplicaciones web que permiten mantener la sesión abierta.
- Utilizar diferentes navegadores, uno para aquellas aplicaciones que traten información sensible y otro para navegación en general.
- Utilizar complementos que bloqueen la ejecución de scripts. De esta forma los formularios que se envíen por POST no podrán ser enviados automáticamente sin el consentimiento del usuario.
No hay comentarios :
Publicar un comentario