Advisory 05/2006 - Zend Platform Multiple Remote Vulnerabilities

Hash: SHA1

Hardened-PHP Project

-= Security Advisory =-

Advisory: Zend Platform Multiple Remote Vulnerabilities
Release Date: 2006/08/24
Last Modified: 2006/08/24
Author: Stefan Esser []

Application: Zend Platform <= 2.2.1
Severity: Malformed session ids may lead to multiple security problems
Risk: Critical
Vendor Status: Vendor has a released an updated version


Quote from
"Zend Platform is the all-in-one production environment that ensures
your PHP applications are available, fast, reliable and scalable. It
uniquely guarantees application uptime and reliability through
enhanced PHP monitoring and immediate problem resolution."

During the development of suhosin, which is our new PHP protection
module, several compatibility tests with binary 3rd party PHP
extensions like the Zend Platform and the Zend Optimizer have been
made. When testing the session protection features of suhosin, we
discovered that the session clustering system, which is shipping
with the Zend Platform is vulnerable to several different attacks.

By exploiting these vulnerabilities, an attacker can crash the
session clustering daemon, which leads to a malfunction of the
session function and renders the attacked node useless. By
carefully crafting the attack session IDs, an attacker might
be able to either execute code within the context of the
session clustering daemon or within the mod_cluster module,
which is the communication link between PHP and the daemon.

Additionally a directory traversal vulnerability in the disk
storage module allows creating and reading the session file
anywhere on the hard disk. If for example a directory or file
within the document root of the webserver is writeable by the
session clustering daemon (which by default runs with the same
privileges as the webserver), this can lead to arbitrary PHP
code injection. On the other hand it might be possible to upload
a user defined file to the webserver and craft a session identifier
so that the data inside the file is used as session data.
This obviously leads to total control over the content of the
session and therefore to control over the application.


The Zend Platform comes with a session handler module that plugs
itself into the session management of PHP to support session
clustering. This module communicates with the ZendSessionManager
daemon. This daemon is responsible for transffering session data
between nodes and does most of the work.

Our analysis revealed that both components, the clustering
module mod_cluster and the daemon, itself have problems with
malicious session identifiers. By default the session identifier
is retrieved from the PHPSESSID request variable. Our first
observation was that sending the identifier as a string with
length 0 immediately crashed the mod_cluster module. The next
observation was that an overlong session identifier also leads
to a crash.

Analysing the responsible code within a debugger revealed that
a statement like:

strncpy(dst, src, strlen(src+1))

was used to copy the session identifier around. This is obvisouly
broken and leads to an overflow in the BSS segment, which makes
exploitation tricky, because the data behind the buffer is not
directly used again. However a later debugging session has shown
that when some conditions are triggered mod_cluster crashed
because the instruction pointer address was changed.

The other observation was that the long PHPSESSID never reached
the daemon. This changed when we took into account the special
layout of Zend Platform session identifiers. They look something
like this:


This special format encodes extra data into the first part of
the session identifier that determines the IP of the node
creating it. With this information it is possible for the daemon
to contact the node that is responsible for storing the session.

When the session data is stored on the hard disk, the last
component of the session identifier is used directly to create
the filename. Unfortunately this is again performed without any
size check. Therefore the filename might overflow its buffer. In
our tests overflowing with a long string resulted in a crash
inside glibc free(). Depending on the system's implementation of
malloc(), this can lead to code execution.

The final observation was that the last component of the session
identifier also allows directory traversal attacks on the place
where the session file is stored. This obviously allows creating
the session files anywhere on the hard disk, where the daemon has
write privileges. And to use any file on the hard disk as origin
for the session data. The later is very dangerous if the
application allows uploading files and the user is able to
predict its storage location. By uploading a file that contains
session data in a daemon compatible format, it is possible to get
total control over the session data, the application uses.

The ability to write session files for example into writeable
directories within the document root path can lead to PHP code
execution if the attacker is either able to put PHP code into a
programm variable that is stored within the session (some session
management systems store for example the User-Agent in the session
to make session hijacking/fixation a little bit harder).

Additionally in PHP < 4.4.3 and < 5.1.4, session identifiers are
not limited in their charset for 3rd party session handlers.
Therefore on these systems it is possible to have PHP code directly
in the session identifier. Because the last component of the
session identifier is also directly copied into the session file
this ensures that PHP code is within the file.

Proof of Concept:

The Hardened-PHP Project is not going to release exploits for
this vulnerability to the public.

Disclosure Timeline:

21. August 2006 - Contacted Zend by email
24. August 2006 - Zend released an updated Zend Platform
24. August 2006 - Public Disclosure


It is strongly recommended to upgrade to the newest version of
Zend Platform (2.2.1a) which you can download at:


pub 1024D/0A864AA1 2004-04-17 Hardened-PHP Signature Key
Key fingerprint = 066F A6D0 E57E 9936 9082 7E52 4439 14CC 0A86 4AA1

Copyright 2006 Stefan Esser. All rights reserved.

Version: GnuPG v1.4.3 (GNU/Linux)

© Hardened PHP Project