CSRF / XSRF - Cross Site Request Forgery

Iniciado por Securitykill, 5 Abril 2008, 20:16 PM

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

Securitykill

[ + ] Información del Paper [ + ]

Cross Site Request Forgery [ CSRF / XSRF ]
Autor: SecurityKill  ;)
Fecha: 03/4/2008
Contacto: SecurityKill [ at ] gmail [ 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.

[ + ] 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


     <form method="POST" action="datos.php" name="datos">
          Usuario <input type="text" name="usuario">
          Email <input type="text" name="email">
          Contraseña <input type="text" name="contraseña">
          Email alternativo: <input type="text" name="emailalternativo">
         <input type="submit" name="submit" value="cambiardatos">
     </form>


// 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=SecurityKill&email=mymail@gmail.com&
contraseña=mypass123&emailalternativo=mymail2@gmail.com

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:


<html>
<head>
<title>Hi</title>
</head>
<body>
<img src="http://http://myhosting.com/Datos.php.php?usuario=SecurityKill&email=atackermail@gmail.com&contraseña=atackerpassword&emailalternativo=atackermail2@gmail.com">
</body
</html>


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 " )



     <form method="POST" action="datos.php" name="datos">
          Usuario <input type="text" name="usuario">
          Email <input type="text" name="email">
          Contraseña <input type="text" name="contraseña">
          Email alternativo: <input type="text" name="emailalternativo">
  Contraseña Actual: <input type="text" name="actualcontraseña">
         <input type="submit" name="submit" value="cambiardatos">
     </form>


Un archivo llamado " config.php " que va a conectar a la bd:


<?php

$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, 'SecurityKill', 'mymail@gmail.com', 'mymail2@gmail.com', 'mypass', 'mypass');



Otra forma de prevenir estos ataques .. sería usando CAPTCHA .. Aqui un codigo:


<?php 
/*************************************************************************** 

* 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


<input type='text' size='5' maxlength='5' name='code'><img src="image.php">


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 =)

Si van a publicarlo en otro foro / blog pongan la fuente y autor =)

Saludos, SecurityKill  ;) .

-sagitari-

directamente prefiero robar la cookie simplemente (XSS) y entrar en su sesión y ya manualmente yo modificar lo que quiera =P

igualmente gracias por el tutorial y por tomarte la molestia de aportar en el foro!

salu2!

sirdarckcat

#2
741852:
Yo prefiero tener shell en el servidor, pero no siempre se puede todo xD.

XSS no es CSRF, no tiene nada que ver con CSRF, no es CSRF, y no tiene nada que ver con CSRF..
CSRF esta tan relacionado con XSS como XSS esta con Buffer Overflow, no es lo mismo, y no lo confundan porque XSS no es CSRF, no tiene nada que ver con CSRF, no es CSRF, y no tiene nada que ver con CSRF, y XSS no es CSRF, no tiene nada que ver con CSRF, no es CSRF, y no tiene nada que ver con CSRF.

¿Saben? me pase 1 semana tratando de explicar lo que era CSRF a 3 personas, porque el 99% del tiempo seguian pensando que era XSS, por lo tanto quiero dejar claro que CSRF NO ES XSS!!!

Si necesitan que lo diga mas veces avisenme ;)

Saludos!! :D

Teddy Picker

Si usamos el metodo post para envio de datos, seremos imunes a los XSRF por la etiqueta "<img>", pero no del todo evitaremos un XSRF... :-\

IWKY

Esta bastante bien, ahora por lo menos ya tengo mas claro este tipo de bug y como explotarlo, asi que a practicar, que si no no se aprende,  ;D

un saludo.
Por internet libre http://red-sostenible.net/
El mejor momento de Dragon Ball Z --> Aqui

zhynar_X

Por lo que tengo entendido XSS y XSRF son practicamente lo contrario ya que XSS se aprovecha de la confianza que el usuario deposita en el servidor y XSRF se aprovecha de la confianza que el servidor deposita en el usuario. ;)

Es asi o me equivoco??


Saludos.
Me he creado un blog:
http://zhynar.blogspot.com  Aver si os gusta! ;)


Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)


Azielito

Igual se puede aprovechar de un XSS para atacar a alguna web vulnerable a XSRF y sobre el metodo post se salta muy facil, generas un form con script y lo envias y donde quedo tu "proteccion"

Aqui en México hace tiempo que hubo un ataque de este tipo contra los modems 2wire, no se si aun sean vulnerables xD


satan69

#8
Este tipo de bug solo se encuentran en cms creados por programadores que dicen que saben pero no saben nada...   cada aplicacion que uno crea hay que llevarlas al limite para ver donde hay bug..

y gracias por el manual... xD

zhynar_X

Citar
este tipo de bug solo se encuentran en cms creados por programadores que dicen que saben pero no saben nada...   cada aplicacion que uno crea hay que llevarlas al limite para ver donde hay bug..

Pues como cualquier otro tipo de vulnerabilidades, un programador que de verdad sabe nunca cometeria un RFI, SQL Inj., XSS,... Aunque si va despistado al trabajo se le puede pasar xD

Saludos. ;)
Me he creado un blog:
http://zhynar.blogspot.com  Aver si os gusta! ;)


Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)