Security risks caused by improper PHP Session serialization and deserialization processor settings
PHP Session serialization and deserialization Processor
PHP has a variety of built-in processors used to access $ _ SESSION data, which will be serialized and deserialized. The following three commonly used processing formats correspond to three different processing formats:
The storage format of the processor is php key name + vertical bars + ASCII characters corresponding to the length of the value php_binary key name processed by the serialize () function deserialization + key name + after serialize () php_serialize
(Php> = 5.5.4) array processed by serialize () function deserialization
Configure session. serialize_handler
PHP provides the session. serialize_handler configuration option, through which you can set the processor used for serialization and deserialization:
Session. serialize_handler "php" PHP_INI_ALL
Security risks
Through the analysis of the storage format, If PHP uses different processors for deserialization of $ _ SESSION data stored, data cannot be correctly deserialized, through special structures, you can even forge arbitrary data :)
$_SESSION['ryat'] = '|O:8:"stdClass":0:{}';
For example, the above $ _ SESSION data is stored with the serialization processor php_serialize. The storage format is as follows:
a:1:{s:4:"ryat";s:20:"|O:8:"stdClass":0:{}";}
When reading data, if the deserialization processor is not php_serialize, but php, The deserialization data will become:
// var_dump($_SESSION);array(1) { ["a:1:{s:4:"ryat";s:20:""]=> object(stdClass)#1 (0) { }}
We can see that the serialized data of the object is forged through injection | characters, and the stdClass object is instantiated successfully :)
Actual use I) When session. auto_start = On:
When the option session is configured. auto_start = On, the Session is automatically registered because the process occurs before the script code is executed, therefore, the setting of session-related configuration options, including the serialization processor, set in the script does not work. Therefore, some programs that need to set the serialization processor configuration in the script will be in the session. when auto_start = On, destroy the automatically generated Session, set the needed serialization processor, and then call the session_start () function to register the Session. If the serialization processor set in the script and php. different settings in ini will cause security issues, as shown in the following code:
//foo.phpif (ini_get('session.auto_start')) { session_destroy();}ini_set('session.serialize_handler', 'php_serialize');session_start();$_SESSION['ryat'] = $_GET['ryat'];
When the script is accessed for the first time and the data is submitted as follows:
foo.php?ryat=|O:8:"stdClass":0:{}
The script stores data in the serialized format of the php_serialize processor:
a:1:{s:4:"ryat";s:20:"|O:8:"stdClass":0:{}";}
When the script is accessed for the second time, PHP will follow the php. the serialization processor configured in ini deserializes the stored data. if the php processor is set in ini, it will deserialize the forged data and instantiate the stdClass object :)
Note that, because PHP automatically registers a Session before the script is executed, only PHP built-in classes can be injected.
Ii) When session. auto_start = Off:
When session. auto_start = Off is configured, the serialization processor used by the two scripts to register the Session is different, and the security problem occurs, as shown in the following code:
//foo1.phpini_set('session.serialize_handler', 'php_serialize');session_start();$_SESSION['ryat'] = $_GET['ryat'];//foo2.phpini_set('session.serialize_handler', 'php');//or session.serialize_handler set to php in php.ini session_start();class ryat { var $hi; function __wakeup() { echo 'hi'; } function __destruct() { echo $this->hi; }}
When you access foo1.php, submit the following data:
foo1.php?ryat=|O:4:"ryat":1:{s:2:"hi";s:4:"ryat";}
The script stores data in the serialized format of the php_serialize processor. When you access foo2.php, it reads data in the deserialization format of the php processor. At this time, it deserializes the forged data, after the ryat object is successfully instantiated, the _ wakeup method and the _ destruct method in the class will be executed :)