Security Advisory

Name         : PHP
Threat level : LOW/MED
Class        : Denial of Service
Discovered   : 2009-08-07
Published    : ---
Credit       : Matthew "j00ru" Jurczyk, Gynvael Coldwind, Martin Noga
Vulnerable   : PHP 5.2.10 / 5.3.0, all platforms

==[ Abstract ]==

PHP is a well-known script programming language, commonly used by the Apache web server,
present on most machines running under Linux/Unix kernel control. It is mostly used to run
scripts on the WWW server side, but it can be also used from the command-line level. Since the
PHP server is running in the context of Apache, an exception generated by PHP will most likely
result in the entire apache process going down. By using the vulnerability describing here, one
is able to crash the PHP server (in its default configuration), both locally and remotely.

==[ Details ]==

The vulnerability makes use of the lack of a special sanity check regarding the user-supplied data,
inside the default EXIF extension. The module intends to allow an external programmer to obtain
every possible information existing inside the EXIF tag inside a JPEG / TIFF image file. Such
information is often stored by modern cameras, providing additional information about the specified

To be more exact, the unsecure code is listed below:

--- cut ---

/* Read the length of the section. */
lh = php_stream_getc(ImageInfo->infile);
ll = php_stream_getc(ImageInfo->infile);

itemlen = (lh << 8) | ll;

if (itemlen < 2) {
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s, Section length: 0x%02X%02X", EXIF_ERROR_CORRUPT, lh, ll);
return FALSE;

sn = exif_file_sections_add(ImageInfo, marker, itemlen+1, NULL);
Data = ImageInfo->file.list[sn].data;

/* Store first two pre-read bytes. */
Data[0] = (uchar)lh;
Data[1] = (uchar)ll;

--- cut ---

As one can see, there is no validation whether the ll/lh values have been correctly read from the file.
Moreover, these values are combined into a single int (itemlen) afterwards. The new variable is then used
as a exif_file_sections_add parameter, responsible for allocating necessary memory for the particular section
defined inside the JPEG file. After the allocation is complete, the new heap pointer is immediately used
to assign the lh and ll bytes to the new memory block.

What makes the code vulnerable is the fact that the attacker could make the lh/ll values contain the
contstant 0xFFFFFFFF value, otherwise known as the EOF marker. This could be accomplished by simply
ending the file right after the Marker value, resulting in the php_stream_getc functions fail. As one
or both of the ll/lh values are -1, itemlen is set to -1, too (due to how the OR operator works).
However, the most critical moment is where the (itemlen+1) value is passed to an internal function.

As (itemlen+1) is simply 0, the function fills the ImageInfo->file.list[sn].data pointer with a NULL
value, being referenced right after the function call (without any check regarding the accessed pointer).
Consequently, this line of code:

--- cut ---

Data[0] = (uchar)lh;

--- cut ---

will generate an access violation (NULL pointer dereference). As this is not an exception that could
be somehow handled by the target application, it will make the whole process crash, resulting in classic
Denial of Service condition.

==[ Solution ]==

The simplest (and probably best) solution is to validate the values returned by php_stream_getc after
every single call. In this case, both ll and lh values should be checked, accomplished by one "if" statement.
What is more, the pointers being referenced inside the code should be validated before being referred to, unless
there is a 100% guarantee the pointer is not going to be set to an invalid memory address, any time.

==[ Proof of Concept ]==

The PoC file should be enclosed to this advisory file, in a ready-to-use form.

==[ Vendor Status ]==

The vendor has not yet been informed about this issue.

==[ Time line ]==

2009-08-07 : The vulnerability has been discovered
2009-xx-xx :

== Disclaimer ==

This document and all the information it contains is provided "as is",
without any warranty. Author is not responsible for the misuse
of the information provided in this advisory. The advisory is
provided for educational purposes only.

Permission is hereby granted to redistribute this advisory, providing
that no changes are made and that the copyright notices and
disclaimers remain intact.

Copyright (C) 2009 Hispasec Sistemas

Add a comment:

URL (optional):
Math captcha: 7 ∗ 7 + 2 =