php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58105 Usage of strcpy in apc.c can cause stack corruption with long filenames
Submitted: 2008-03-17 11:43 UTC Modified: 2008-03-25 00:43 UTC
From: Daniel dot Papasian at chronicle dot com Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.2.1 OS: FreeBSD 6.2-RELEASE, RHEL4
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: Daniel dot Papasian at chronicle dot com
New email:
PHP Version: OS:

 

 [2008-03-17 11:43 UTC] Daniel dot Papasian at chronicle dot com
Description:
------------
There is a security vulnerability in at least the last several revisions of apc.c, including the last release version and CVS, due to lengths not being checked with strcpy.

If the filename is longer than the realpath array, stack corruption can occur, which could trivially lead to the webserver crashing, or execution of arbitrary code as the webserver.

Reproduce code:
---------------
Proof of concept vulnerability: 
http://papasian.org/~dannyp/apc-vuln.php 

Patch to fix: http://papasian.org/~dannyp/apc.patch.dpapasian

GNU gdb 6.6 [GDB v6.6 for FreeBSD]
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-portbld-freebsd6.2"...
(no debugging symbols found)
(gdb) run -X
Starting program: /usr/local/sbin/httpd -X
(no debugging symbols found)
(no debugging symbols found)
[Mon Mar 17 12:39:55 2008] [warn] (2)No such file or directory: Failed to enable the 'httpready' Accept Filter
[Mon Mar 17 12:39:55 2008] [warn] (2)No such file or directory: Failed to enable the 'httpready' Accept Filter
[Mon Mar 17 12:39:55 2008] [warn] (2)No such file or directory: Failed to enable the 'httpready' Accept Filter

Program received signal SIGSEGV, Segmentation fault.
0x90909090 in ?? ()
(gdb) bt
#0  0x90909090 in ?? ()
#1  0x90909090 in ?? ()
#2  0x90909090 in ?? ()
#3  0x90909090 in ?? ()
#4  0x90909090 in ?? ()
#5  0x90909090 in ?? ()
#6  0x90909090 in ?? ()



Expected result:
----------------
Not the stack getting wiped out, that's for sure.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-03-17 12:12 UTC] Daniel dot Papasian at chronicle dot com
APC configuration:

apc.include_once_override=1
apc.shm_size=64
apc.gc_ttl=3600
apc.ttl=0
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.filters=
apc.stat=1
apc.enable_cli=1

php -v information:
PHP 5.2.5 (cli) (built: Dec 18 2007 13:37:09)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

Apache information (but I've repeated on more than one version):
Server version: Apache/2.2.4 (FreeBSD)
Server built:   Jun  4 2007 11:13:32
 [2008-03-17 16:05 UTC] rasmus@php.net
In your patch you change the copy from path_for_open to filename?
 [2008-03-17 16:17 UTC] Daniel dot Papasian at chronicle dot com
Nope, although I admit that I had that faulty patch up there for a bit -- it's been fixed, however.  I was merging from an earlier version of APC (where I found and fixed the version first, before forward-porting to CVS) where the second argument was filename, and missed it in the diff.

The patch should be right now.  The only thing changed was going from strcpy to strncpy and adding a bound:

http://papasian.org/~dannyp/apc.patch.dpapasian
 [2008-03-17 16:23 UTC] Daniel dot Papasian at chronicle dot com
And I should point out that my patch is probably not the most correct.  There should probably be an effort to terminate the string if it's overflowing, or do something else that's smarter -- not knowing the code too well, it's hard to say the proper way.

Here is another patch.  I'm also dropping some of the extra parentheses around the size argument.  This patch should ensure that the string is always terminated.

http://papasian.org/~dannyp/apc.dpapasian.patch2
 [2008-03-22 18:46 UTC] Daniel dot Papasian at chronicle dot com
I've written a more advanced proof of concept that uses the buffer overflow to actually execute code, instead of merely crash:

http://papasian.org/~dannyp/apcsmash.php.txt

It's still not the easiest thing to exploit because, on Linux at least, apc seems to be loaded into different parts of memory each time apache starts.  A committed attacker could simply brute force it, however, segfaulting a bunch of apache children until the sweet spot is found and the reverse shell opened.
 [2008-03-25 00:23 UTC] Daniel dot Papasian at chronicle dot com
This bug is referenced in CVE-2008-1488
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2008-1488
 [2008-03-25 00:43 UTC] rasmus@php.net
Fixed in CVS.  We use strlcpy for this.  
3.0.17 will be out shortly.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 09:01:28 2024 UTC