php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #67492 unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
Submitted: 2014-06-22 02:01 UTC Modified: 2014-06-27 23:17 UTC
From: stas@php.net Assigned: stas
Status: Closed Package: Reproducible crash
PHP Version: 5.4.29 OS: *
Private report: No CVE-ID:
 [2014-06-22 02:01 UTC] stas@php.net
Description:
------------
Betreff: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
"Remote" Code Execution Vulnerability
Datum: Fri, 20 Jun 2014 23:06:40 +0200
Von: Stefan Esser <ontheroad@nopiracy.de>
An: security@php.net

Hey,

i have found two more type confusion vulnerabilities in PHP. This
time I had a look into the SPL extension and the unserialize()
handlers of it's objects. The ArrayObject and also the
SPLObjectStorage unserialize() handler contain a similar code snippet
that does not verify the type of unserialized data before using it.

Let's have a look at the code from /ext/spl/spl_observer.c. When
you look into SPL_METHOD(SplObjectStorage, unserialize) you can find
the following code at the end of the function.

	ALLOC_INIT_ZVAL(pmembers);
	if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash
TSRMLS_CC)) {
		zval_ptr_dtor(&pmembers);
		goto outexcept;
	}

	/* copy members */
	if (!intern->std.properties) {
		rebuild_object_properties(&intern->std);
	}
	zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers),
(copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *));
	zval_ptr_dtor(&pmembers);
	
The problem here is the "pmembers" is trusted to be an array after
unserialization. However a malicious attacker can make it whatever
he wants it to be, which might lead to a simple crash or arbitrary
code execution. If "pmembers" is for example an integer the integer
value will be used as a pointer to a Hashtable in memory. If an
attacker knows the address of any Hashtable in memory (real or fake)
he can cause trouble.

However the attack is a lot easier if the attacker uses a string
instead, because he can make the string look like a fake Hashtable
and then let it be used. A fake Hashtable will then be copied into
the properties. And on destruction the attacker supplied destructor
of the fake Hashtable is executed. This allows arbitrary code
execution.

I have attached two example exploits for the two separate
vulnerabilities in ArrayObject and SPLObjectStorage. They try to
exploit the vulnerability locally with some heap spraying.
As you can see from the output I control the program counter and
because this is a destructor of our Fake Hashtable I also control
the memory RDI points to.

$ lldb php-5.5.13/sapi/cli/php unserialize_arrayobject_exploit.php
0x112233445566
Current executable set to 'php-5.5.13/sapi/cli/php' (x86_64).
(lldb) run
Process 86493 launched:
'/Users/sesser/Desktop/PHP/php-5.5.13/sapi/cli/php' (x86_64)
Setting up memory...
Now performing exploit...
Process 86493 stopped
* thread #1: tid = 0x29ab6, 0x0000112233445566, queue =
'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1,
address=0x112233445566)
    frame #0: 0x0000112233445566
error: memory read failed for 0x112233445400
(lldb) re re $pc
     rip = 0x0000112233445566
(lldb) x/20 $rdi
0x114000038: 0x14000120 0x00000001 0x00000000 0x00000000
0x114000048: 0x00000000 0x00000000 0x00000000 0x00000000
0x114000058: 0x00000000 0x00000000 0x00000000 0x00000000
0x114000068: 0x73737373 0x73737373 0x73737373 0x73737373
0x114000078: 0x73737373 0x73737373 0x73737373 0x73737373
(lldb)

Unlike the previous vulnerability in phpinfo() that I reported
last week (btw I still haven't received some ACK about it) this two
vulnerabilities are exposed through unserialize() to user input quite
often. And yes we all know that unserialize() should not be
exposed to user input, because of object injection, but many
projects still do it. Most of the time they think they are safe,
because they do not expose any objects themselves and only use
unserialize() for data exchange.

These vulnerabilities however are a reminder how dangerous this is...

Regards,
Stefan Esser




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-27 23:17 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2014-06-27 23:17 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.


 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=a374dfab567ff7f0ab0dc150f14cc891b0340b47
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b03993dde90b59a6b80ede62a6a268c5b4d390f6
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 01:41 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b03993dde90b59a6b80ede62a6a268c5b4d390f6
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 01:41 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 08:26 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b03993dde90b59a6b80ede62a6a268c5b4d390f6
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 08:26 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=a374dfab567ff7f0ab0dc150f14cc891b0340b47
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b03993dde90b59a6b80ede62a6a268c5b4d390f6
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-07-29 21:56 UTC] johannes@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c74efe1b2efd7222b27d36f383623cd19ed0e102
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-08-14 15:34 UTC] johannes@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c74efe1b2efd7222b27d36f383623cd19ed0e102
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-08-14 19:32 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c74efe1b2efd7222b27d36f383623cd19ed0e102
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-10-07 23:13 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=c74efe1b2efd7222b27d36f383623cd19ed0e102
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-10-07 23:14 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-10-07 23:25 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=c74efe1b2efd7222b27d36f383623cd19ed0e102
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2014-10-07 23:25 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=88223c5245e9b470e1e6362bfd96829562ffe6ab
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 [2016-07-20 11:40 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=a374dfab567ff7f0ab0dc150f14cc891b0340b47
Log: Fix bug #67492: unserialize() SPL ArrayObject / SPLObjectStorage Type Confusion
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Feb 26 14:01:37 2017 UTC