PHP CGI arbitrary code execution vulnerability

Bug #919451 reported by Joerie de Gram
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
php5 (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

We have identified an arbitrary code execution vulnerability in PHP CGI. Please
refer to the advisory below, as reported to <email address hidden> on 2012-01-17.

As of the time of writing, no response has been received from the upstream vendor.

In addition to the upstream vendor, one additional party
(a hosting provider) has been notified of this vulnerability.

------ Original advisory ------

When PHP is used in a CGI-based setup (such as Apache's mod_cgid), the php-cgi
receives a processed query string parameter as command line arguments
(in case of GET or HEAD requests, and provided there are no unescaped
'=' characters in the query string). This is expected behavior for CGI scripts,
as defined in section 4.4 of RFC 3875 [1].

Even though many setups have abandoned 'traditional' CGI in favor of
FastCGI-based solutions (e.g. mod_fastcgi, mod_fcgid), which cannot pass on a
requests' query string as command line parameters, PHP should refuse to
process command line arguments when invoked as a CGI binary.

This used to be PHP's exact behavior and is still documented as such in [2],
but nonetheless a change to re-introduce parsing of a specific set of command
line args was introduced in 2004, preceded by a post on the php-devel
mailing list:

"The point of the question here is if anybody remembers why we decided not
to parse command line args for the cgi version?" [3]

Parsing command line args allows command-line switches, such as -s, -d or -c
to be passed to the php-cgi binary, which can be exploited to disclose source
code and obtain arbitrary code execution.

This can be trivially demonstrated by configuring Apache to run PHP
in CGI mode, for example using mod_cgi:

Options +ExecCGI
AddHandler php5-cgi .php
Action php5-cgi /cgi-bin/php5-cgi

Subsequently accessing http://localhost/index.php?-s unintentionally reveals
the source code of index.php

Another example, demonstrating remote code execution:

curl -s -H 'Output: <?php system("id");die(); ?>' \
'http://localhost/index.php?-dauto_prepend_file%3d/proc/self/environ' \
| awk -F 'HTTP_OUTPUT=' '{ print $2 }'

Eindbazen
http://eindbazen.net

[1] http://www.ietf.org/rfc/rfc3875
[2] http://www.php.net/manual/en/security.cgi-bin.attacks.php
[3] http://thread.gmane.org/gmane.comp.php.devel/20745

CVE References

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thank you for using Ubuntu and reporting a bug. What was upstream's response?

Changed in php5 (Ubuntu):
assignee: nobody → Jamie Strandboge (jdstrand)
status: New → Incomplete
Revision history for this message
Joerie de Gram (jdegram) wrote :

Below is the full disclosure timeline, up until now:

Jan 17, 2012: Eindbazen informs <email address hidden> about the vulnerability
Jan 20, 2012: Eindbazen informs Ubuntu about the vulnerability
Feb 1, 2012: Eindbazen again informs <email address hidden> about the vulnerability and provides a workaround
Feb 1, 2012: PHP confirms the issue and states that it does not know how to patch
Feb 6, 2012: Eindbazen again provides suggested workaround
Feb 19, 2012: Eindbazen informs CERT/CC about the vulnerability because of lack of action from PHP

Aforementioned workaround has been attached to this comment. As upstream stated on Feb 1st, command arguments to php-cgi can originate from various sources (eg. fcgi config, a scripts' shebang or a HTTP request), which makes the issue difficult to fix.

As such, supplied workaround resolves the issue, but as a result breaks eg. arguments originating from shebangs. We too are unsure how to properly fix this issue.

For reference, the commit which introduced the vulnerability: http://svn.php.net/viewvc?view=revision&revision=152585

Revision history for this message
Joerie de Gram (jdegram) wrote :

Looks like I forgot to attach the workaround.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thank you for this additional information. We probably do not want to diverge from upstream on this. If you hear anything back from php on this, please comment in the bug. We coordinate via CERT as well, so we will update this bug as we get more details.

Changed in php5 (Ubuntu):
assignee: Jamie Strandboge (jdstrand) → nobody
status: Incomplete → Confirmed
Revision history for this message
Joerie de Gram (jdegram) wrote :

PHP is apparantly testing a patch to mitigate this vulnerability, for which they requested to push back the disclosure date by two weeks.

Unfortunately, due to an error on PHP's side, their bug tracker entry was initially marked public; as such the vulnerability has been prematurely disclosed, with no upstream fix available (yet).

Revision history for this message
Jamie Strandboge (jdstrand) wrote :
Changed in php5 (Ubuntu):
status: Confirmed → Fix Released
visibility: private → public
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.