php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #69443 Heap metadata corruption when parsing tar file in phar_tar_process_metadata()
Submitted: 2015-04-14 09:03 UTC Modified: 2015-05-22 09:49 UTC
From: emmanuel dot law at gmail dot com Assigned: kaplan (profile)
Status: Closed Package: PHAR related
PHP Version: 5.6.8RC1 OS: *
Private report: No CVE-ID: 2015-3307
 [2015-04-14 09:03 UTC] emmanuel dot law at gmail dot com
Description:
------------
This is a vulnerability whereby the Heap header gets misaligned resulting in the corruption of the heap chunk's metadata.

A heap chunk is allocated in tar.c:167

metadata = (char *) safe_emalloc(1, entry->uncompressed_filesize, 1);



A reference to this heap chunk is passed into phar_parse_metadata() at tar.c:176

if (phar_parse_metadata(&metadata, &entry->metadata, entry->uncompressed_filesize TSRMLS_CC) == FAILURE) {



The following gets called within phar_parse_metadata:611 when zip_metadata_len==0

 PHAR_GET_32(*buffer, buf_len);

This moves the pointer referencing the heap chunk by 4bytes. 



When the heap chunk gets freeed at at tar.c:177:
efree(metadata);

The heap chunk is now misaligned by 4 bytes. In otherwords: ZEND_MM_HEADER_OF(metadata).info._size is now ZEND_MM_HEADER_OF(metadata).info._prev and ZEND_MM_HEADER_OF(metadata).info._prev is tained with the body's data.


Possible means of exploitation:
-Vulnerable heap unlinking
-Use after free due to freeing more memory then the real size of chunk

Test script:
---------------
I've a POC that demonstrate the vulnerable path:
./php Heap_MetaData_Corruption.php

Segmentation fault: 11

https://www.dropbox.com/s/otaz6znqzix0z0d/POC_Heap_MetaData_Corruption_TarBasedPhar.zip?dl=0

Actual result:
--------------
Initial allocation of metadata:
gdb-peda$ p metadata
$1 = 0x7ffff7fbece8



After phar_parse_metadata():
gdb-peda$ p metadata
$2 = 0x7ffff7fbecec   <<< notice the mis-alignment by 4 bytes


#0  phar_tar_process_metadata (entry=0x7ffff7fc15e0, fp=0x7ffff7fbe0e8)
    at /home/elaw/php-5.6.8RC1/ext/phar/tar.c:178
#1  0x00000000006134fb in phar_parse_tarfile (fp=0x7ffff7fbe0e8,
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/PHAR_TAR_GZ_FUZZING/temp/PharBZTAR1.000017.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, pphar=0x7fffffffa858,
    is_data=0x0, compression=0x0, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/tar.c:500
#2  0x00000000006339d2 in phar_open_from_fp (fp=0x7ffff7fbe0e8,
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/PHAR_TAR_GZ_FUZZING/temp/PharBZTAR1.000017.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, options=0x8,
    pphar=0x7fffffffa858, is_data=0x0, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1709
#3  0x00000000006326f4 in phar_create_or_parse_filename (
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/PHAR_TAR_GZ_FUZZING/temp/PharBZTAR1.000017.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, is_data=0x0, options=0x8,
    pphar=0x7fffffffa858, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1346
#4  0x0000000000632602 in phar_open_or_create_filename (
    fname=0x7ffff7fbf928 "temp/PharBZTAR1.000017.phar", fname_len=0x1b, alias=0x0,
    alias_len=0x0, is_data=0x0, options=0x8, pphar=0x7fffffffa858, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1315
#5  0x000000000063e438 in zim_Phar___construct (ht=0x2, return_value=0x7ffff7fbc340,
    return_value_ptr=0x7ffff7f854d0, this_ptr=0x7ffff7fbc430, return_value_used=0x0)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar_object.c:1189




#0  phar_tar_process_metadata (entry=0x7ffff7fc15e0, fp=0x7ffff7fbe0e8)
    at /home/elaw/php-5.6.8RC1/ext/phar/tar.c:178
#1  0x00000000006134fb in phar_parse_tarfile (fp=0x7ffff7fbe0e8,
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/POC.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, pphar=0x7fffffffa858,
    is_data=0x0, compression=0x0, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/tar.c:500
#2  0x00000000006339d2 in phar_open_from_fp (fp=0x7ffff7fbe0e8,
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/POC.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, options=0x8,
    pphar=0x7fffffffa858, is_data=0x0, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1709
#3  0x00000000006326f4 in phar_create_or_parse_filename (
    fname=0x7ffff7fbeb70 "/home/elaw/php-5.6.7/sapi/cli/POC.phar", fname_len=0x4d, alias=0x0, alias_len=0x0, is_data=0x0, options=0x8,
    pphar=0x7fffffffa858, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1346
#4  0x0000000000632602 in phar_open_or_create_filename (
    fname=0x7ffff7fbf928 "temp/PharBZTAR1.000017.phar", fname_len=0x1b, alias=0x0,
    alias_len=0x0, is_data=0x0, options=0x8, pphar=0x7fffffffa858, error=0x7fffffffa898)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar.c:1315
#5  0x000000000063e438 in zim_Phar___construct (ht=0x2, return_value=0x7ffff7fbc340,
    return_value_ptr=0x7ffff7f854d0, this_ptr=0x7ffff7fbc430, return_value_used=0x0)
    at /home/elaw/php-5.6.8RC1/ext/phar/phar_object.c:1189


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-04-15 15:19 UTC] emmanuel dot law at gmail dot com
please use CVE-2015-3307 for this, thanks
 [2015-04-15 18:29 UTC] stas@php.net
-CVE-ID: +CVE-ID: 2015-3307
 [2015-04-16 02:52 UTC] emmanuel dot law at gmail dot com
-Summary: Heapmetada data corruption when parsing tar file in phar_tar_process_metadata() +Summary: Heap metadata corruption when parsing tar file in phar_tar_process_metadata()
 [2015-04-16 02:52 UTC] emmanuel dot law at gmail dot com
Even though this is a different vulnerability, I think your patch for #69324 may have inadvertently resolved this as well.
 [2015-05-10 09:08 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2015-05-10 09:08 UTC] stas@php.net
Could you please verify it's fixed?
 [2015-05-12 09:29 UTC] emmanuel dot law at gmail dot com
-Status: Feedback +Status: Open
 [2015-05-12 09:29 UTC] emmanuel dot law at gmail dot com
Yes, it was inadvertently resolved in 5.6.8 when fixing #69324

This is the commit that fixes it:
http://git.php.net/?p=php-src.git;a=commit;h=17cbd0b5b78a7500f185b3781a2149881bfff8ae

The vulnerable line that was removed was on phar.c:611
PHAR_GET_32(*buffer, buf_len);
 [2015-05-15 23:00 UTC] emmanuel dot law at gmail dot com
-Status: Open +Status: Closed
 [2015-05-15 23:00 UTC] emmanuel dot law at gmail dot com
Close bug
 [2015-05-22 09:48 UTC] kaplan@php.net
-Assigned To: +Assigned To: kaplan
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 08:01:29 2024 UTC