php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67338 Data from Faulting Address controls subsequent Write Address
Submitted: 2014-05-25 00:19 UTC Modified: 2014-10-30 09:36 UTC
From: jigsaw0658 at gmail dot com Assigned:
Status: Closed Package: Apache2 related
PHP Version: Irrelevant OS: Windows 7_64bit
Private report: No CVE-ID: None
 [2014-05-25 00:19 UTC] jigsaw0658 at gmail dot com
Description:
------------
The bug reside in the following piece of code : https://github.com/php/php-src/blob/master/Zend/zend_opcode.c

ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
{
zend_literal *literal = op_array->literals;
zend_literal *end;
zend_uint i;

if (op_array->static_variables) {
zend_hash_destroy(op_array->static_variables);
FREE_HASHTABLE(op_array->static_variables);
}

if (op_array->run_time_cache) {
efree(op_array->run_time_cache);
}

//op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint));
//*op_array->refcount = 1; initialized here.
if (--(*op_array->refcount)>0) { // Exception occur here (Invalid Pointer).
return;
}

efree(op_array->refcount);

.
.
.
.
}

===============================================================================

Crash Dump and analysis results : ( you can check that to confirm this analysis)
I used Microsoft crash analyzer to see if it's exploitable or no.
the results information :

!exploitable 1.6.0.0
HostMachine\HostUser
Executing Processor Architecture is x86
Debuggee is in User Mode
Debuggee is a user mode small dump file
Event Type: Exception
Exception Faulting Address: 0x5883050
Second Chance Exception Type: STATUS_ACCESS_VIOLATION (0xC0000005)
Exception Sub-Type: Read Access Violation

Faulting Instruction:0217d315 mov edx,dword ptr [eax]

Basic Block:
    0217d315 mov edx,dword ptr [eax]
       Tainted Input operands: 'eax'
    0217d317 dec edx
       Tainted Input operands: 'edx'
    0217d318 mov dword ptr [eax],edx
       Tainted Input operands: 'eax','edx'
    0217d31a mov eax,dword ptr [esi+24h]
    0217d31d cmp dword ptr [eax],0
    0217d320 ja php5ts!destroy_op_array+0x194 (0217d474)

Exception Hash (Major/Minor): 0xff233afd.0x01458bdd

 Hash Usage : Stack Trace:
Major+Minor : php5ts!destroy_op_array+0x35
Major+Minor : php5ts!destroy_zend_function+0x18
Major+Minor : php5ts!zend_function_dtor+0x14
Major+Minor : php5ts!zend_hash_destroy+0x27
Instruction Address: 0x000000000217d315

Description: Data from Faulting Address controls subsequent Write Address
Short Description: TaintedDataControlsWriteAddress
Exploitability Classification: PROBABLY_EXPLOITABLE
Recommended Bug Title: Probably Exploitable - Data from Faulting Address controls subsequent Write Address starting at php5ts!destroy_op_array+0x0000000000000035 (Hash=0xff233afd.0x01458bdd)

The data from the faulting address is later used as the target for a later write.
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

***** OS symbols are WRONG. Please fix symbols to do analysis.

***** OS symbols are WRONG. Please fix symbols to do analysis.

***** OS (WOW64 kernel32) symbols are WRONG. Please fix symbols to do analysis.

***** OS (WOW64 kernel32) symbols are WRONG. Please fix symbols to do analysis.

*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: ntdll!_PEB                                    ***
***                                                                   ***
*************************************************************************
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y <symbol_path> argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y <symbol_path> argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for user32.dll - 
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y <symbol_path> argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************

FAULTING_IP: 
php5ts!destroy_op_array+35
0217d315 8b10            mov     edx,dword ptr [eax]

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 0217d315 (php5ts!destroy_op_array+0x00000035)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 05883050
Attempt to read from address 05883050

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

PROCESS_NAME:  httpd.exe

FAULTING_MODULE: 77130000 kernel32

DEBUG_FLR_IMAGE_TIMESTAMP:  481b8f4b

MODULE_NAME: php5ts

ERROR_CODE: (NTSTATUS) 0xc0000005 - L

READ_ADDRESS:  05883050 

BUGCHECK_STR:  ACCESS_VIOLATION

LAST_CONTROL_TRANSFER:  from 0217d068 to 0217d315

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
000cfdac 0217d068 05889088 0024d010 0217d084 php5ts!destroy_op_array+0x35
000cfdb8 0217d084 05990b80 0024d010 00000000 php5ts!destroy_zend_function+0x18
000cfdcc 0216c537 05990b80 76de9894 029a5d68 php5ts!zend_function_dtor+0x14
00000000 00000000 00000000 00000000 00000000 php5ts!zend_hash_destroy+0x27


STACK_COMMAND:  ~0s; .ecxr ; kb

FAULTING_THREAD:  00018910

FOLLOWUP_IP: 
php5ts!destroy_op_array+35
0217d315 8b10            mov     edx,dword ptr [eax]

SYMBOL_STACK_INDEX:  0

FOLLOWUP_NAME:  MachineOwner

IMAGE_NAME:  php5ts.dll

SYMBOL_NAME:  php5ts!destroy_op_array+35

BUCKET_ID:  WRONG_SYMBOLS

Followup: MachineOwner
---------



Test script:
---------------
Actually i tested with a script but it didn't work, i didn't find a way to reproduce the bug since the first time occurred but i'll provide a crash dump when the bug is reviewed that can help you to analyze more this behavior.

Expected result:
----------------
-Denial of service in Apache Web server.
-Apache crashed once the script "test.php" is executed.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-05-25 08:52 UTC] pajoye@php.net
Thanks for the report.

Could you attach the test.php script please?
 [2014-05-25 08:52 UTC] pajoye@php.net
-Status: Open +Status: Feedback
 [2014-05-25 14:22 UTC] jigsaw0658 at gmail dot com
-Status: Feedback +Status: Open
 [2014-05-25 14:22 UTC] jigsaw0658 at gmail dot com
Hi, let me explain how i detected this behavior :
the first time i tested the script it triggers the crash of Apache service httpd.exe until i restart the service again. This behavior occurred 3 times while executing the same script but later i wasn't able to reproduce it, anyway here is the script i used :

<?php
session_start();
set_time_limit(5000);

$code = md5(uniqid(rand(), true));
$HTTP['http']['method']          = 'GET';
$HTTP['http']['follow_location'] = 0;
$HTTP['http']['header']          = "Host: host.com\r\n";
$HTTP['http']['header']         .= "Referer: http://host.com/\r\n";
$HTTP['http']['header']          = "Cookie: COOKIE=u275gfdjphn0rr721avhgcps82; screenWidth=1366\r\n";
$link = "http://example.com/index.php?Page=Login&Action=ConfirmCode&user=1&code=$code";
$context = stream_context_create($HTTP);
$string = file_get_contents($link, false, $context);
$file = "log1.txt";
file_put_contents($file,$string);

function RightLine($str,$r)
{
$str = 'Fill in the form to generate a new password. An email will be sent to you containing a link which you must click to confirm your password change.';
$matches = array();
$file = "log1.txt";
$handle = fopen($file, "r");
if ($handle)
{
    while (!feof($handle))
    {
        $buffer = fgets($handle);
        if(strpos($buffer, $str) == TRUE)
            $matches[] = $buffer;
    }
    fclose($handle);
}
$res = substr($matches[0],$r = 0);
return $res;
}
do
{
RightLine($str,$r);
}while(RightLine($str,$r) == $str);
echo $code;
?>
 [2014-05-27 05:25 UTC] stas@php.net
-Type: Security +Type: Bug
 [2014-05-27 05:25 UTC] stas@php.net
Doesn't look like a security issue.
 [2014-05-27 13:24 UTC] jigsaw0658 at gmail dot com
Hi,
can you explain please why it's not a security issue because the analysis show that the bug can be probably exploitable based on the stack trace and the attempt of reading from address 05883050. In addition if we are able to overwrite/corrupt the pointer it can be exploitable surely.
i'll provide soon a crash dump so u can investigate further.
Regards,
 [2014-05-30 20:38 UTC] jigsaw0658 at gmail dot com
Hi,

I didn't get a reply for my latest comment.
 [2014-10-30 09:36 UTC] jigsaw0658 at gmail dot com
-Status: Open +Status: Closed
 [2014-10-30 09:36 UTC] jigsaw0658 at gmail dot com
Closed
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Thu Dec 02 13:03:33 2021 UTC