php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73018 Deprecated case usage in unserialize() function
Submitted: 2016-09-05 08:19 UTC Modified: 2016-09-05 17:44 UTC
From: root at stypr dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: master-Git-2016-09-05 (Git) OS: All
Private report: No CVE-ID: None
 [2016-09-05 08:19 UTC] root at stypr dot com
Description:
------------
https://github.com/php/php-src/blob/master/ext/standard/var_unserializer.c#L629

the case "C" seems to be deprecated, and none of developers/users now use it. should be removed.

"""
	case 'C':
	case 'O':	goto yy13;
	case 'N':	goto yy5;
"""

For instance, even if the programmer blocked "O"(object) on unserialize() execution, hackers can still use "C" type, which is identical to object.

Refer to https://www.owasp.org/index.php/PHP_Object_Injection for more details

Test script:
---------------
<?php

class Expl {
    public function __destruct(){
         system("id");
    }
}

echo unserialize('a:2:{i:0;s:1:"1";i:1;O:4:"Expl":1:{s:1:"a";s:1:"a";};}');
echo "is identical to";
echo unserialize('a:2:{i:0;s:1:"1";i:1;C:4:"Expl":1:{s:1:"a";s:1:"a";};}');

?>

Expected result:
----------------
uid=0(root) gid=0(root) groups=0(root)
PHP Notice:  unserialize(): Error at offset 53 of 54 bytes in /home/test/www/exploit.php on line 9
is identical toPHP Warning:  Class Expl has no unserializer in /home/test/www/exploit.php on line 11
uid=0(root) gid=0(root) groups=0(root)
PHP Notice:  unserialize(): Error at offset 37 of 54 bytes in /home/test/www/exploit.php on line 11



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-05 08:23 UTC] root at stypr dot com
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index d59231c..c6755c7 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -626,7 +626,6 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
        if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
        yych = *YYCURSOR;
        switch (yych) {
-       case 'C':
        case 'O':       goto yy13;
        case 'N':       goto yy5;
        case 'R':       goto yy2;
 [2016-09-05 17:01 UTC] stas@php.net
-Type: Security +Type: Bug -Package: PHP Language Specification +Package: *General Issues
 [2016-09-05 17:44 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2016-09-05 17:44 UTC] nikic@php.net
C-style serialization is in active use by many internal classes, and exposed to userland through the Serializable interface.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 20:01:45 2024 UTC