|
Bueno, en este paper vamos a hablar sobre lo que es CSRF / XSRF [ Cross Site Request Forgery ] .
Intentare explicar todo lo posible sobre esta vulnerabilidad y lo mas importante .. Como prevenir estos ataques.
Empezemos .. =)
Cross Site Request Forgery [ CSRF / XSRF ] Autor: Tec-n0x ;) Fecha: 03/4/2008 Www.Editcodex.NET Contacto: Tec-n0x [ at ] hotmail [ dot ] com
======================================
[ + ] Indice [ + ]
= > 0x001 Introducción = > 0x002 Como funciona el CSRF / Pequeño ejemplo = > 0x003 Codeando una Aplicación Vulnerable = > 0x004 Evitando el CSRF = > 0x005 Despedida
======================================
[ + ] Introducción [ + ]
Bueno, en este paper vamos a hablar sobre lo que es CSRF / XSRF [ Cross Site Request Forgery ] .
Intentare explicar todo lo posible sobre esta vulnerabilidad y lo mas importante .. Como prevenir estos ataques.
Empezemos .. =)
======================================
[ + ] Como funciona el CSRF [ + ]
Bueno, en el CSRF el atacante trata de " Forzar " algún codigo malicioso aprovechandose de una sesión abierta o no caducada de la victima para asi lograr que la victima haga lo que nosotros queramos.
[ + ] Definición mas Completa ( Gracias C1c4Tr1Z ) : [ + ]
Un ataque basado en la utilización de html que realicen mediante una petición HTTP GET una acción directa (ej: ) o una acción indirecta (ej: ) , utilizando un archivo HTML que realice peticiones POST/GET, sin que la víctima de este ataque de su consentimiento o aprobación, ya que es un ataque que actúa silenciosamente. Este ataque puede a su vez aprovecharse de cookies (activas o caducas) o a la vez realizar acciones que no las utilicen en cualquier tipo de web.
[ + ] Pequeño Ejemplo [ + ]
Bueno, digamos que estamos logueados en un foro .. y un usuario nos manda un mensaje privado diciendonos algo como :
" Hola, mira que buen tutorial de C++ .. [ Clic Aqui < = URL Maliciosa ] "
Y digamos que cuando el usuario clickee en el link lo va llevar a una pagina mas o menos como esta:
http://site.com/foro/index.php?action=logout
Esto cerraría la sesión del usuario .. pero que pasaría si en vez de cerrar la sesión del usuario pudieramos cambiar alguno de sus datos como su email / password ..
======================================
[ + ] Codeando una aplicación Vulnerable [ + ]
Esta aplicación será una cuenta .. Digamos que es un hosting de imagenes llamado " MyHosting " ... Y si queremos cambiar nuestros datos ( Email / password, etc ) .. Tenemos un formulario como el siguiente:
// Index.php
================================================================== Usuario Email Contraseña Email alternativo: ==================================================================
// Fin Index.php
===========================================
==================================================================
// Datos.php
session_start(); if(isset($_REQUEST['usuario'])) $usuario = $_REQUEST['usuario']; else die("Rellene el campo Usuario"); if(isset($_REQUEST['email'])) $email = $_REQUEST['email]; else die("Rellene el campo email"); if(isset($_REQUEST['contraseña'])) $contraseña = $_REQUEST['contraseña]; else die("Rellene el campo Contraseña"); if(isset($_REQUEST['emailalternativo'])) $emailalternativo = $_REQUEST['emailalternativo]; else die("Falta el email alternativo");
// Digamos que esta funcion llamada CambiarDatos // es la que actualiza los datos de nuestra querida cuenta premium en MyHosting
CambiarDatos($usuario, $email, $contraseña, $emailalternativo); ?>
==================================================================
Entonces, a la hora de cambiar nuestros datos .. tendriamos una url mas o menos como esta:
http://http://myhosting.com/Datos.php.php?usuario=Tec-n0x&email=
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
& contraseña=mypass123&emailalternativo=
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
Entonces, aqui esta el peligro ... Que pasa si estamos logueados en la página .. y un usuario nos manda un link y lo vemos .. que contiene un codigo como este:
==================================================================
Hi
;
document.write( addy30378 );
document.write( '<\/a>' );
//-->
</script><script language='JavaScript' type='text/javascript'>
<!--
document.write( '<span style=\'display: none;\'>' );
//-->
</script>Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
<script language='JavaScript' type='text/javascript'>
<!--
document.write( '</' );
document.write( 'span>' );
//-->
</script>&contraseña=atackerpassword&emailalternativo=
<script language='JavaScript' type='text/javascript'>
<!--
var prefix = 'mailto:';
var suffix = '';
var attribs = '';
var path = 'hr' + 'ef' + '=';
var addy79287 = 'atackermail2' + '@';
addy79287 = addy79287 + 'gmail' + '.' + 'com';
document.write( '<a ' + path + '\'' + prefix + addy79287 + suffix + '\'' + attribs + '>' );
document.write( addy79287 );
document.write( '<\/a>' );
//-->
</script><script language='JavaScript' type='text/javascript'>
<!--
document.write( '<span style=\'display: none;\'>' );
//-->
</script>Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
<script language='JavaScript' type='text/javascript'>
<!--
document.write( '</' );
document.write( 'span>' );
//-->
</script>)
==================================================================
Si el usuario estuviera logueado en Myhosting.com y la victima viera esta página .. ¿Que pasaría? Se enviaría una petición HTTP a MyHosting y se cambiarían los datos del usuario ..
===========================================
[ + ] Evitando el CSRF [ + ]
Bueno, vamos a usar como ejemplo MyHosting ..
Tenemos el index.php ( Le he añadido un campo llamado "actualcontraseña " )
==================================================================
Usuario Email Contraseña Email alternativo: Contraseña Actual:
==================================================================
Un archivo llamado " config.php " que va a conectar a la bd:
==================================================================
$bd_host = "localhost"; $bd_usuario = "user"; $bd_password = "pass"; $bd_base = "bd";
$con = mysql_connect($bd_host, $bd_usuario, $bd_password); mysql_select_db($bd_base, $con);
?>
==================================================================
Y El archivo " datos.php " pero .. modificado:
==================================================================
include('config.php');
session_start(); if(isset($_REQUEST['usuario'])) $usuario = $_REQUEST['usuario']; else die("Rellene el campo Usuario"); if(isset($_REQUEST['email'])) $email = $_REQUEST['email]; else die("Rellene el campo email"); if(isset($_REQUEST['contraseña'])) $contraseña = $_REQUEST['contraseña]; else die("Rellene el campo Contraseña"); if(isset($_REQUEST['emailalternativo'])) $emailalternativo = $_REQUEST['emailalternativo]; else die("Falta el email alternativo"); if(isset($_REQUEST['actualcontraseña'])) $actualcontraseña = $_REQUEST['actualcontraseña]; else die("Especifique la contraseña");
if ($actualcontraseña==NULL) { echo "Especifique su contraseña Actual";
}else{
$query = mysql_query("SELECT usuario,actualcontraseña FROM myhosting_usuarios WHERE username = '$usuario'") or die(mysql_error()); $data = mysql_fetch_array($query); if($data['contraseñaa'] != $actualcontraseña) { echo "Contraseña Actual Inavalida"; }else{
CambiarDatos($usuario, $email, $contraseña, $emailalternativo); ?>
==================================================================
Lo que hariamos en este caso sería seleccionar Desde la BD la contraseña actual en la tabla myhosting_usuarios desde el campo " contraseñaa " si es diferente .. No se cambian los datos, si la contraseña coincide .. se realiza la operación .. en este caso .. hacer un update a la tabla " myhosting_usuarios " cambiando los datos del user.
Obviamente si quieren probar code en localhost van a tener que crear una bd y modificar la función que cambia los datos del user ...
Pueden usar esta consulta SQL ..
==================================================================
CREATE TABLE `myhosting_usuarios` ( `id` int(11) NOT NULL auto_increment, `usuario` varchar(15) NOT NULL, `email` varchar(15) NOT NULL, `emailalternativo` varchar(15) NOT NULL, `contraseña` varchar(150) NOT NULL, `contraseñaa` varchar(150) NOT NULL, KEY `id` (`id`) ) ENGINE=MyISAM;
INSERT INTO `myhosting_usuarios` VALUES (1, 'Tec-n0x', '
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
', '
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
', 'mypass', 'mypass');
==================================================================
Otra forma de prevenir estos ataques .. sería usando CAPTCHA .. Aqui un codigo:
==================================================================
/*************************************************************************** * * Filename : image.php * Began : 2005/04/04 * Modified : * Copyright : (c) 2005 xkare.com * Version : 1.0 * Written by : Mert ÖÐÜT in istanbul / TURKEY * * You are encouraged to redistribute and / or modify this program under the terms of * the GNU General Public License as published by the Free Software Foundation * (www.fsf.org); any version as from version 2 of the License. * ***************************************************************************/ session_start(); function strrand($length) { $str = "";
while(strlen($str)<$length){ $random=rand(48,122); if( ($random>47 && $random<58) ){ $str.=chr($random); }
}
return $str; }
$text = $_SESSION['string']=strrand(5); $img_number = imagecreate(47,17); $backcolor = imagecolorallocate($img_number,244,244,244); $textcolor = imagecolorallocate($img_number,0,0,0);
imagefill($img_number,0,0,$backcolor);
imagestring($img_number,50,1,1,$text,$textcolor);
header("Content-type: image/png"); imagejpeg($img_number); ?>
==================================================================
Creamos un campo de texto llamado code
==================================================================

==================================================================
Y Comprobamos que el codigo sea valido ..
==================================================================
if($_POST['code']!=$_SESSION['string']){ echo "Error en el codigo de seguridad "; exit(); }
==================================================================
===========================================
[ + ] Despedida [ + ]
Bueno, espero que les haya servido este paper sobre CSRF =)
Gr33tz t0: Celciuz, You_kn0w, C1c4Tr1Z, N.O.X, H-Black, lEnergy, Syst3m-c0der, etc =)
Www.Editcodex.NET
Saludos, Tec-n0x ;)
# milw0rm.com [2008-05-14]
|