Bug #73131 [Opn->Csd]: Use-after-free in php_var_serialize_intern
| From: | cmb@php.net | Date: | Fri, 19 Mar 2021 16:42:05 +0000 |
| Subject: | Bug #73131 [Opn->Csd]: Use-after-free in php_var_serialize_intern | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-232887@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73131&edit=1
ID: 73131
Updated by: cmb@php.net
Reported by: ahihibughunter at gmail dot com
Summary: Use-after-free in php_var_serialize_intern
-Status: Open
+Status: Closed
Type: Bug
Package: Session related
Operating System: ALL
PHP Version: 5.6.26
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
This bug has been fixed in the meantime.
Previous Comments:
------------------------------------------------------------------------
[2016-09-21 07:33:42] ahihibughunter at gmail dot com
Ok, thanks for your explanation.
------------------------------------------------------------------------
[2016-09-21 07:25:09] yohgaki@php.net
Because it requires to control script, not external data.
It's possible to inject PHP script to system and exploit. However, if PHP script could be
injected, attackers can do anything with injected PHP scripts without using null pointer
dereference.
It may be used to workaround open_basedir restriction, but PHP does not provide full virtual
environment nor perfect security in the first place. There are number of ways to workaround the
restriction by using simple PHP code.
------------------------------------------------------------------------
[2016-09-20 23:05:30] ahihibughunter at gmail dot com
Hi stas,
Can I know why this Use-After-Free is not security issue? I think it critical more than other null
pointer dereference or integer overflow because this kind of issue can lead to code execution easier
than others.
Thanks
------------------------------------------------------------------------
[2016-09-20 17:23:50] ahihibughunter at gmail dot com
Description:
------------
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
....
switch (Z_TYPE_P(struc)) {
...
case IS_ARRAY: {
...
if (Z_TYPE_PP(data) == IS_ARRAY) {
php_var_serialize_intern(buf, *data, var_hash TSRMLS_CC); <----------- call
php_var_serialize_intern again with new data
...
}
Free the memory when call to call_user_function_ex
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
....
switch (Z_TYPE_P(struc)) {
....
case IS_OBJECT: {
....
if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table,
"__sleep", sizeof("__sleep"))) {
...
res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1,
NULL TSRMLS_CC);
...
}
.....
.....
/php-src-PHP-5.6.26/Zend/zend_execute.h:80
efree_rel(zval_ptr); <------------------------ Free the memory
And memory reused
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
...
case IS_OBJECT: {
...
if (res == SUCCESS) {
if (retval_ptr) {
if (HASH_OF(retval_ptr)) {
php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC); <-----------------------
BOOM
...
}
Test script:
---------------
<?php
class Ahihi {};
class Ihaha
{
function __sleep()
{
new Ahihi;
$_SESSION['ihaha'] = "gogogo";
return array();
}
}
session_start();
$_SESSION['ihaha']['boom'] = new Ihaha;
?>
Expected result:
----------------
No crash
Actual result:
--------------
$ gdb php-src-PHP-5.6.26/sapi/cli/php
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
..
(gdb) r crash.php
Starting program: /home/s/php/php-src-PHP-5.6.26/sapi/cli/php crash.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000000000927a21 in php_var_serialize_class_name (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:607
607 PHP_SET_CLASS_ATTRIBUTES(struc);
(gdb) (gdb) print *struc
$1 = {value = {lval = 6510615555426900570, dval = 1.7838867517321418e+127, str = {
val = 0x5a5a5a5a5a5a5a5a <error: Cannot access memory at address 0x5a5a5a5a5a5a5a5a>,
len = 1515870810},
ht = 0x5a5a5a5a5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a5a5a5a5a}, ast =
0x5a5a5a5a5a5a5a5a},
refcount__gc = 1515870810, type = 90 'Z', is_ref__gc = 90 'Z'}
gdb) bt
#0 0x0000000000927a21 in php_var_serialize_class_name (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:607
#1 0x00000000009283bf in php_var_serialize_class (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00,
retval_ptr=0x7ffff7fcb678, var_hash=0x7ffff7fcb0f8) at
/home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:623
#2 0x000000000092c1c1 in php_var_serialize_intern (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00,
var_hash=0x7ffff7fcb0f8)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:813
#3 0x000000000092cd72 in php_var_serialize_intern (buf=0x7fffffffcd10, struc=0x7ffff7fccf90,
var_hash=0x7ffff7fcb0f8)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:886
#4 0x000000000092d0cd in php_var_serialize (buf=0x7fffffffcd10, struc=0x7ffff7fcea08,
var_hash=0x7fffffffccd0)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:905
#5 0x00000000007fc8b6 in ps_srlzr_encode_php (newstr=0x7fffffffcd68, newlen=0x7fffffffcd80)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:988
#6 0x00000000007f9a73 in php_session_encode (newlen=0x7fffffffcd80)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:209
#7 0x00000000007fa72d in php_session_save_current_state () at
/home/s/php/php-src-PHP-5.6.26/ext/session/session.c:542
#8 0x000000000080041a in php_session_flush () at
/home/s/php/php-src-PHP-5.6.26/ext/session/session.c:1646
#9 0x00000000008027ff in zm_deactivate_session (type=1, module_number=28)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:2415
#10 0x0000000000ab451f in zend_deactivate_modules () at
/home/s/php/php-src-PHP-5.6.26/Zend/zend_API.c:2488
#11 0x0000000000a0e158 in php_request_shutdown (dummy=0x0) at
/home/s/php/php-src-PHP-5.6.26/main/main.c:1867
#12 0x0000000000b5f4af in do_cli (argc=2, argv=0x1457a20) at
/home/s/php/php-src-PHP-5.6.26/sapi/cli/php_cli.c:1177
#13 0x0000000000b5fd39 in main (argc=2, argv=0x1457a20) at
/home/s/php/php-src-PHP-5.6.26/sapi/cli/php_cli.c:1378
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73131&edit=1