sábado, 15 de octubre de 2016

Creando URLs con CSRF implícito

Resultado de imagen de csrf

Autor: Samuel Lopez Saura

CSRF son las siglas de Cross Site Request Forgery. Esto es una técnica a través de la cual un usuario víctima realiza determinadas acciones programadas sin ser consciente de ello.

Imaginémonos el siguiente escenario.

El usuario A es administrador del sitio web empresadeejemplo.com

Dentro de empresadeejemplo.com puede realizar las siguientes acciones.

  Ver empleados de la empresa
  Ver  nómina de un empleado
  Subir sueldo a un empleado
  Ver mi sueldo
  Mi historial

El sitio web empresadeejemplo.com tiene un mecanismo de sesiones y solo permite que el usuario admin realice las acciones marcadas en rojo.


Para subir el sueldo de un empleado se encuentra con el siguiente escenario.


El usuario administrador elige un usuario, la cantidad a subir su sueldo y al darle a enviar genera una URL tal que

http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=100

Dentro de la petición HTTP se manda la Cookie de sesión del administrador. La aplicación comprobará que la cookie de sesión es válida y que pertenece a un usuario con privilegios administrativos.

Dentro del código de la aplicación habrá algo parecido a esto:

$usuario = $_REQUEST[‘usuario’];
$aumento = $_REQUEST[‘aumento’];

→ si el usuario al que corresponde la sesión es admin
        subir_sueldo($usuario, $cantidad);
        header(‘Location: /admin’); /* Redirigimos al panel de administración */

→  si el usuario al que corresponde la sesión no es admin
        header(‘Location: /’);  /* Redirigimos a la raíz del sitio */

La aplicación funcionaría y en principio un usuario que no fuera admin no podría realizar la acción.

La pregunta es, ¿qué pasaría si admin hiciera clic en http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=9000 sin ser consciente de ello?

Su navegador realizaría una petición GET  y mandaría su cookie de sesión el servidor comprobaría que realmente es admin quién está realizando la acción y subiría en 9000€ el sueldo al empleado juan ejemplo perez.

Pero ¿cómo va a hacer clic en eso el administrador? Volvamos atrás, cuando hacemos clic emitimos una petición GET al servidor y esta la procesa. Esta petición también la realizamos cuando, por ejemplo, cargamos una imagen. Entonces si el usuario administrador visitara un sitio web que cargase esa URL su navegador emitiría una petición GET al servidor como si el propio administrador conscientemente hiciera la petición.

– Una imagen dice más de mil palabras


Además, ¿y si los datos se pasaran por el método POST en lugar de por el método GET?
Desde PHP podemos recibir parámetros con $_GET, $_POST, $_REQUEST. El primero contiene un array asociativo con los datos mandados por el método GET. El segundo por el método POST y el tercero por cualquiera de los dos métodos.

La utilización de $_REQUEST es una práctica muy común y sin una validación adecuada podemos enviar en un método GET parámetros que el servidor procesaría como si fuera un método POST para un campo que se espera ser recibido solo por POST. Es decir, en una URL podríamos simular un “POST” implícito en ella si al recibir el parámetro lo recibiéramos mediante $_REQUEST.


junto a un método POST los parámetros de usuario y aumento.


Si el documento PHP tuviese en cuenta por donde vienen los datos. Utilizando $_POST o $_GET en lugar de la opción genérica $_REQUEST. Y la acción fuera dada por el método POST habría que simular el envío de un formulario con esos valores al servidor pero el mecanismo sería muy similar a la opción de la imagen con la excepción de que sería un código javascript quién realizase la petición POST o activase el envío de un formulario.

La tarde del miércoles creé una micro aplicación que bajo un fin educativo automatizaba este proceso.



Arriba a la derecha tenemos un botón que pone Nueva URL. Esto levantará una ventana donde podremos poner los parámetros.



Lo que nos genera una URL como la siguiente:

Cuando copiemos la URL y la peguemos en la barra del navegador nos encontraremos con esto:


Lo que está pasando en realidad es lo siguiente:

  Se accede a http://cj.curiosoinformatico.com, lo primero en cargar es un script que comprueba si tenemos parámetros en la URL que nos indiquen a donde redirigir y donde hacer clic.
  De tenerlos carga el sitio que hemos escogido para hacer clic como una imagen nada sospechosa y cambia la URL del documento al sitio destino.
  No obstante como la URL es un poco sospechosa podemos usar un acortador de enlaces como bit.ly para hacerla más confiable.

¡Magia! Esta poderosa URL subirá nuestro sueldo en 9000 euros sin que nadie se entere y le informará a nuestro jefe de un evento donde aprender y mejorar su seguridad. http://bit.ly/2ea3VFM



Nota del autor: Actualmente la página no tiene soporte para peticiones POST -si tiene para GET y para los POST que recoja PHP a través de $_REQUEST (que en realidad se envían como GET)-. Imagino que en un hueco libre que tenga se lo pondré pero si alguien quiere adelantarse aquí dejo el github del mismo.

https://github.com/curiosoinformatico/two_steps_redirector 


******************* ACTUALIZACIÓN *********************

Tras publicar este articulo Vicente Aguilera Diaz se puso en contacto con nosotros y nos indico varios interesantes enlaces de sus publicaciones sobre CSRF y redes sociales, aquí podéis consultarlos:

Caso Facebook: http://www.isecauditors.com/advisories-2011#2011-002

Caso Linkedin: http://seclists.org/fulldisclosure/2013/Mar/216

Caso Gmail: http://www.securiteam.com/securitynews/5ZP010UQKK.html



Muchas gracias Vicente.







No hay comentarios:

Publicar un comentario