POSITRON SECURITY LLC
              <http://www.positronsecurity.com/>


                  Security Advisory #2009-001
         Memcached and MemcacheDB ASLR Bypass Weakness



Author:  Joe Testa <jt _at_sign_ positronsecurity_dot_com>
Date:    April 28th, 2009
URL:     <http://www.positronsecurity.com/advisories/2009-001.html>



I. Executive Summary

    Memcached [1] is a popular open-source, multi-platform database-
caching software program used to alleviate repetitive database
operations.  It was originally developed by Danga Interactive [2].
MemcacheDB [3] is a fork of the memcached project which adds
persistent storage using the BerkeleyDB database engine [4].

    An implementation weakness that impacts security was identified
in memcached v1.2.7 and MemcacheDB v1.2.0.  Users in high-security
environments should consider upgrading to memcached v1.2.8 and/or
a fixed version of MemcacheDB to protect against potential attacks.



II. Overview

    During an audit of the memcached v1.2.7 source code, it was
found that the software divulges its stack, heap, and shared library
memory locations.  This effectively disables address space layout
randomization (ASLR) [5] protection, making potential buffer overflow
vulnerabilities much easier to exploit.  The same behavior exists in
MemcacheDB v1.2.0.



III. Detailed Description

    By simply connecting to the memcached TCP port (default: 11211)
or MemcacheDB's TCP port (default: 21201) and issuing a 'stats maps'
command, the software will directly pipe the output of
/proc/self/maps to the client (see memcached.c:1153 and
memcachedb.c:946).


    jdog@thegibson:~$ telnet 192.168.x.x 11211
    Trying 192.168.x.x...
    Connected to localhost.
    Escape character is '^]'.
    stats maps
    08048000-08053000 r-xp 00000000 fe:01 5934920    /home/jdog/ \
    sources/memcached-1.2.7/memcached
    08053000-08054000 rw-p 0000b000 fe:01 5934920    /home/jdog/ \
    sources/memcached-1.2.7/memcached
    08054000-080a4000 rw-p 08054000 00:00 0          [heap]
    b7d0a000-b7d4d000 rw-p b7d0a000 00:00 0 
    b7d4d000-b7d61000 r-xp 00000000 fe:01 2555942    /lib/tls/i686/ \
    cmov/libpthread-2.7.so
    b7d61000-b7d63000 rw-p 00013000 fe:01 2555942    /lib/tls/i686/ \
    cmov/libpthread-2.7.so
    b7d63000-b7d65000 rw-p b7d63000 00:00 0 
    b7d65000-b7d74000 r-xp 00000000 fe:01 2555943    /lib/tls/i686/ \
    cmov/libresolv-2.7.so
    b7d74000-b7d76000 rw-p 0000f000 fe:01 2555943    /lib/tls/i686/ \
    cmov/libresolv-2.7.so
    b7d76000-b7d78000 rw-p b7d76000 00:00 0 
    b7d78000-b7d7f000 r-xp 00000000 fe:01 2555944    /lib/tls/i686/ \
    cmov/librt-2.7.so
    b7d7f000-b7d81000 rw-p 00006000 fe:01 2555944    /lib/tls/i686/ \
    cmov/librt-2.7.so
    b7d81000-b7d95000 r-xp 00000000 fe:01 2555934    /lib/tls/i686/ \
    cmov/libnsl-2.7.so
    b7d95000-b7d97000 rw-p 00013000 fe:01 2555934    /lib/tls/i686/ \
    cmov/libnsl-2.7.so
    b7d97000-b7d9a000 rw-p b7d97000 00:00 0 
    b7d9a000-b7ee3000 r-xp 00000000 fe:01 2555928    /lib/tls/i686/ \
    cmov/libc-2.7.so
    b7ee3000-b7ee4000 r--p 00149000 fe:01 2555928    /lib/tls/i686/ \
    cmov/libc-2.7.so
    b7ee4000-b7ee6000 rw-p 0014a000 fe:01 2555928    /lib/tls/i686/ \
    cmov/libc-2.7.so
    b7ee6000-b7ee9000 rw-p b7ee6000 00:00 0 
    b7ee9000-b7efc000 r-xp 00000000 fe:01 614755     /usr/lib/ \
    libevent-1.3e.so.1.0.3
    b7efc000-b7efd000 rw-p 00013000 fe:01 614755     /usr/lib/ \
    libevent-1.3e.so.1.0.3
    b7efd000-b7efe000 rw-p b7efd000 00:00 0 
    b7f0e000-b7f10000 rw-p b7f0e000 00:00 0 
    b7f10000-b7f11000 r-xp b7f10000 00:00 0          [vdso]
    b7f11000-b7f2b000 r-xp 00000000 fe:01 2557432    /lib/ld-2.7.so
    b7f2b000-b7f2d000 rw-p 00019000 fe:01 2557432    /lib/ld-2.7.so
    bfce7000-bfcfc000 rw-p bffeb000 00:00 0          [stack]
    END


    Since neither memcached nor MemcacheDB do any authentication, a
well-known requirement is that the services must never be accessible
by untrusted machines.  If an untrusted machine were to access the
services, then any contents of the cache could be read and/or
modified; arbitrary data could be inserted as well.

    Even in light of this requirement, it remains reasonable for an
administrator to expect that using these pieces of software would
not allow a trusted machine to execute arbitrary code.  By extension,
it remains reasonable for an administrator to rely on ASLR protections
to thwart any potential buffer overflow attacks.  Because of these
reasonable assumptions, and because no explicit documentation warns
users of this non-obvious feature and its non-obvious impact, this
issue qualifies as a security weakness.

    This issue has been assigned the following CVE ID: CVE-2009-1255.



IV. Solution

    The offending functionality was removed from the software, thus
reinstating ASLR protection.  Users in high-security environments may
consider upgrading to better protect against potential buffer
overflow vulnerabilities.

    memcached v1.2.8 was released to address this issue and can be
downloaded at
<http://memcached.googlecode.com/files/memcached-1.2.8.tar.gz>.  The
official release announcement can be viewed at
<http://groups.google.com/group/memcached/browse_thread/thread/ \
ff96a9b88fb5d40e>.

    The maintainer of MemcacheDB claimed to fix the issue in the
code repository, but unfortunately, has not released a stable
package containing it (see section V below for details).  In the
meantime, the following unofficial patch can be applied to the
source tree of MemcacheDB v1.2.0:

----
diff -ru memcachedb.c memcachedb.c.fixed
--- memcachedb.c	2008-10-14 01:40:58.000000000 -0400
+++ memcachedb.c.fixed	2009-04-28 12:15:12.000000000 -0400
@@ -931,43 +931,6 @@
 #endif /* HAVE_STRUCT_MALLINFO */
 #endif /* HAVE_MALLOC_H */
 
-#if !defined(WIN32) || !defined(__APPLE__)
-    if (strcmp(subcommand, "maps") == 0) {
-        char *wbuf;
-        int wsize = 8192; /* should be enough */
-        int fd;
-        int res;
-
-        if ((wbuf = (char *)malloc(wsize)) == NULL) {
-            out_string(c, "SERVER_ERROR out of memory writing stats maps");
-            return;
-        }
-
-        fd = open("/proc/self/maps", O_RDONLY);
-        if (fd == -1) {
-            out_string(c, "SERVER_ERROR cannot open the maps file");
-            free(wbuf);
-            return;
-        }
-
-        res = read(fd, wbuf, wsize - 6);  /* 6 = END\r\n\0 */
-        if (res == wsize - 6) {
-            out_string(c, "SERVER_ERROR buffer overflow");
-            free(wbuf); close(fd);
-            return;
-        }
-        if (res == 0 || res == -1) {
-            out_string(c, "SERVER_ERROR can't read the maps file");
-            free(wbuf); close(fd);
-            return;
-        }
-        memcpy(wbuf + res, "END\r\n", 5);
-        write_and_free(c, wbuf, res + 5);
-        close(fd);
-        return;
-    }
-#endif
-
     out_string(c, "ERROR");
 }
 

----

    The above patch can be applied to the MemcacheDB v1.2.0
sources with:

        $ cd memcachedb-1.2.0
        $ patch < ../memcachedb.patch

    The source tree must then be re-compiled and the existing
vulnerable 'memcachedb' binary replaced with the fixed result.



V. Vendor Timeline

    Contacting the vendor of memcached proved difficult at first
because the contents of the packaged AUTHORS file was apparently
out of date.  Once the proper maintainer was located (Dormando),
the issue was fixed quickly.

    The maintainer of MemcacheDB fixed the problem quickly in the
source code repository, but never released a fixed stable version
after claiming one was on the way; subsequent attempts to contact
the maintainer have been ignored.


    March 31st, 2009:  Using the contents of the packaged AUTHORS
                       file, Brad Fitzpatrick and Anatoly Vorobey
                       were notified via e-mail.

    April 7th, 2009:   After receiving no reply from the official
                       maintainers, a request to contact any
                       acting maintainer(s) was made to the memcached
                       mailing list at <http://groups.google.com/ \
                       group/memcached/browse_thread/thread/ \
                       ff92b3d1a6191e4d#>.  Dormando identified
                       himself as a maintainer via e-mail, and was
                       notified of the issue.

    April 10th, 2009:  Dormando released v1.2.8 to resolve the issue.

    April 13th, 2009:  Steve Chu, the maintainer of MemcacheDB, was
                       notified of the issue.  He replied that he
                       would fix it.

    April 14th, 2009:  Steve Chu sent notification that the issue
                       was fixed in the code repository and provided
                       the following link:  <http://code.google.com/ \
                       p/memcachedb/source/detail?r=98>.

    April 15th, 2009:  Steve Chu was asked when a stable release would
                       be available.

    April 17th, 2009:  Steve Chu was again asked when a stable release
                       would be available.

    April 18th, 2009:  Steve Chu indicated that a stable release
                       containing the fix would be available "a couple
                       of days later."

    April 24th, 2009:  An update was requested from Steve Chu regarding
                       the release date for the fixed stable version
                       of MemcacheDB.  As of April 28th, 2009, no reply
                       was received.



VI. References

[1] "memcached: a distributed memory object caching system",
    <http://www.danga.com/memcached/>, Retrieved April 13th, 2009.

[2] No title, <http://www.danga.com/>, Retrieved April 13th, 2009.

[3] "MemcacheDB: A distributed key-value storage system designed
    for persistent", <http://memcachedb.org/>, Retrieved April
    13th, 2009.

[4] "Oracle Berkeley DB", <http://www.oracle.com/technology/ \
    products/berkeley-db/db/index.html>, Retrieved April 13th, 2009.

[5] "Address space layout randomization - Wikipedia, the free
    encyclopedia",
    <http://en.wikipedia.org/wiki/Address_space_layout_randomization>,
    Retrieved April 13th, 2009.


----

Key: <http://www.positronsecurity.com/keys/positron_security_2009.key.asc>
Fingerprint: F567 5BEF 3450 A521 C00D  2690 D7BD 2A5C 9644 9804

Twitter: therealjoetesta

Copyright 2009, Positron Security LLC.  All rights reserved.