catalogue
Serialization and deserialization in PHP
@Create a class, an object, and serialize and deserialize it
Deserialization
Why serialize
class
obj object
Baidu Encyclopedia's definition of serialization is the process of converting the state information of an object into a form (string) that can be stored or transmitted. During serialization, the object writes its current state to the temporary or persistent storage area (store it in the database. The preferred database is Redis, or a key value pair database of type Redis. It can be understood that the Redis database is a large array accessed through key value pairs, and the relational database is a large Excel table). Later, you can recreate the object by reading or deserializing its state from the store.
To put it simply, serialization is to turn an object into a string that can be transmitted (convenient for transmission), and deserialization is the process of converting a string into an object (if the string client is controllable, we can let the web application deserialize any object. What's more, we will trigger some executable PHP code, such as phpinfo, in the process of deserialization), Processes can communicate across platforms and safely in a specific format.
<?php class Stu{ public $name; public $sex; public $agel; public $score; } $stu1= new Stu();//Created an object new $stu1->name="ZQX"; $stu1->sex=true; $stu1->age=16; $stu1->score=60; $stu2= new Stu(); $stu2->name="HMM"; $stu2->sex=false; $stu2->age=16; $stu2->score=90; echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 find the object name first and then its attribute echo $stu2->name."'s score = ".$stu2->score; echo "<hr />"; var_dump($stu1); //The object stu1, an abstract data structure, is transformed into a string and stored in a file on the hard disk. This process is called serialization //Advantages of serialization: we can pause a user's state, take out the string from the hard disk when the user activates, deserialize it into an object, and then store it in memory for him to work. ?>
Serialization and deserialization in PHP
PHP deserialization vulnerability, also known as PHP object injection, is a common vulnerability. Although this type of vulnerability is difficult to exploit, once successfully exploited, it will cause very threatening consequences. The root cause of the vulnerability is that the programmer does not detect the deserialization string entered by the user, resulting in the deserialization process can be maliciously controlled, resulting in a series of uncontrollable consequences such as code execution and getshell. Deserialization vulnerability is not unique to PHP, but also exists in Java, Python and other languages, but its principle is basically the same.
Serialization and deserialization in PHP are basically expanded around two functions: serialize() and unserialize().
*Simple example
We can understand the serialization and deserialization process by using the encoding and decoding of json format data (json format is a formatted string, that is, the data in json format has its own certain format). Although json data has nothing to do with deserialization vulnerabilities, this example helps us understand.
Test code:
<?php $stu=array('name'=>'Waffle','age'=>20,'SEX'=>true,'score'=>96.6); echo $stu; //echo cannot output an array echo "<hr />"; $stu_json=json_encode($stu);//But if we convert the number $stu to json format_ encode //Array is an abstract array. After being encoded in json format, it will become a string. After becoming a string, it can be output with echo echo $stu_json; ?>
We define an array, which is an abstract data structure. In order to facilitate cross platform transmission, it can be json encoded. Data in json format is in the form of key value pairs.
Array{"name":"Waffle","age":20,"SEX":true,"score":96.6}
<?php class Stu{ public $name; public $sex; public $agel; public $score; } $stu1= new Stu();//Created an object new $stu1->name="ZQX"; $stu1->sex=true; $stu1->age=16; $stu1->score=60; $stu2= new Stu(); $stu2->name="HMM"; $stu2->sex=false; $stu2->age=16; $stu2->score=90; echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 find the object name first and then its attribute echo $stu2->name."'s score = ".$stu2->score; echo "<hr />"; //var_dump($stu1); //The object stu1, an abstract data structure, is transformed into a string and stored in a file on the hard disk. This process is called serialization //Advantages of serialization: we can pause a user's state, take out the string from the hard disk when the user activates, deserialize it into an object, and then store it in memory for him to work. //echo $stu1;// (x) It cannot be output as a string. Next, we need to convert stu1 echo serialize($stu1);//The serialize function will serialize our object and serialize it into a string //O:3:"Stu":5:{s:4:"name";s:3:"ZQX";s:3:"sex";b:1;s:4:"agel";N;s:5:"score";i:60;s:3:"age";i:16;} //O stands for object, 3 is the length of the class name, and 5 indicates that there are four attributes in our class. Each sentence ends with a semicolon, s stands for string type, and b stands for bool type ?>
*Serialize Demo
Serialization converts an abstract to a string.
We can write a Demo to illustrate the serialization process. First, create a class with the following code
<?php class Stu{ public $name; public $sex; public $age; public $score; } ?>
The class name is Stu and there are four variables.
Next, we create an object and assign values to variables in the object. The code is as follows
<?php include "classStu.php"; $stu1 = new Stu(); $stu1->name = "Waffle"; $stu1->sex = true; $stu1->age = 18; $stu1->score = 89.9; echo serialize($stu1); ?>
Finally, we use the serialize() function to serialize the $stu1 object into a string. Such a string is easy to transmit and store. as follows
O:3:"Stu":4 / / O stands for Object object; 3. The Object name has three characters; There are four variables in the Object
{s:4:"name";s:3:"GGG";
s:3:"sex";b:1;
s:3:"age";i:18;
s:5:"score";d:89.900000000000006;}
Similarly, we can also use the deserialize () function to deserialize the string into an object. Since the string contains double quotation marks, we can use the delimiter. The code is as follows
<?php include "classStu.php"; $stu1 =<<<HTML O:3:"Stu":4:{s:4:"name";s:3:"GGG";s:3:"sex";b:1;s:3:"age";i:18;s:5:"score";d:89.900000000000006;} HTML; $stu1=unserialize($stu1); var_dump($stu1); ?>
Running this script, we can see the deserialized object
object(Stu)#1 (4) { ["name"]=> string(3) "GGG" ["sex"]=> bool(true) ["age"]=> int(18) ["score"]=> float(89.9) }
*Where are the loopholes?
@Create a class, an object, and serialize and deserialize it
<?php class Test{ public $str='Waffle'; function __destruct(){ //echo "This is function __contruct()"; @eval($this->str); } } $test = new Test(); echo serialize($test);//serialize means serialization / / O:4:"Test":1:{s:3:"str";s:6:"Waffle";} There are only attributes and no methods echo "<hr />"; //$t=serialize($test); //var_dump(unserialize($t)); //object(Test)#2 (1) { ["str"]=> string(6) "Waffle" } var_dump(unserialize($_GET['obj'])); //Deserialize it ?>
@Deserialization injection
Construct serialized characters
.../class/loudong.php?obj=O:4:"Test":1:{s:3:"str";s:10:"phpinfo();";}
You will find that the phpinfo() function has been executed
It can be found from the above code that the deserialization vulnerability of PHP needs to cooperate with other vulnerabilities, such as code execution SQLi, etc
*Why
Why does the injected string [phpinfo()] run as a PHP statement? Observe the code and find a function in the class__ destruct() and the eval statement called by this function executes the $this - > STR variable. Why__ If destruct () is not called, the statement in the function is executed?
You can test with the following code__ destruct() function
<?php class Test{ public $str='GGG'; function __destruct(){ echo "This is function __destruct()"; //@eval($this->str); } } $test = new Test(); echo serialize($test); echo "<hr />"; var_dump(unserialize($_GET['obj'])); ?>
We will find that when destroying instantiated classes (that is, objects)__ The destruct() function is called and outputs a string
With__ The first method is the magic method in PHP and the magic method in class, which will be called automatically under specific circumstances. The main methods of magic are as follows
__construct() | Called automatically when an object is created |
__destruct() | Called automatically when an object is destroyed |
__call() | When an invocation method is invoked in an object, call() will be called |
__callStatic() | Call when an invocable method is invoked in a static context |
__get() | When reading the value of an inaccessible property__ get() will be called |
__set() | When assigning a value to an inaccessible property__ set() will be called |
__isset() | When isset() or empty() is called on an inaccessible property__ Isset() will be called |
__unset() | When unset() is called on an inaccessible property__ Unset() will be called |
__sleep() | The serialize() function checks whether a magic method exists in the class__ sleep(), if any, will be called first and then serialized |
__wakeup() | unserialize() checks to see if there is one__ wakeup() method, if any, will be called first__ The wakeup method prepares the resources required by the object in advance |
__toString() | __ The toString () method is used to respond when a class is treated as a string |
__invoke() | When you try to call an object by calling a function__ The invoke() method is called automatically |
__set_state() | Calling var from PHP 5.1.0_ When export() exports a class, this static method will be called |
__clone() | When the copy is complete, if defined__ Clone method, the__ The clone() method is called and can be used to modify the value of the property. |
__debugInfo() | This method is called by var_dump() anobject to get the properties that should be shown .If the method isn't on an object ,then all public ,protec''ted and private propertieswill be shown. |
Reference link:
http://www.freebuf.com/articles/web/167721.html
https://baike.baidu.com/item/%E5%BA%8F%E5%88%97%E5%8C%96/2890184?fr=aladdin
https://www.cnblogs.com/magic-zero/p/7737274.html
https://mp.weixin.qq.com/s?__biz=MzAxNDY2MTQ2OQ==&mid=2650942666&idx=1&sn=5c84d6d69463a0a430e01dfa68c2d3ab&chksm=80796ef8b70ee7ee8ba5d88feb8d794bee19a55b6e17dff45fcee6ba6ee726fb4e2e029d50bd&scene=0#rd