Cross Site Request Forgery [CSRF / XSRF] Author: Tec-n0x;) Date: 03/4/2008 Www.Editcodex.NET Contact: Tec-n0x [at] hotmail [dot] com ====================================== [+] Index [+] => 0x001 <= => Introduction => 0x002 <= => How does the CSRF / Small example => 0x003 <= => Code an application Vulnerable => 0x004 <= => Avoiding the CSRF => 0x005 <= => Farewell ====================================== [+] Introduction [+] Well, in this paper we will talk about what is CSRF / XSRF [Cross Site Request Forgery]. Try to explain everything possible on this vulnerability and most importantly .. As prevent these attacks. Let's start .. =) ====================================== [+] How does the CSRF [+] Well, the CSRF the attacker tries to "Forcing" some malicious code exploiting a meeting open or not expired for the victim to achieve that the victim do what we want. [+] Fuller definition (Thanks C1c4Tr1Z): [+] An attack based on the use of <tags> html performed by a petition HTTP GET direct action (eg <img src=http://mail.google.com/mail/?logout&hl=es>) or an indirect action (eg <img src=http://www.atacante.com/xsrf.html>), using an HTML file petitions to conduct POST / GET, without the victim of this attack of its consent or approval, as it is an attack which operates silently. This attack can in turn take advantage of cookies (active or expired) or while performing actions that are not used in any type of site. [+] Small Example [+] Well, let's say that we are currently logged in a forum .. and a user sends us a private message telling us something like: "Hello, that looks good tutorial C + + .. [Click Here <= Maliciosa URL]" And let's say that when the user click on the link it will lead to a page more or less like this: http://site.com/foro/index.php?action=logout This would close the user's session .. but what would happen if instead of closing the user's session may change any of its data as email / password .. ====================================== [+] Code an application Vulnerable [+] This application will be an account .. Say it is a hosting of images called "MyHosting" ... And if we change our data (Email / password, etc.) .. We have a form as follows: / / Index.php ================================================== ================ <form method="POST" action="datos.php" name="datos"> User <input type="text" name="usuario"> Email <input type="text" name="email"> Password <input type="text" name="contraseña"> Email alternative: <input type="text" name="emailalternativo"> <input type="submit" name="submit" value="cambiardatos"> </ form> ================================================== ================ / / Index.php End =========================================== ================================================== ================ / / Datos.php <? session_start (); if (isset ($ _REQUEST [ 'user'])) $ user = $ _REQUEST [ 'user']; Else die ( "Fill the field User"); if (isset ($ _REQUEST [ 'email'])) $ email = $ _REQUEST [ 'email]; Else die ( "Fill in the email field"); if (isset ($ _REQUEST [ 'password'])) $ password = $ _REQUEST [ 'password]; Else die ( "Fill the Password field"); if (isset ($ _REQUEST [ 'emailalternativo'])) emailalternativo $ = $ _REQUEST [ 'emailalternativo]; Else die ( "Missing email alternative"); / / Let's say this function called CambiarDatos / / Is the updating of data in our beloved premium account MyHosting CambiarDatos ($ user, $ email, $ password, $ emailalternativo); > ================================================== ================ Then, when change our data .. url would have a more or less like this: http://http://myhosting.com/Datos.php.php?usuario=Tec-n0x&email=mymail & @ gmail.com password = mypass123 & emailalternativo = mymail2@gmail.com So here is the danger ... What if we are currently logged on page .. and a user sends us a link and we see .. which contains a code like this: ================================================== ================ <html> <head> Hi <title> </ title> </ head> <body> <img src="http://http://myhosting.com/Datos.php.php?usuario=Tec-n0x&email=atackermail@gmail.com&contraseña=atackerpassword&emailalternativo=atackermail2@gmail.com"> </ Body </ html> ================================================== ================ If the user was logged in Myhosting.com and the victim saw this page .. What? It would send an HTTP request to MyHosting and change user data .. =========================================== [+] Avoiding the CSRF [+] Well, let's use as an example MyHosting .. We index.php (I have added a field called "actualcontraseña") ================================================== ================ <form method="POST" action="datos.php" name="datos"> User <input type="text" name="usuario"> Email <input type="text" name="email"> Password <input type="text" name="contraseña"> Email alternative: <input type="text" name="emailalternativo"> Actual Password: <input type="text" name="actualcontraseña"> <input type="submit" name="submit" value="cambiardatos"> </ form> ================================================== ================ A file called "config.php" that will connect to the bd: ================================================== ================ <? PHP $ bd_host = "localhost"; $ bd_usuario = "user"; $ bd_password = "pass"; $ bd_base = "bd"; with $ = mysql_connect ($ bd_host, $ bd_usuario, $ bd_password); mysql_select_db ($ bd_base, with $); > ================================================== ================ And File datos.php "but .. Amended: ================================================== ================ <? include ( 'config.php'); session_start (); if (isset ($ _REQUEST [ 'user'])) $ user = $ _REQUEST [ 'user']; Else die ( "Fill the field User"); if (isset ($ _REQUEST [ 'email'])) $ email = $ _REQUEST [ 'email]; Else die ( "Fill in the email field"); if (isset ($ _REQUEST [ 'password'])) $ password = $ _REQUEST [ 'password]; Else die ( "Fill the Password field"); if (isset ($ _REQUEST [ 'emailalternativo'])) emailalternativo $ = $ _REQUEST [ 'emailalternativo]; Else die ( "Missing email alternative"); if (isset ($ _REQUEST [ 'actualcontraseña'])) actualcontraseña $ = $ _REQUEST [ 'actualcontraseña]; Else die ( "Enter password"); if ($ actualcontraseña == NULL) ( echo "Enter your password Current"; else () $ query = mysql_query ( "SELECT user actualcontraseña FROM myhosting_usuarios where username = '$ user'") or die (mysql_error ()); $ data = mysql_fetch_array ($ query); if ($ data [ 'PASSWORD']! = $ actualcontraseña) ( echo "Actual Inavalida Password"; else () CambiarDatos ($ user, $ email, $ password, $ emailalternativo); > ================================================== ================ What we do in this case would select the BD Since the current password in the table myhosting_usuarios from the field "PASSWORD" if different .. Do not change the data if the password matches .. this operation is performed .. in this case .. make an update to the table "myhosting_usuarios" changing data user. Obviously if they want to test code in localhost will have to modify and create a bd the changing role of user data ... They can use this query .. ================================================== ================ Create table myhosting_usuarios `` ( `id` int (11) NOT NULL auto_increment, `` user varchar (15) NOT NULL, Email `` varchar (15) NOT NULL, `` emailalternativo varchar (15) NOT NULL, `password` varchar (150) NOT NULL, `` PASSWORD varchar (150) NOT NULL, KEY `id` ( `id`) ) = MyISAM engine; INSERT INTO `myhosting_usuarios` values (1, 'Tec-n0x', 'mymail@gmail.com', 'mymail2@gmail.com', 'mypass',' mypass'); ================================================== ================ Another way to prevent these attacks .. would be using Captcha .. Here a code: ================================================== ================ <? PHP /************************************************* ************************** * * Filename: image.php * Began: 2005/04/04 * Modified: * Copyright © 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 (); strrand function ($ 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, 244244244); $ 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); > ================================================== ================ We create a text field called code ================================================== ================ <input type='text' size='5' maxlength='5' name='code'> <img src="image.php"> ================================================== ================ And verify that the code is valid .. ================================================== ================ if ($ _POST [ 'code']!=$_ SESSION [' string ']) ( echo "error in the security code"; exit (); ) ================================================== ================ =========================================== [+] Farewell [+] Well, I hope they have served this paper on CSRF =) Gr33tz t0: Celciuz, You_kn0w, C1c4Tr1Z, NOX, M-Black, lEnergy, Syst3m-c0der, etc. =) Www.Editcodex.NET Greetings, Tec-n0x;) # Milw0rm.com [2008-05-14]