go to bug id or search bugs for
phar.c - phar_parse_pharfile() has insufficient sanity checks on the entry data. A hostile phar archive can lead the parser to access memory out of the allocated buffer, resulting in a crash.
The for loop that parses the manifest entries does not properly checks that the metadata_len 4 bytes field is inside the buffer, enabling a huge page aligned archive to trigger an out-of-page read, causing a segmentation fault - as presented in the attached trace.
The proposed fix is to add a check before reading this length field (just like the check in the start of the for loop):
if ( 4 > (size_t)(endbuffer - buffer))
This report is somewhat connected to report #73764, and both should probably be fixed together so to avoid confusion.
$p = new Phar('example_hostile.phar', 0);
echo "Loaded the phar archive\n";
no crash, calling the echo with the specified message as intended
#0 0xb4c7cb56 in ?? () from /usr/lib/php/20151012/phar.so
#1 0xb4c7ebce in phar_create_or_parse_filename ()
#2 0xb4c7f8b7 in phar_open_or_create_filename ()
#3 0xb4c8120e in zim_Phar___construct () from /usr/lib/php/20151012/phar.so
#4 0x80348662 in execute_internal ()
#5 0x802a1dce in dtrace_execute_internal ()
#6 0x80339f65 in ?? ()
#7 0x802f26da in execute_ex ()
#8 0x802a1c35 in dtrace_execute_ex ()
#9 0x8034a1b6 in zend_execute ()
#10 0x802b210d in zend_execute_scripts ()
#11 0x80251054 in php_execute_script ()
#12 0x8034c01f in ?? ()
#13 0x8012b64f in main ()
(gdb) info reg
eax 0xa8200000 -1474297856
ecx 0x0 0
edx 0xb49fffec -1264582676
ebx 0xb4ca6c40 -1261802432
esp 0xbfeee240 0xbfeee240
ebp 0xb5274000 0xb5274000
esi 0x640001b 104857627
edi 0xb4a00000 -1264582656
eip 0xb4c7cb56 0xb4c7cb56
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
Add a Patch
Add a Pull Request
Please provide example_hostile.phar
Uploaded the example_hostile.phar (+ the python script than generated it) to this link: http://www.cs.tau.ac.il/~eyalitki/Upload/73773/
I can't reproduce this after fix for #73764 is applied. Could you please check if it still happens for you?
It still happens, and this is because:
1) #73764 checked that the static 24 entry bytes (entry.filename_len, entry.uncompressed_filesize, timestamp, compressed_filesize, crc32, flags) have enough space in the buffer.
2) #73764 also checked that the dynamic filename has enough space in the buffer
3) After all of these fields there are additional fields:
a) 4 bytes - len (metadata_len)
b) len bytes - the actual metadata
The current code reads the 4 bytes (without checking it is inside the buffer), and the checks that has enough (len) bytes so to read the metadata itself.
Could you please supply the file that reproduces it for you? For me it does not reproduce with the file at the link here.
* I uploaded a new .phar file that was tested in my environment to reproduce the error.
* Again, I uploaded the python script that generated it (build_phar_new.py).
* Both files can be found in the same link as before: http://www.cs.tau.ac.il/~eyalitki/Upload/73773/
The fix is in security repo as e5246580a85f031e1a3b8064edbaa55c1643a451 and in https://gist.github.com/b7b2c560555bedec94a12f73cacc182f
I approve of the suggested fix.
Automatic comment on behalf of stas
Log: Fix bug #73773 - Seg fault when loading hostile phar
CVE-2017-11147 has been assigned for this issue.