php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73876 Crash when exporting **= in expansion of assign op
Submitted: 2017-01-05 22:02 UTC Modified: 2017-01-08 20:09 UTC
From: kshah at fortinet dot com Assigned: ab (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.1.0 OS: Windows 7 SP1
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kshah at fortinet dot com
New email:
PHP Version: OS:

 

 [2017-01-05 22:02 UTC] kshah at fortinet dot com
Description:
------------
Description:
------------
There exists a DEP Violation Vulnerability leading to Arbitrary Code Execution within the latest PHP-Win client.

In order to reproduce this issue, please do the following.
1) Enable Full page heap using the command "gflags /p /enable php-win.exe /full" without the double quotes in an elevated command prompt.
2) Run the PoC.php test script using the php-win cli client under windbg.
3) Check the debug output in windbg.



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

assert_options(ASSERT_WARNING);
assert(false &รข ($a **= 2));


Actual result:
--------------
Microsoft (R) Windows Debugger Version 6.11.0001.404 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: C:\php-7.1.0-nts-Win32-VC14-x86\php-win.exe "C:\PoC.php"
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is: 
ModLoad: 00000000`00d80000 00000000`00d8c000   php-win.exe
ModLoad: 00000000`77730000 00000000`778da000   ntdll.dll
ModLoad: 00000000`77910000 00000000`77a90000   ntdll32.dll
ModLoad: 00000000`00080000 00000000`000ee000   C:\Windows\system32\verifier.dll
Page heap: pid 0x2704: page heap enabled with flags 0x3.
ModLoad: 00000000`73960000 00000000`7399f000   C:\Windows\SYSTEM32\wow64.dll
ModLoad: 00000000`73900000 00000000`7395c000   C:\Windows\SYSTEM32\wow64win.dll
ModLoad: 00000000`738f0000 00000000`738f8000   C:\Windows\SYSTEM32\wow64cpu.dll
(2704.2088): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
ntdll!CsrSetPriorityClass+0x40:
00000000`777d7980 cc              int     3
0:000> .symfix+; .reload /f
Reloading current modules
..*** ERROR: Symbol file could not be found.  Defaulted to export symbols for php-win.exe - 
.....
0:000> g
ModLoad: 00000000`77510000 00000000`7762f000   WOW64_IMAGE_SECTION
ModLoad: 00000000`764e0000 00000000`765f0000   WOW64_IMAGE_SECTION
ModLoad: 00000000`77510000 00000000`7762f000   NOT_AN_IMAGE
ModLoad: 00000000`77630000 00000000`7772a000   NOT_AN_IMAGE
ModLoad: 00000000`6de30000 00000000`6de90000   C:\Windows\syswow64\verifier.dll
Page heap: pid 0x2704: page heap enabled with flags 0x3.
ModLoad: 00000000`764e0000 00000000`765f0000   C:\Windows\syswow64\kernel32.dll
ModLoad: 00000000`754c0000 00000000`75507000   C:\Windows\syswow64\KERNELBASE.dll
ModLoad: 00000000`5a760000 00000000`5ae60000   C:\php-7.1.0-nts-Win32-VC14-x86\php7.dll
ModLoad: 00000000`77460000 00000000`77501000   C:\Windows\syswow64\ADVAPI32.dll
ModLoad: 00000000`77340000 00000000`773ec000   C:\Windows\syswow64\msvcrt.dll
ModLoad: 00000000`75ea0000 00000000`75eb9000   C:\Windows\SysWOW64\sechost.dll
ModLoad: 00000000`75270000 00000000`75360000   C:\Windows\syswow64\RPCRT4.dll
ModLoad: 00000000`75200000 00000000`75260000   C:\Windows\syswow64\SspiCli.dll
ModLoad: 00000000`751f0000 00000000`751fc000   C:\Windows\syswow64\CRYPTBASE.dll
ModLoad: 00000000`76280000 00000000`762b5000   C:\Windows\syswow64\WS2_32.dll
ModLoad: 00000000`76270000 00000000`76276000   C:\Windows\syswow64\NSI.dll
ModLoad: 00000000`75360000 00000000`754bd000   C:\Windows\syswow64\ole32.dll
ModLoad: 00000000`75de0000 00000000`75e70000   C:\Windows\syswow64\GDI32.dll
ModLoad: 00000000`75f60000 00000000`76060000   C:\Windows\syswow64\USER32.dll
ModLoad: 00000000`772f0000 00000000`772fa000   C:\Windows\syswow64\LPK.dll
ModLoad: 00000000`75520000 00000000`755bd000   C:\Windows\syswow64\USP10.dll
ModLoad: 00000000`72dd0000 00000000`72e14000   C:\Windows\SysWOW64\DNSAPI.dll
ModLoad: 00000000`772d0000 00000000`772d5000   C:\Windows\syswow64\PSAPI.DLL
ModLoad: 00000000`6f490000 00000000`6f4a5000   C:\Windows\SysWOW64\VCRUNTIME140.dll
ModLoad: 00000000`6f590000 00000000`6f594000   C:\Windows\SysWOW64\api-ms-win-crt-runtime-l1-1-0.dll
ModLoad: 00000000`687a0000 00000000`68881000   C:\Windows\SysWOW64\ucrtbase.DLL
ModLoad: 00000000`6f580000 00000000`6f583000   C:\Windows\SysWOW64\api-ms-win-core-timezone-l1-1-0.dll
ModLoad: 00000000`6f480000 00000000`6f483000   C:\Windows\SysWOW64\api-ms-win-core-file-l2-1-0.dll
ModLoad: 00000000`6ef10000 00000000`6ef13000   C:\Windows\SysWOW64\api-ms-win-core-localization-l1-2-0.dll
ModLoad: 00000000`70e90000 00000000`70e93000   C:\Windows\SysWOW64\api-ms-win-core-synch-l1-2-0.dll
ModLoad: 00000000`6e960000 00000000`6e963000   C:\Windows\SysWOW64\api-ms-win-core-processthreads-l1-1-1.dll
ModLoad: 00000000`6e950000 00000000`6e953000   C:\Windows\SysWOW64\api-ms-win-core-file-l1-2-0.dll
ModLoad: 00000000`6e940000 00000000`6e944000   C:\Windows\SysWOW64\api-ms-win-crt-string-l1-1-0.dll
ModLoad: 00000000`6e460000 00000000`6e463000   C:\Windows\SysWOW64\api-ms-win-crt-heap-l1-1-0.dll
ModLoad: 00000000`6e440000 00000000`6e444000   C:\Windows\SysWOW64\api-ms-win-crt-stdio-l1-1-0.dll
ModLoad: 00000000`6e430000 00000000`6e434000   C:\Windows\SysWOW64\api-ms-win-crt-convert-l1-1-0.dll
ModLoad: 00000000`6df90000 00000000`6df95000   C:\Windows\SysWOW64\api-ms-win-crt-math-l1-1-0.dll
ModLoad: 00000000`6de20000 00000000`6de23000   C:\Windows\SysWOW64\api-ms-win-crt-environment-l1-1-0.dll
ModLoad: 00000000`6de10000 00000000`6de13000   C:\Windows\SysWOW64\api-ms-win-crt-locale-l1-1-0.dll
ModLoad: 00000000`6c2d0000 00000000`6c2d3000   C:\Windows\SysWOW64\api-ms-win-crt-filesystem-l1-1-0.dll
ModLoad: 00000000`6c2c0000 00000000`6c2c3000   C:\Windows\SysWOW64\api-ms-win-crt-time-l1-1-0.dll
ModLoad: 00000000`68790000 00000000`68793000   C:\Windows\SysWOW64\api-ms-win-crt-utility-l1-1-0.dll
(2704.2088): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
779b0ed4 cc              int     3
0:000:x86> g
ModLoad: 77400000 77460000   C:\Windows\SysWOW64\IMM32.DLL
ModLoad: 75d10000 75ddd000   C:\Windows\syswow64\MSCTF.dll
(2704.2088): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
e8cb8bd6 ??              ???
0:000:x86> g
(2704.2088): Access violation - code c0000005 (!!! second chance !!!)
e8cb8bd6 ??              ???
0:000:x86> r
eax=00000090 ebx=04f3c1bc ecx=00000207 edx=00000008 esi=0b26b138 edi=00000000
eip=e8cb8bd6 esp=04f3c084 ebp=00000001 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
e8cb8bd6 ??              ???
0:000:x86> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
04f3c080 0b26b154 0b26b148 00000000 04f3c1bc 0xe8cb8bd6
04f3c0ac 687cf7c6 5aab3b41 00000014 00000000 0xb26b154
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Users\Kush_Test\Desktop\php-7.1.0-nts-Win32-VC14-x86\php7.dll - 
04f3c0d0 5aab1cd3 00000001 00000014 00000000 ucrtbase!__crt_state_management::get_current_state_index+0x66
04f3c110 5aab2033 00000000 00000000 000000a1 php7!zend_ast_export+0x1403
04f3c1c4 5aac199c 5acffc74 0b26b178 5acfd868 php7!zend_ast_export+0x1763
04f3c204 5a7772e9 5aa83992 0b2012d0 0c79efc8 php7!zend_assert_valid_class_name+0x10bc
04f3c208 5aa83992 0b2012d0 0c79efc8 0c79efc8 php7!zend_string_tolower+0x269
04f3c224 5a776ec1 0b26b188 0c79efc8 00000000 php7!libiconv_set_relocation_prefix+0x1da72
04f3c2f0 5a775c4d 00000001 0b26b010 0b26b020 php7!zend_check_magic_method_implementation+0x13b1
04f3c308 5a775c9d 04f3c370 5ae2100c 0b273000 php7!zend_check_magic_method_implementation+0x13d
04f3c320 5a789439 00000000 04f3ef94 04f3c43c php7!zend_check_magic_method_implementation+0x18d
04f3c3ac 5a789300 5a789312 00000000 5a7892e0 php7!compile_file+0x159
04f3c3b0 5a789312 00000000 5a7892e0 00000000 php7!compile_file+0x20
04f3c43c 5a94b80f 04f3ef94 00000008 00000001 php7!compile_file+0x32
04f3c4ec 5a94b7ea 04f3f958 00000000 56433230 php7!php_pdo_free_statement+0x1230f
00000000 00000000 00000000 00000000 00000000 php7!php_pdo_free_statement+0x122ea

0:000:x86> !exploitable -v

!exploitable 1.6.0.0
HostMachine\HostUser
Executing Processor Architecture is x86
Debuggee is in User Mode
Debuggee is a live user mode debugging session on the local machine
Event Type: Exception
Exception Faulting Address: 0xe8cb8bd6
Second Chance Exception Type: STATUS_ACCESS_VIOLATION (0xC0000005)
Exception Sub-Type: Data Execution Protection (DEP) Violation

Exception Hash (Major/Minor): 0xcbe3bf09.0x1504bb6e

 Hash Usage : Stack Trace:
Major+Minor : Unknown
Major+Minor : Unknown
Major+Minor : ucrtbase!__crt_state_management::get_current_state_index+0x66
Major+Minor : php7!zend_ast_export+0x1403
Major+Minor : php7!zend_ast_export+0x1763
Minor       : php7!zend_assert_valid_class_name+0x10bc
Minor       : php7!zend_string_tolower+0x269
Minor       : php7!libiconv_set_relocation_prefix+0x1da72
Minor       : php7!zend_check_magic_method_implementation+0x13b1
Minor       : php7!zend_check_magic_method_implementation+0x13d
Minor       : php7!zend_check_magic_method_implementation+0x18d
Minor       : php7!compile_file+0x159
Minor       : php7!compile_file+0x20
Minor       : php7!compile_file+0x32
Minor       : php7!php_pdo_free_statement+0x1230f
Minor       : php7!php_pdo_free_statement+0x122ea
Instruction Address: 0xffffffffe8cb8bd6

Description: Data Execution Prevention Violation
Short Description: DEPViolation
Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - Data Execution Prevention Violation starting at Unknown Symbol @ 0xffffffffe8cb8bd6 called from ucrtbase!__crt_state_management::get_current_state_index+0x0000000000000066 (Hash=0xcbe3bf09.0x1504bb6e)

User mode DEP access violations are exploitable.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-01-05 23:39 UTC] stas@php.net
-Summary: FG-VD-17-002 Fortinet discovers DEP Violation Vulnerability in PHP +Summary: Crash when calling undefined function from assert() on Windows -Type: Security +Type: Bug
 [2017-01-05 23:39 UTC] stas@php.net
Not a security issue.

It would be helpful if PHP was compiled with debug information (such as line numbers) so we could see where the problem is.
 [2017-01-06 01:28 UTC] kshah at fortinet dot com
-Type: Bug +Type: Security -Private report: No +Private report: Yes
 [2017-01-06 01:28 UTC] kshah at fortinet dot com
Not a security issue? How?

A DEP Violation is caused when we run the following PHP test script which thereby tries to write to NX bits on a system. 

This is most definitely a big security issue.

Yes, I agree, PHP should be compiled with debug information (such as line numbers), but in this case the test binary was provided by PHP website which might have missed out on it.
 [2017-01-06 17:19 UTC] cmb@php.net
-Package: *General Issues +Package: Scripting Engine problem
 [2017-01-06 17:19 UTC] cmb@php.net
I can reproduce the issue with the current PHP-7.1 branch (commit
c50f61b9), and get the following backtrace:

 	ucrtbased.dll!00007ffeb7da1a05()	Unknown
 	ucrtbased.dll!00007ffeb7da1ba3()	Unknown
 	ucrtbased.dll!00007ffeb7dc2b7d()	Unknown
 	ucrtbased.dll!00007ffeb7dc8765()	Unknown
 	ucrtbased.dll!00007ffeb7dc8287()	Unknown
 	ucrtbased.dll!00007ffeb7dc6318()	Unknown
 	ucrtbased.dll!00007ffeb7dc8cef()	Unknown
>	php7ts_debug.dll!zend_ast_export_ex(smart_str * str, _zend_ast * ast, int priority, int indent) Line 1346	C
 	php7ts_debug.dll!zend_ast_export_list(smart_str * str, _zend_ast_list * list, int separator, int priority, int indent) Line 754	C
 	php7ts_debug.dll!zend_ast_export_ex(smart_str * str, _zend_ast * ast, int priority, int indent) Line 1112	C
 	php7ts_debug.dll!zend_ast_export_ex(smart_str * str, _zend_ast * ast, int priority, int indent) Line 1323	C
 	php7ts_debug.dll!zend_ast_export_ex(smart_str * str, _zend_ast * ast, int priority, int indent) Line 1661	C
 	php7ts_debug.dll!zend_ast_export(const char * prefix, _zend_ast * ast, const char * suffix) Line 1713	C
 	php7ts_debug.dll!zend_compile_assert(_znode * result, _zend_ast_list * args, _zend_string * name, _zend_function * fbc) Line 3633	C
 	php7ts_debug.dll!zend_try_compile_special_func(_znode * result, _zend_string * lcname, _zend_ast_list * args, _zend_function * fbc, unsigned int type) Line 3662	C
 	php7ts_debug.dll!zend_compile_call(_znode * result, _zend_ast * ast, unsigned int type) Line 3763	C
 	php7ts_debug.dll!zend_compile_var(_znode * result, _zend_ast * ast, unsigned int type) Line 8022	C
 	php7ts_debug.dll!zend_compile_expr(_znode * result, _zend_ast * ast) Line 7902	C
 	php7ts_debug.dll!zend_compile_stmt(_zend_ast * ast) Line 7871	C
 	php7ts_debug.dll!zend_compile_top_stmt(_zend_ast * ast) Line 7758	C
 	php7ts_debug.dll!zend_compile_top_stmt(_zend_ast * ast) Line 7752	C
 	php7ts_debug.dll!zend_compile(int type) Line 602	C
 	php7ts_debug.dll!compile_file(_zend_file_handle * file_handle, int type) Line 635	C
 	php7ts_debug.dll!zend_execute_scripts(int type, _zval_struct * retval, int file_count, ...) Line 1468	C
 	php7ts_debug.dll!php_execute_script(_zend_file_handle * primary_file) Line 2537	C
 	php.exe!do_cli(int argc, char * * argv) Line 994	C
 	php.exe!main(int argc, char * * argv) Line 1381	C
 	[External Code]	

I have not been able to reproduce the issue with current master.
 [2017-01-08 17:38 UTC] ab@php.net
@kshah, I really doubt it is a security issue. Unpredictable behavior - yes, as from Christoph's BT it lands at the unreachable code path. Your dump also shows 0xe8cb8bd6 as possibly being wrong. So it looks more like a first best exception that that was thrown. Also, given a specific PHP code is required to be written, which doesn't depend on any data, it sounds more like a not a security issue.

Thanks.
 [2017-01-08 19:19 UTC] ab@php.net
-Summary: Crash when calling undefined function from assert() on Windows +Summary: Crash when exporting **= in expansion of assign op -Status: Open +Status: Closed -Type: Security +Type: Bug -Assigned To: +Assigned To: ab
 [2017-01-08 19:19 UTC] ab@php.net
Got it. I've applied 9c3865eb6a7 which fixes the issue, was only applied to master previously. With debug symbols btw - you find them for every release or even snapshot build as a separate package on widows.php.net. Set to bug, lets keep closed till release, as there's a concern.

Thanks.
 [2017-01-08 19:32 UTC] nikic@php.net
Sorry, I marked this as non-private prior to reading the last comment. However, it looks like non-sec bugs are sent to the bugs list whether or not they're marked as private, so it doesn't really make a difference. Should that be changed? In any case, this is clearly not a security issue, because there is no remote exploitation vector.
 [2017-01-08 20:09 UTC] ab@php.net
Oh, i didn't check that :) Was tempted to do so myself as well also, because the patch was already public for many months.

But posting private bug mails to the public lists IMO is a bug, not what one would expect from "private".

thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Oct 09 07:01:28 2024 UTC