|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2016-09-06 03:58 UTC] stas@php.net
-Type: Security
+Type: Bug
[2016-09-06 04:50 UTC] stackexploit at gmail dot com
[2016-09-06 09:52 UTC] cmb@php.net
-Status: Open
+Status: Analyzed
-Package: Filesystem function related
+Package: Program Execution
-Assigned To:
+Assigned To: cmb
[2016-09-06 09:52 UTC] cmb@php.net
[2016-09-06 10:21 UTC] cmb@php.net
[2016-09-06 10:21 UTC] cmb@php.net
-Status: Analyzed
+Status: Closed
[2016-10-17 10:08 UTC] bwoebi@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 12:00:01 2025 UTC |
Description: ------------ PHP VERSION ----------------------- worker@ubuntu:~/Desktop/repo/php-src$ ./sapi/cli/php --version PHP 7.2.0-dev (cli) (built: Sep 5 2016 20:18:09) ( ZTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies PROOF-OF-CONCEPT FILE ----------------------- Posted in the "Test script" section. CONFIGURE LINE ----------------------- ./configure --enable-maintainer-zts --enable-static --enable-cli --disable-shared --disable-all OTHER INFORMATION ----------------------- The proof-of-concept file I supplied may consume lots of memory and time. To reproduce this issue more quickly, please run the command "export USE_ZEND_ALLOC=0" in terminal to disable ZEND heap management. STACKTRACE ----------------------- Posted in the "Actual result" section. VULNERABILITY DETAILS ----------------------- The vulnerability exists in function virtual_popen of file zend_virtual_cwd.c. When we supply a super long command to this function, the value of variable command_length can be negative. Thus a small heap buffer will be returned by function emalloc. It will lead to heap buffer overflow when manipulating the heap buffer. Function virtual_popen is reachable via PHP_FUNCTION exec, system, passthru, shell_exec, etc. CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ { int command_length; // type is int (not size_t) int dir_length, extra = 0; char *command_line; char *ptr, *dir; FILE *retval; command_length = strlen(command); // 0xfffffff0 dir_length = CWDG(cwd).cwd_length; dir = CWDG(cwd).cwd; while (dir_length > 0) { if (*dir == '\'') extra+=3; dir++; dir_length--; } dir_length = CWDG(cwd).cwd_length; dir = CWDG(cwd).cwd; // --------> small heap buffer will be returned here ptr = command_line = (char *) emalloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); if (!command_line) { return NULL; } /* ... */ } SIMPLE PATCH ----------------------- Use type size_t instead of type int. int command_length; --------> size_t command_length; CREDIT ----------------------- This vulnerability was discovered by Ke Liu of Tencent's Xuanwu LAB. Test script: --------------- <?php ini_set('memory_limit', -1); $cmd = str_repeat("/", 0xfffffff0); echo exec($cmd); ?> Expected result: ---------------- Exit quietly. Actual result: -------------- ==89629== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60060002945c at pc 0xc636d9 bp 0x7ffe93f986c0 sp 0x7ffe93f986b8 WRITE of size 1 at 0x60060002945c thread T0 #0 0xc636d8 in virtual_popen php-src/Zend/zend_virtual_cwd.c:1965 #1 0x744a57 in php_exec php-src/ext/standard/exec.c:113 #2 0x74593e in php_exec_ex php-src/ext/standard/exec.c:231 #3 0x745dae in zif_exec php-src/ext/standard/exec.c:250 #4 0xd095d5 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER php-src/Zend/zend_vm_execute.h:675 #5 0xd029a1 in execute_ex php-src/Zend/zend_vm_execute.h:429 #6 0xd04545 in zend_execute php-src/Zend/zend_vm_execute.h:474 #7 0xb49477 in zend_execute_scripts php-src/Zend/zend.c:1464 #8 0x8f650d in php_execute_script php-src/main/main.c:2537 #9 0x1007883 in do_cli php-src/sapi/cli/php_cli.c:990 #10 0x100aaca in main php-src/sapi/cli/php_cli.c:1378 #11 0x7f6231dc2f44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287 #12 0x41ae68 in _start (php-src/sapi/cli/php+0x41ae68) 0x60060002945c is located 0 bytes to the right of 28-byte region [0x600600029440,0x60060002945c) allocated by thread T0 here: #0 0x7f6232abe41a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1541a) #1 0xa762d0 in _emalloc php-src/Zend/zend_alloc.c:2402 #2 0xc63305 in virtual_popen php-src/Zend/zend_virtual_cwd.c:1946 #3 0x744a57 in php_exec php-src/ext/standard/exec.c:113 #4 0x74593e in php_exec_ex php-src/ext/standard/exec.c:231 #5 0x745dae in zif_exec php-src/ext/standard/exec.c:250 #6 0xd095d5 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER php-src/Zend/zend_vm_execute.h:675 #7 0xd029a1 in execute_ex php-src/Zend/zend_vm_execute.h:429 #8 0xd04545 in zend_execute php-src/Zend/zend_vm_execute.h:474 #9 0xb49477 in zend_execute_scripts php-src/Zend/zend.c:1464 #10 0x8f650d in php_execute_script php-src/main/main.c:2537 #11 0x1007883 in do_cli php-src/sapi/cli/php_cli.c:990 #12 0x100aaca in main php-src/sapi/cli/php_cli.c:1378 #13 0x7f6231dc2f44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287 SUMMARY: AddressSanitizer: heap-buffer-overflow php-src/Zend/zend_virtual_cwd.c:1965 virtual_popen Shadow bytes around the buggy address: 0x0c013fffd230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c013fffd240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c013fffd250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c013fffd260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c013fffd270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c013fffd280: fa fa fa fa fa fa fa fa 00 00 00[04]fa fa fd fd 0x0c013fffd290: fd fd fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa 0x0c013fffd2a0: fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 00 00 0x0c013fffd2b0: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 0x0c013fffd2c0: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 0x0c013fffd2d0: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap righ redzone: fb Freed Heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==89629== ABORTING