Anti CSRF

Iniciado por Destructor.cs, Mayo 01, 2013, 10:14:15 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Mayo 01, 2013, 10:14:15 PM Ultima modificación: Marzo 27, 2014, 05:32:05 PM por Expermicid
Bueno, aqui les traigo una manera muy facil de evitar ataques CSRF con la utilización de los llamados "tokens" en PHP!
El formulario donde se crea y se envia el token seria el siguiente:
Código: php

<html>
   <head><title>Formulario</title></head>
   <body>
        <?php> $_SESSION["token"] = md5(uniqid(mt_rand(), true));  //creamos el token aleatoriamente y lo guardamos en la sesión
        echo '<form name="formulario" action="receptor.php?token=' . $_SESSION["token"] . '" method="post">' ?> //abrimos la etiqueta form, le damos un name, le ponemos que enviaremos los datos por post, y aprovechamos para mandar el token por GET
                 <input type="text" value="Ingrese algo" name="dato">
        </form>
   </body>
</html>


Con ese codigo ademas de enviar el dato del campo por POST, creamos un token el cual guardamos en la sesion, y el mismo token lo usamos para enviarlo por GET. En la siguiente pagina, comprobaremos el token recibido por GET con el token guardado en la sesion, ademas recibiremos lo que nos envio e imprimiremos el dato recibido en pantalla:

Código: php

<html>
   <head> <title> Receptor </title> </head>
   <body>
        <?php
             $dato = $_POST["dato"];
             $token1 = $_GET["token"];
             $token2 = $_SESSION["token"];
             if ($token1 == $token2){
                    echo $dato;
             }else{
                    echo '¿Que intentas hacer?';
            }
       ?>
   </body>
</html>

El sistema tiene 2 vulnerabilidades.

Es posible obtener el token:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Y es posible hacerle un bypass al sistema.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Mi madre me dijo que estoy destinado a ser pobre toda la vida.
Engineering is the art of balancing the benefits and drawbacks of any approach.

Segun lo que pude leer de lo que me dejaste, la primera solo te daria la opcion de robar el token, de igual manera no tendrias utilidad, ya que el token que viene por GET se compara por el de la sesion y tu no puedes editar la sesion. Eso es lo que entendi de la primera vulnerabilidad. Ademas agrego que puedes cifrar con diferentes claves cada token y decifrar cada uno cuando los vayas a comparar, de esa manera aunque consigas un token cifrado, el otro no seria igual.
Sobre la segunda vulnerabilidad no tenia muchas ganas de leer en ingles, asique si me la quieres explicar por aqui mejor! Por las dudas te digo que ese codigo es un anti csrf basico, solo se encarga de ver como funciona, imaginate que con el simple echo de editar el get podrias hacer una inyeccion, pero cree el codigo para centrarme solamente en el uso basico de tokens

Por mas básico que alguien plante un sistema de seguridad, no significa que deba ser vulnerable.

El robo del token no es para saber el contenido del token. Es para realizar un bypass cuando se realiza el CSRF. Ha habido muchísimas vulnerabilidades en los diferentes CMS incluyendo SMF, que utilizan esa técnica para realizar un bypass. Tendrias que investigar y quizás luego testear para entender bien como explotar esta vulnerabilidad utilizando el token.

El segundo link que te deje, abre directamente un comentario mio, donde se explica como se da la vulnerabilidad y esta en español la explicación. Aunque esta es un poco compleja de entender que la primera.

Y el problema se da en la forma de implementacion, de hay salen muchísimos bypass.

Saludos.
Mi madre me dijo que estoy destinado a ser pobre toda la vida.
Engineering is the art of balancing the benefits and drawbacks of any approach.

Vuelvo a decir que era para mostrar un CSRF basico, ademas la primer vulnerabilidad dice claramente:

"Este ataque en principio afectaría a todo tipo de web, blog, foro, etc que dejara postear tags tipo <img> o el BBcode [img], ya que en el caso de un foro por ejemplo, podríamos ponernos una firma que apuntase a nuestro robador de sesiones...."

Adiero que esta vulnerabilidad sirve para cuando se envian los identificadores por GET, en casos asi, se podria enviar por post y un input type="hidden" y tambien podria servir!

Acabo de intentar abrir la otra vulnerabilidad y me aparece un error en la web, en un rato pruebo otra vez

Mayo 04, 2013, 12:15:04 AM #5 Ultima modificación: Mayo 04, 2013, 12:17:36 AM por ~ Yoya ~
Por mas basico que sea, no por eso significa que sea vulnerable. Y si el PoC que haz mostrado, es vulnerable y no es conveniente que se exponga como un sistema de seguridad. Y desde ahora, te digo que cuando se expone alguna sistema para prevenir alguna vulnerabilidad, lo que se suele exponer es un PoC, ya que el objetivo no es mostrar que el sistema funciona, sino demostrar como funciona el sistema para prevenir la vulnerabilidad y no puedes exponerlo con vulnerabilidades conocidas.

Por lo menos ya has reconocido que es vulnerable y es un gran paso. Lo que si te digo que no es bueno argumentar basándote en lo que escribe un tercero, es mejor conocer realmente como funciona el sistema. Y no tiene que postear img, puede ser con el mismo avatar e incluso en algunos caso quizás no sea necesario utilizar una img, si conoces bien el sistema, conoces como funciona la vulnerabilidad, puedes crear un nuevo vector de ataque basandote en otros.

Y sobre pasar el token vía POST puede funcionar pero no es una buena idea. O en cada petición que realice el usuario sera POST?? cuando vaya hacer click en algún link dentro del foro, sera una petición POST... Por ejemplo si el usuario quiere desloguearse, lo ideal seria que haga click para desloguearse, que seria una peticion GET y en ese caso tendrias que pasar el token via GET, pero tranquilo hay una buena forma de evitar CSRF.

También seria correcto, alguna solución, argumentes con un PoC que hayas creado, así los demás entienden mejor y aprenden.

Saludos.
Mi madre me dijo que estoy destinado a ser pobre toda la vida.
Engineering is the art of balancing the benefits and drawbacks of any approach.

Mayo 04, 2013, 12:08:56 PM #6 Ultima modificación: Marzo 27, 2014, 05:32:22 PM por Expermicid
Entiendo lo que dices que por mas basico que sea no tiene por que tener una vulnerabilidad, pero es el echo de mostrar el funcionamiento BASICO de un token, obviamente segun tu pagina web puede tener diferentes vulnerabilidades y para eso lo tienes que ir adaptando a sistema! Pero te recuerdo que es BASICO!

CREO que acabo de entender la vunlerabilidad, osea, lo que tu quisieras hacer es robarle los tokens de otros, para asi hacerle un bypass haciendo que entre al siguiente enlace: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta aqui el token que tu le robaste!

Si es asi la vunlerabilidad te digo que no funcionaria, por el simple echo de que se implementa este sistema en todas las paginas, haciendo que el token se cambie constantemente, te doy el siguiente ejemplo, aqui se crea un token y se envia a un lugar

Código: php
<html>
   <head><title>Formulario</title></head>
   <body>
        <?php> $_SESSION["token"] = md5(uniqid(mt_rand(), true));  //creamos el token aleatoriamente y lo guardamos en la sesión
        echo '<form name="formulario" action="receptor.php?token=' . $_SESSION["token"] . '" method="post">' ?> //abrimos la etiqueta form, le damos un name, le ponemos que enviaremos los datos por post, y aprovechamos para mandar el token por GET
                 <input type="text" value="Ingrese algo" name="dato">
        </form>
   </body>
</html>


aqui se recibe y es donde tu tienes tu imagen para robarle el token! y ademas de eso, se vuelve a reenviar a otra pagina
Código: php
<html>
   <head> <title> Receptor </title> </head>
   <body>
        <?php
             $dato = $_POST["dato"];
             $token1 = $_GET["token"];
             $token2 = $_SESSION["token"];
             if ($token1 == $token2){
                    $_SESSION["token"] = md5(uniqid(mt_rand(), true));
                    header ('Location: Pagina.php?token=' . $_SESSION["token"] . '');
             }else{
                    echo '¿Que intentas hacer?';
            }
       ?>
   </body>
</html>


De esta manera, aunque consigas el token que ya usaron, no te servira de nada, porque para cada accion se cambia de token y tu siempre iras un paso atras!

Que bien que hayaz pensado, sip una de la soluciones es actualizar el token. Me alegro que hayas entendido.

Pero lo que me parece mal es que sigas insistiendo que por ser basico, sea vulnerable pero es tu opinion y la respeto.

En seguridad web, saber programacion y tener un buen nivel de programacion es indispensable, en mi opinion. Espero algun dia llevarme una sorpresita de ti, ya sea publicando un bug de algun famoso cms o algun nuevo vector de ataque.

Saludos.
Mi madre me dijo que estoy destinado a ser pobre toda la vida.
Engineering is the art of balancing the benefits and drawbacks of any approach.

Es que esa era la idea principal, error mio al no explicar todas las caracteristicas, me disculpo!

Esta bien al igual que yo entiendo tu postura!

Lo dudo, aunque aprendo lo basico del hacking y me gusta a veces hacer algun ejercicio para abrir la cabeza, me voy mas por la programacion web y eso es lo que me gusta!

Saludos!

La mejor forma descubierta mundialmente para prevenir el CSRF es enviando un token dinámico junto a la petición post y no get, eso es todo, no hay para que calentarse la cabeza con otras cosas, luego verificas que la petición post tenga dicho token o si no se rechaza y listo, y si el token va en la urlo a traves de una petición GET el resultado en HTML no debe contener ningún recurso externo que pueda revelar dicho token a traves de una referencia, o si no se debe hacer una redirección hacia otra url sin token tal como lo hace vbulletín.

Como lo hace vbulletín?: Creando una página avisando con una redirección.
Como lo hace SMF?: Creando una redirección a traves de las cabeceras http.
Como lo hace Joomla?: En el panel de administración todas los botones son POST, nada de enlaces ni peticiones GET.
Como lo hace Wordpress?: Envía el token en peticiones POST y GET teniendo cuidado de no incluir recursos externos en dichas peticiones.
Como lo hago yo?: igual que Wordpress.
- No tienes permitido ver los links. Registrarse o Entrar a mi cuenta - No tienes permitido ver los links. Registrarse o Entrar a mi cuenta