Kyberdigi Labs
 Projects
  Exec_dir
   Download
   Installation
   Configuration
   Other
   Bugs
   History
Access counter
 
|
PHP patch exec_dir
Progamming language PHP allows one to limit executing of external commands
via configuration directive safe_mode.
This directive should contain full path to a directory conatining programs
which PHP script can run. If the script tries to execute a command not
located in this directory, the command is not executed. This configuration
directive is active only if safe mode is enabled, which means more
and sometimes unwanted restrictions to users.
PHP has no known possibility to limit executing of external commands with
disabled safe mode. Teherefore, here is a patch adding special
directive exec_dir straightly into PHP. This directive is very
similar to safe_mode_exec_dir, but safe mode has not to be enabled.
This patch limits executing commands via functions from the
exec family, i. e. exec(),
system() or popen().
Download
You can download this patch for concrete PHP version you are using:
Installation
This patch modifies PHP source, so first of all you need the PHP source,
download it from official PHP
site. After unpacking the archive, step into the directory created:
$ cd /path/to/directory/with/php-x.y.z
Now apply the patch:
$ zcat /path/to/file/php-exec-dir.x.y.z.patch.gz | patch -p1
If everything went OK, you should see output similar to this one:
patching file ext/standard/exec.c
patching file ext/standard/file.c
patching file main/main.c
patching file main/php_globals.h
patching file php.ini-dist
patching file php.ini-recommended
Now you have to compile and install the PHP.
Note: patch is compressed with gzip,
so you have to use zcat to decompress it for the patch prgram
or gunzip to decompress the patch as such.
Configuration
All you have to do is set the directove exec_dir. You can do this
in php.ini or in configuration files of http server
Apache. Beacause of some security
reasons, this variable cannot be changed while running PHP script.
The directive should contain full path to an existing directory which
contains files or symlinks to files which can be executed.
For example, let's imagine a server with running http server Apache, which
serves 2 virtuals: virtual1.tld and virtual2.tld, each of
these being maintained by other person. Maintainer of virtual1.tld wants to
execute cp, rm and mv, maintainer of virtual2.tld
wants to execute mysqldump.
The most clean solution now is to create one directory for
virtual1.tld, i.e. /usr/local/php/bin/virtual1.tld and place binaries
cp, rm and mv into it (or create symlinks to them). Similary we should
create /usr/local/php/bin/virtual2.tld with mysqldump in it.
Of cource it is better to create symlinks than to copy raw files, because of
upgrades. Now we have to configure Apache:
<VirtualHost virtual1.tld>
php_admin_value exec_dir /usr/local/php/bin/virtual1.tld
</VirtualHost>
<VirtualHost virtual2.tld>
php_admin_value exec_dir /usr/local/php/bin/virtual2.tld
</VirtualHost>
A bit more simple is to create one directory for whole server containing
trusted commands. In our example we can create directory /usr/local/php
and place (or create symlinks) cp, mv, rm and mysqldump in it. Now it is
enough to edit the php.ini file, where should be such line:
exec_dir = /usr/local/php
Note: after editing php.ini or Apache configuration
files, the Apache server has to be restarted.
Other
Now we have to describe how the executing works. The name of the command to
be executed will be modified, first it will be shorted: only the last part
(only characters behind last occurence of '/') of the command will rest.
Before this new command name, the contents of exec_dir will be placed.
For example, if we call /bin/cp and directive exec_dir conatins
/usr/local/php, the command /bin/cp will be modified to
cp and then to /usr/local/bin/cp. This command will be
executed.
If the exec_dir directive is not set or is set to an empty string,
functions exec(), popen() etc. are running without any
restrictions.
If safe mode is enabled and safe_mode_exec_dir is set, exec_dir is
ignored.
If exec_dir is set, the called command cannot contain strings ".."
and ";", similar functionality offers safe_mode_exec_dir.
Bugs
Possible memory leak has been found by Manuel Mausz. He also sent a
patch for exec_dir patch solving the issue (thanks!). All versions of the exec_dir
patch bellow 5.2.11 include the leak, so please upgrade to 5.2.11, patch
for this version should be secured.
A minimalistic bug about disabling exec_dir has been discovered by myself.
If you want to disable the exec_dir in (i.e.) httpd.conf, you have to add
such line somewhere:
php_admin_value exec_dir none
Although you set it so, it does not disable the usability of exec_dir,
but it tries to run binaries as if they were in the root directory
of the filesystem (/ls, /df etc.). If you are
in trouble with this, please download new patch for your version of
PHP. All patches listed in section download are
correct ones, so check the MD5 of the patch you have to those in the list.
Vulnerable versions: 4.3.2 - 4.3.8 (inclusive), 5.0.0 and 5.0.1. This
is not a really dramatical bug you should really worry about.
VeNoMouS reported that you can execute commands out of specified
directories if you prepend a ';', '|', '&'
or may other ugly character to the beginning
of the command and try to execute it with the backtick operator.
In original safe_mode_exec_dir the backtick operator is turned off,
in this patch it is not. Therefore, all the patches listed here were
updated with a simple fix that escapes these and other characters
the same way as other commands (as exec() or popen()) do.
You are strongly encouraged to download new patch for your version of
PHP. The patches listed in section download are
correct ones, so check the MD5 of the patch you have to those in the list.
All version from 4.3.2 to 4.3.7 (inclusive) were vulnerable.
There are no other known bugs at this moment. If you have exec_dir set to some
directory and you will execute command out of it, please let me know at
mccohy@kyberdigi.cz.
Note: the patch has not been tested on Windows
platform yet. If you test it and it will work,
let me know.
History
The patch was created for purposes of limit execution of external commands
of users on a multidomain apache server, first for PHP version 4.2.1.
The patch was sent to PHP developers so it could be a part of PHP
(see the archive of mailinglist php-dev),
but no one of PHP developers was interested in. On the other side, some
PHP users wanted this patch, therefore this site was created.
|