|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[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
[2014-06-30 20:23 UTC] dmitry@php.net
[2014-06-30 20:23 UTC] dmitry@php.net
[2014-06-30 20:23 UTC] dmitry@php.net
[2014-07-02 01:41 UTC] tyrael@php.net
[2014-07-02 01:41 UTC] tyrael@php.net
[2014-07-02 08:26 UTC] ab@php.net
[2014-07-02 08:26 UTC] ab@php.net
[2014-07-02 08:33 UTC] ab@php.net
[2014-07-02 08:33 UTC] ab@php.net
[2014-07-02 08:33 UTC] ab@php.net
[2014-07-29 21:56 UTC] johannes@php.net
[2014-08-14 15:34 UTC] johannes@php.net
[2014-08-14 19:32 UTC] dmitry@php.net
[2014-10-07 23:13 UTC] stas@php.net
[2014-10-07 23:14 UTC] stas@php.net
[2014-10-07 23:25 UTC] stas@php.net
[2014-10-07 23:25 UTC] stas@php.net
[2016-07-20 11:40 UTC] davey@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 02:00:01 2025 UTC |
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