[UNIX] PHP memory_limit Remote Vulnerability

From: SecuriTeam (support_at_securiteam.com)
Date: 07/14/04

  • Next message: SecuriTeam: "[UNIX] PHP strip_tags() bypass vulnerability"
    To: list@securiteam.com
    Date: 14 Jul 2004 11:05:53 +0200

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.

    - - - - - - - - -

      PHP memory_limit Remote Vulnerability


    PHP is "a widely-used general-purpose scripting language that is
    especially suited for Web development and can be embedded into HTML".

    According to Security Space PHP is the most popular Apache module and is
    installed on about 50% of all Apaches worldwide. This figure includes of
    course only those servers that are not configured with expose_php=Off.

    During a reaudit of the memory_limit problematic it was discovered that it
    is possible for a remote attacker to trigger the memory_limit request
    termination in places where an interruption is unsafe. This can be abused
    to execute arbitrary code on remote PHP servers.


    Vulnerable Systems:
     * PHP version 4.3.7 and prior
     * PHP version 5.0.0RC3 and prior

    On the 28th June 2004 Gregori Guninski released his advisory about a
    possible remote DOS vulnerability within Apache 2 (CAN-2004-0493). This
    vulnerability allows tricking Apache 2 into accepting arbitrary sized HTTP
    headers. Guninski and many others rated this bug as "Low Risk" for 32bit
    systems, but they did not take into account that such a bug could have a
    huge impact on 3rd party modules.

    After his advisory was released I re-audited PHP's memory_limit request
    termination, because this bug made it possible to reach the memory_limit
    at places that were never meant to be interrupted. After a possible
    exploitation path for Apache 2 servers was discovered and a working
    exploit was created, similar patches were found and added to the proof of
    concept exploit that allowed exploitation of NON Apache 2 servers. (i.e.
    Apache 1.3.31)

    The idea of the exploit is simple. When PHP allocates a block of memory it
    first checks in the cache of free memory blocks for a block of the same
    size. If such a block were found it is taken from the cache otherwise PHP
    checks if an allocation would violate the memory_limit. In that case the
    request shutdown is triggered through zend_error(). (PHP < 4.3.7 aborts
    after the violating memory block is allocated) PHP contains several places
    where such an interruption is unsafe. An example for such places is those
    where Zend HashTables are allocated and initialized. This is performed in
    2 steps and the initialization step itself allocates memory before
    important members are correctly initialized. An attacker that is able to
    trigger the memory_limit abort within zend_hash_init() and is additionally
    able to control the heap before the HashTable itself is allocated, is able
    to supply his own HashTable destructor pointer.

    Several places within PHP where found where this action is performed on
    HashTables that actually get destructed by the request shutdown. One of
    such places is i.e. within the fileupload code, but is only trigger-able
    on Apache 2 servers that are vulnerable to CAN-2004-0493, another one is
    only reachable if variables_order was changed to have the "E" in the end,
    a third one is within session extension which is activated by default but
    the vulnerability can not be triggered if the session functionality is not
    used. A fourth place is within the implementation of the register_globals
    functionality. Although this is deactivated by default since PHP 4.2 it is
    activated on nearly all servers that have to ensure compatibility with
    older scripts. Other places might exist in not default activated or 3rd
    party extensions.

    All mentioned places outside of the extensions are quite easy to exploit,
    because the memory allocation up to those places is deterministic and
    quite static throughout different PHP versions. The only unknown entity is
    the size of the environment vars array. But that is usually small and can
    be brute forced with some kind of binary search algorithm. Additionally
    this information could leak to an attacker through an open phpinfo() page.
    If the admin used php.ini-recommended as configuration basis it is
    irrelevant anyway because the ENV array is not populated in that case.

    Because the exploit itself consists of supplying an arbitrary destructor
    pointer this bug is exploitable on any platform. (Except the system runs
    with non exec heap+stack protection) This includes systems running
    Hardened-PHP <= 0.1.2 because they have no protection of the HashTable
    destructor pointer.

    As a last word it should be said, that an attacker does not need to send
    8/16/64MB (or whatever the memory_limit is) per attack. With POST requests
    it is quite easy to eat 100 (and more) times the amount of sent bytes.

    Disclosure Timeline:
    07. July 2004 - Vendor-sec was informed about the fact that this
    vulnerability was found
    14. July 2004 - Public Disclosure

    CVE Information:

     If you are running PHP with compiled in memory_limit support, it is
    strongly recommended that you upgrade as soon as possible to the newest
    version. Disabling memory_limit within your configuration can be
    considered a workaround, but leaves your site vulnerable to memory hungry
    PHP scripts or POST requests that create huge variables. If you are
    running PHP with Apache <= 2.0.49 ensure that you have the fix for
    CAN-2004-0493 applied.


    The information has been provided by <mailto:s.esser@e-matters.de> Stefan
    The original article can be found at:


    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com


    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.

  • Next message: SecuriTeam: "[UNIX] PHP strip_tags() bypass vulnerability"